Watch Your POST: Save PHP POST Data as XML
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!
- Login or register to post comments
- 2854 reads
- Flag as offensive
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)







Comments
Ian Maddox replied on Wed, 2008/03/26 - 3:59pm
This is an interesting concept, but the XML it generates may not be well-formed.
In the section shown below, the child elements have numeric names, but the first character of an XML element must be either an alpha char, a colon, or an underscore.
David Walsh replied on Wed, 2008/03/26 - 4:09pm
Mark replied on Wed, 2008/03/26 - 8:29pm
I hate to rain on your parade, but you've done a pretty mediocre job of re-inventing a wheel here.
Firstly theres no filtering of user input. If youre going to echo this to the page then you're opening it up to XSS attacks, if you're inserting into a database then you need to make sure you're escaping correctly.
Secondly (and perhaps most importantly), I'm left wondering why you needed to write this function at all? You could have used either the serialize function or JSON encoding (or no doubt a whole slew of existing libraries or code) to do a very similar thing in one line. They would be easier to parse and probably require less storage.
Then there's the really important point that hoping to parse your XML without enforcing wellformedness is just a nightmare waiting to happen. If you do insist on using XML for this, your reason is that you can parse it with other tools a later date, but with your current schema you'd need to either tokenise or regex it to all buggery for it to be reliable. Plus because you're not filtering user input theres no certainty that the user won't have added their own XML.
David Walsh replied on Wed, 2008/03/26 - 8:56pm
Thank you for your post Mark -- my parade continues to see sunshine.
Scrubbing input before inserting into the DB is a given and can be done after the function is run. I don't do any DB scrubbing in the function because I currently use the function to write the POST=>XML info to file.
Serializing the data is another option.
This function has worked great for me. Feel free to post your similar article to the PHP Zone!