做微信开发时,接收微信端发过来的数据,是一件苦恼事。(不过至少比微博强几倍)
按照腾讯官网给的demo代码,是用$GLOBALS["HTTP_RAW_POST_DATA"]
接收XML格式数据,再进行分析。
腾讯微信demo代码片段:
1 2 3 4 5 |
public function responseMsg() { //get post data, May be due to the different environments $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; ...... |
一般情况下,HTTP_RAW_POST_DATA 只有在MIME类型无法识别的时候才会有值,否则$GLOBALS["HTTP_RAW_POST_DATA这个参数"]
就是空的。除非在php.ini中开启always_populate_raw_post_data
,但是这是一个全局设置,会影响整个php环境,会浪费很多内存。
正经的请求一般都是有标准的MIME type的,比如application/x-www-form-urlencoded,这种请求就没有 HTTP_RAW_POST_DATA 数据。如果想要设计个用于转发微信数据的中心服务器,因为收到的是没有MIME类型的数据,但数据很明显是标准的json或者xml格式,处理转发时就很容易被curl等函数自己加上标准的MIME type,导致最终的接收服务器读不到 HTTP_RAW_POST_DATA 。不得不说微信做的这玩意真心没什么技术标准。(不过至少比微博强几倍)
HTTP_RAW_POST_DATA 这个参数在php5.6之后已经不建议使用了,并且在最新发布的php7版本中已经删除。参见: [$HTTP_RAW_POST_DATA]
建议使用 php://input 代替 HTTP_RAW_POST_DATA 使用。
代码:
1 |
$postdata = file_get_contents("php://input"); |
使用方法并没有什么区别,php://input 的数据与开启了always_populate_raw_post_data
的 HTTP_RAW_POST_DATA 是相同的,但 php://input 不需要设置 php.ini ,使用更灵活。
关于 php://input 的更多信息,参见:[php://input]
2015年12月16日更新:
微信服务器发送过来的Content-Type是text/xml,这玩意我一直不知道怎么处理,看别人一直都是在用simplexml_load_string处理。
simplexml_load_string只能接受xml格式的字符串,如果是非xml的字符串,那就返回false。但是有可能报PHP Warning。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
POST /wechat/index?signature=51318fcb570a55ae6916269eba4383e30038f163×tamp=1450248974&nonce=1860079439 HTTP/1.0 User-Agent: Mozilla/4.0 Accept: */* Host: a.b.com Pragma: no-cache Content-Length: 276 Content-Type: text/xml <xml><ToUserName><![CDATA[gh_d421f2f2553a]]></ToUserName> <FromUserName><![CDATA[okKzOt69Ak1nasDd3yFV8kw2ktLU]]></FromUserName> <CreateTime>1450248974</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[message]]></Content> <MsgId>6228771914789178470</MsgId> </xml> |
虽然自己能保证传的文件就是xml,但是保不齐有外部调用,往我这里面塞其他东西。今天遇到问题,有同事调用,塞了个get格式的字符串过来。之前没做xml的判断,直接搞得整个系统报500错误。
没想到好的解决办法,毕竟腾讯并没有在其文档中声明他发的是什么破玩意,get/post混用,xml和json混用,简直就是刚实习1个月的实习生写出来的。
近期评论