Skip to the content...

Welcome to the David Walsh Blog. I'm a MooTools, Dojo, jQuery, CSS, and PHP Web Developer located in Madison, Wisconsin, United States. Please contact me if I can make your experience on my website better.

Watch Your POST: Save PHP POST Data as XML

23 Responses »

One of my main goals when creating PHP web forms is to keep them secure and protected from spammers and automated bots. With the amount of spam that Akismet catches every day, I don't need to be reminded of the importance of securing forms. Since 90+% of my forms are POST transmissions, I've taken a lot of time to develop POST debugging and listening code.

One function I use to keep track of POST submissions is my custom print_r_xml() function. The function takes a given array (in my case, $_POST), cycles through each key, and places each key=>value into XML format. From there, I can save the XML to a file or place the XML into a database.

The function can be used on any array ($_SESSION and $_GET would be good options too!).

The PHP Code

/* print the contents of a url */
function print_r_xml($arr,$wrapper = 'data',$cycle = 1)
{
	//useful vars
	$new_line = "\n";

	//start building content
	if($cycle == 1) { $output = '<?xml version="1.0" encoding="UTF-8" ?>'.$new_line; }
	$output.= tabify($cycle - 1).'<'.$wrapper.'>'.$new_line;
	foreach($arr as $key => $val)
	{
		if(!is_array($val))
		{
			$output.= tabify($cycle).'<'.htmlspecialchars($key).'>'.$val.'</'.htmlspecialchars($key).'>'.$new_line;
		}
		else
		{
			$output.= print_r_xml($val,$key,$cycle + 1).$new_line;
		}
	}
	$output.= tabify($cycle - 1).'</'.$wrapper.'>';

	//return the value
	return $output;
}

/* tabify */
function tabify($num_tabs)
{
	for($x = 1; $x <= $num_tabs; $x++) { $return.= "\t"; }
	return $return;
}

Notice that this function is used recursively when a value is an array.

The Usage

/* test */
$_POST = array(
				'first_name'=>'David',
				'last_name'=>'Walsh',
				'url'=>'http://davidwalsh.name',
				'languages'=>array('php','javascript','java','css'),
				'title'=>'Web Developer',
				'favorite_blogs'=>array('CSSTricks'=>'http://css-tricks.com','AJAXian'=>'http://ajaxian.com')
			);
echo print_r_xml($_POST);

The Result

<?xml version="1.0" encoding="UTF-8">
<data>
	<first_name>David</first_name>
	<last_name>Walsh</last_name>
	<url>http://davidwalsh.name</url>
	<languages>
		<0>php</0>
		<1>javascript</1>
		<2>java</2>
		<3>css</3>
	</languages>
	<title>Web Developer</title>
	<favorite_blogs>
		<CSSTricks>http://css-tricks.com</CSSTricks>
		<AJAXian>http://ajaxian.com</AJAXian>
	</favorite_blogs>
</data>

This function has been a huge help in debugging GET and POST data. Try it out, let me know what you think!

