公司目前正在使用一套基于 TP5的开源商城,在线上测试过程中碰到了一个问题,微信支付完成后无法进行回调更新订单状态,简单点说就是钱没了,啥也没得到。
What?
这可是一个无法容忍的错误。
原本以为是微信支付配置环节出了问题,于是便去查看微信官网给出的帮助手册,又顺着流程走了一边,信心满满的又测试了一边,结果尴尬了,又损失了0.01人民币。
反复确认流程后,确认并不是配置的问题,于是便开始了百度,原来这一切都是在微信官网给出的SDK中的一段代码惹的祸,就这么一段代码让我们团队损失了接近1人民币。
//获取通知的数据
$xml = $GLOBALS['HTTP_RAW_POST_DATA']; // WxPay.Api.php 414 line
这段代码如果放在PHP7之前的版本是不会有任何问题的,但是在 PHP7版本中却已经__废除__了 HTTP\_RAW\_POST\_DATA
。
在官方文档中给了说明:
Warning This feature was DEPRECATED in PHP 5.6.0, and REMOVED as of PHP 7.0.0.
在 PHP5.6.0
发布的时候,就已经不推荐只用这种方法,于是在PHP 社区在开发 PHP7.0的时候直接就将其废弃掉了。
而官方也给出了替代的方案,那就是php://input
php://input
是个可以访问请求的原始数据的只读流。
POST
请求的情况下,最好使用 php://input
来代替 $HTTP\_RAW\_POST\_DATA
,因为它不依赖于特定的 php.ini
指令。
而且,这样的情况下 $HTTP\_RAW\_POST\_DATA
默认没有填充, 比激活 always\_populate\_raw\_post\_data
潜在需要更少的内存。 enctype="multipart/form-data"
的时候 php://input
是无效的。
Note
: 在 PHP 5.6 之前 php://input 打开的数据流只能读取一次; 数据流不支持 seek 操作。 不过,依赖于 SAPI 的实现,请求体数据被保存的时候, 它可以打开另一个 php://input 数据流并重新读取。 通常情况下,这种情况只是针对 POST 请求,而不是其他请求方式,比如 PUT 或者 PROPFIND。
于是我将这段代码改为了:
//获取通知的数据
$xml = file_get_contents("php://input"); // WxPay.Api.php 414 line
最后我又以0.01人民币的代价确认修复了这个 BUG。