Watch Your POST: Save PHP POST Data as XML

By  on  

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'=>'https://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>https://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!

Recent Features

  • By
    How to Create a Twitter Card

    One of my favorite social APIs was the Open Graph API adopted by Facebook.  Adding just a few META tags to each page allowed links to my article to be styled and presented the way I wanted them to, giving me a bit of control...

  • By
    CSS @supports

    Feature detection via JavaScript is a client side best practice and for all the right reasons, but unfortunately that same functionality hasn't been available within CSS.  What we end up doing is repeating the same properties multiple times with each browser prefix.  Yuck.  Another thing we...

Incredible Demos

  • By
    jQuery topLink Plugin

    Last week I released a snippet of code for MooTools that allowed you to fade in and out a "to the top" link on any page. Here's how to implement that functionality using jQuery. The XHTML A simple link. The CSS A little CSS for position and style. The jQuery...

  • By
    Using MooTools For Opacity

    Although it's possible to achieve opacity using CSS, the hacks involved aren't pretty. If you're using the MooTools JavaScript library, opacity is as easy as using an element's "set" method. The following MooTools snippet takes every image with the "opacity" class and sets...

Discussion

  1. 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. @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

    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. @What would you propose EllisGL?

  5. 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

    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. 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

    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. why don’t you use serialize($_POST) for data storing purposes? ;0)

  10. @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

    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. 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. any chance you can supply a download link to play with your files.
    would be much appreciated.

    Cheers

  14. Tana

    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. 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. 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. Updated, thanks Ben!

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

  19. 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. 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. great help mate!
    thanks!

  22. Timmy

    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?

  23. Delscorcho

    Hello. I am trying to create a form that allows users to upload a video file and an image file with variable text fields. I have the uploader. I have the text fields. 1) How do marry the two? 2) How do I get the information to write to an XML file? That information must include the filepath of the video file and the image file. I need the instructions to have comments with them, so that I understand what the lines of code is doing. Thank you so much for your help.

  24. Sarah

    Hey thank you for this code! I’m now learning about xml and this was very helpful. I have a question though, I would like to modify it, instead of an echo.. can I save it to an xml file that repeats keeps adding new data on each submission?

  25. FredTheWebGuy

    Dave, I just got a call from a client who asked for this functionality…and boom! here we are. Saved my hide again. As I’ve said it before: I owe you a beer. A keg, actually, at this juncture.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!