PayPal's sample code for a PHP IPN listener has this comment/code at the top:
// reading posted data from directly from $_POST causes serialization
// issues with array data in POST
// reading raw POST data from input stream instead.
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
$keyval = explode ('=', $keyval);
if (count($keyval) == 2)
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
Can someone explain what serialization issues this comment refers to? While I'm ok doing it this way, I would feel more comfortable knowing why it should be done this way.
I can't tell you paypals motivations, but I can guess: php likes to change the keys of incoming variables from an http request.
For example, the name a.b [
would show up as $_POST['a_b__']
. php will replace spaces, dots, and open brackets with underscores:
source: http://php.net/manual/en/language.variables.external.php
Also, php will parse well formed matching brackets in variable names into nested arrays. eg, arr[a][b]
would show up as $_POST['arr']['a']['b']
.
http://php.net/manual/en/faq.html.php#faq.html.arrays
Also, php behaves all kinds of crazy and buggy when brackets aren't well formed: https://bugs.php.net/bug.php?id=48597
Also, magic_quotes_gpc
used to have its talons into every php installation, changing the names of variables in certain cases too. http://php.net/manual/en/security.magicquotes.php
Also, php has the arg_seperator.input
setting, and some people like to set this to &
instead of just &
. Paypal cannot know which you prefer, and would obviously always use &
when crafting a url and/or post body to request, causing your php engine to parse the params wrong.
http://php.net/manual/en/ini.core.php#ini.arg-separator.input
Also, despite being bad practice, it's not too uncommon in php for code/libraries to automatically modify the request inputs such as $_POST
, eg to xss "sanitize" them or other such cross cutting concerns. $_POST is a writable/modifiable variable, whereas php://input is read only, so it's guaranteed not to be mucked with by libraries.
By parsing the input manually, you avoid all those potential issues. This decision seems like good engineering on their part.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With