Discussion

  1. March 26, 2008 @ 2:24 am

    Your bloging script must have changed \n to just n in line 5:

    $new_line = “n”;

    And further on with “\t” (oh, any why not use str_repeat() instead of for?)

    Anyhow, I would recommentd using PHP_EOL instead of “\n”

  2. March 26, 2008 @ 6:32 am

    @BTM: You’re right, WordPress changed my newline variable. Also, I used tabify to make what I was repeating clearer. str_repeat would work just fine too.

  3. ellisgl
    March 26, 2008 @ 9:31 am

    Seems like overhead to take $_POST and convert the array to XML then to turn around and save it to the DB, since you would have to take the XML and turn it into an array of sorts to put each element into their the respective fields.

    If my thoughts are wrong, show me the way.

  4. March 26, 2008 @ 12:11 pm

    @What would you propose EllisGL?

  5. March 26, 2008 @ 1:11 pm

    I tend to use this function

    function debug($object)
    {
    echo “” . print_r($object) . “”;
    }

    Not sure if this correct but just what I remember from the top of my head. (WordPress is also messing around with my pre tags.)

    Then you can just use debug($_POST). It’s not as pretty as xml but I like it.

  6. jay
    March 26, 2008 @ 2:43 pm

    Ya you definitely have serious overhead there, but you could have a debug flag that you keep in your config to turn on saving the xml but I agree with the uncomfortably named Jesus that what’s the point? You could have the poor man’s debugger with print_r or use something like Zend’s debugger that let’s you step through execution visual studio style.

  7. March 26, 2008 @ 11:08 pm

    Currently, I use this script to generate XML that I place into a file. That way, I can do advanced functionality like parsing and generating reports, or simply eyeball a file when needed.

  8. ellisgl
    March 27, 2008 @ 12:22 pm

    For *SQL – Leave the POST array as is and just call by the key name and insert into your *SQL.

    A problem you might encounter with XML in PHP will be if you are trying to process large files (>1MB), you’ll end up running out of memory. Many of times I have had to convert an XML file to a CSV with a DOS program (really quick and light), so I can load it to the DB.

  9. March 31, 2008 @ 6:13 pm

    why don’t you use serialize($_POST) for data storing purposes? ;0)

  10. March 31, 2008 @ 7:25 pm

    @Dan: I’m actually doing that with one project, but I want to be able to open the generated file and read it in a semi-English format. Unfortunately, my serialized data reading skills aren’t great! :)

  11. josh
    May 24, 2008 @ 9:59 am

    Actually, this could be helpful with contract first web applications. Just have the user submit their request in a form, transform the POST and submit the XML to the service. I don’t have too too much experience with this, but it seems like it could work.

  12. June 9, 2008 @ 4:02 am

    Dave,

    You’re the man!

    I’ve been looking for a way to capture paypal IPN notifications for auditing order transactions.

    My first thought was to simply insert into a database table. but then I recalled the power of xml.

  13. October 28, 2008 @ 7:42 pm

    any chance you can supply a download link to play with your files.
    would be much appreciated.

    Cheers

  14. tana
    January 9, 2009 @ 12:29 pm

    Thanks for this script, really helpful for generating dynamic templates… Still working on setting it up for my purposes but this really helped me!

  15. February 28, 2009 @ 7:16 pm

    The \t still isn’t fixed in your Tabify function but I ended up switching to using str_repeat in any case just so I could keep everything in one contained function. Very very useful though so thank you :-)

  16. March 1, 2009 @ 2:18 pm

    Also just noticed that your XML declaration is incorrect as it doesn’t have a proper closing tag. Line 8 should read:

    if($cycle == 1) { $output = ‘<\?xml version=”1.0″ encoding=”UTF-8″?>’.$new_line; }

    The question mark after the UTF-8 section is crucial otherwise if you send your XML as text/xml in a browser, it will break due to a parsing error “unclosed token”.

    Please note: that you’ll need to remove the backslash in front of the first question mark that I’ve highlighted in red – had to put that in to make the blog comments let me post it!!

  17. March 1, 2009 @ 2:24 pm

    Updated, thanks Ben!

  18. March 1, 2009 @ 8:44 pm

    Thank you Ben. My hosting provider had security restrictions in place that prevented me from adding that in “PHP” blocks.

  19. March 2, 2009 @ 7:21 am

    Ah I see – I’d recommend that you use something like the php function highlight_file which would allow you to put your example code in a separate file and then pull it into your blog post with full syntax highlighting – it escapes all of the code so you can echo it correctly on your page. Alternatively, as you’re using WordPress, you could use a plugin such as WP-Syntax which does essentially the same thing but has support for lots of different programming languages and custom theming.

  20. March 16, 2009 @ 9:11 am

    Does anyone know how to save a pushed XML post from a external company to a file on my server. And this wihout knowing the URL form the company?

  21. April 10, 2010 @ 1:11 pm

    great help mate!
    thanks!

  22. timmy
    April 10, 2010 @ 3:50 pm

    Great tip. How would I reverse this process? That is, how would I take the saved XML POST data and send it to a PHP script?

Be Heard!

Share your thoughts with fellow developers of all skill levels! I want to hear from you!

Name*:
Email*:
Website:  
Wrap your code with <code> tags, f00!