PayPal PHP IPN示例提到了哪些POST序列化问题?

12

PayPal的PHP IPN监听器示例代码顶部有这个注释/代码:

// 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]);
}

有人能解释一下这条评论所提到的序列化问题吗?虽然我可以按照这种方式操作,但是如果知道为什么应该这样做,我会感觉更加舒适。


不确定上下文中这意味着什么,但是 $_POST 并不总是包含与 php://input 相同的内容。例如:key=val1&key=val2 将在 $_POST 数组中只产生一个 key 条目。而且,php://input 是只读的,而 $_POST 不是。 - Wesley Murch
看着我放上去的测试页面,$raw_post_array确实包含了两个“key”条目,以索引数组的形式。 然而,样例代码的其余部分最终将原始数据解析为一个数组。比较这两个数组,它们的自定义$myPost数组与$_POST完全相同。也就是说:保留最后声明的$key = 'val2'。 - Jason Taylor
为什么他们不直接使用parse_str,而要用这种方式呢?难道它有一些奇怪的特性吗?毕竟,它使用的是生成$_GET$_POST的相同代码... - Charles
示例代码将是最糟糕的! - Gabriel Santos
我在PayPal找到的一些代码是冗余的。你可以只使用if(get_magic_quotes_gpc())curl_setopt_array() - StackSlave
1个回答

13

我无法告诉你Paypal的动机,但是我可以猜测:PHP喜欢更改来自HTTP请求的变量键。

例如,名称a.b [会显示为$_POST ['a_b__']。 PHP将使用下划线替换空格、点和开括号: 来源:http://php.net/manual/en/language.variables.external.php

此外,PHP将解析变量名称中形式良好的匹配括号为嵌套数组。例如,arr[a][b]将显示为$_POST ['arr'] ['a'] ['b']http://php.net/manual/en/faq.html.php#faq.html.arrays

此外,当括号形式不良时,PHP的行为很疯狂和有缺陷: https://bugs.php.net/bug.php?id=48597

此外,magic_quotes_gpc曾经在每个PHP安装中都有其爪子,在某些情况下也会更改变量名称。 http://php.net/manual/en/security.magicquotes.php

此外,PHP具有arg_seperator.input设置,有些人喜欢将其设置为&而不仅仅是&。 Paypal 无法知道您的偏好,显然会在构建URL和/或POST请求体时始终使用&,从而导致您的PHP引擎错误解析参数。 http://php.net/manual/en/ini.core.php#ini.arg-separator.input

此外,尽管这是一个不好的实践,在php中代码/库自动修改请求输入(例如$_POST)并对它们进行xss“消毒”或其他与跨层关注点相关的操作也并不罕见。 $_POST是一个可写/可修改的变量,而php://input是只读的,因此可以保证它不会被库破坏。

通过手动解析输入,您可以避免所有这些潜在问题。这个决定似乎是他们良好工程实践的体现。


2
太棒了的回答。谢谢你提供的参考资料! - Jason Taylor
好的答案。现在有意义了。 - Daniel West
谢谢。这也让我感到困惑。 - Mark Roworth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接