php://input是什么意思?php输入流input的介绍
PHP输入流php://input
同时,我们通过ngrep抓取的相应的http请求数据包如下:
########T 192.168.0.8:3981 -> 192.168.0.6:80 [AP] POST /phpinput_server.php HTTP/1.1..Host: 192.168.0.6..Connection: kee p-alive..User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) A ppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.3 Safari/533.2..Re ferer: http://192.168.0.6/phpinput_server.php..Content-Length: 306..Ca che-Control: max-age=0..Origin: http://192.168.0.6..Content-Type: mult ipart/form-data; boundary=----WebKitFormBoundarybLQwkp4opIEZn1fA..Acce pt: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q =0.8,image/png,*/*;q=0.5..Accept-Encoding: gzip,deflate,sdch..Accept-L anguage: zh-CN,zh;q=0.8..Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3..Cook ie: SESS3b0e658f87cf58240de13ab43a399df6=lju6o5bg8u04lv1ojugm2ccic6... .##T 192.168.0.8:3981 -> 192.168.0.6:80 [AP] ------WebKitFormBoundarybLQwkp4opIEZn1fA..Content-Disposition: form-da ta; name="n"....perfgeeks..------WebKitFormBoundarybLQwkp4opIEZn1fA..C ontent-Disposition: form-data; name="f"; filename="test.txt"..Content- Type: text/plain....i am file..multipart/form-data..------WebKitFormBo undarybLQwkp4opIEZn1fA--..##
从响应输出来比对,$_POST数据跟请求提交数据相符,即$_POST = array(‘n’ => ‘perfgeeks’)。这也跟http请求body中的数据相呼应,同时说明PHP把相应的数据填入$_POST全局变量。而php://input输出为空,没有输出任何东西,尽管http请求数据包中body不为空。这表示,当Content-Type为multipart/form-data的时候,即便http请求body中存在数据,php://input也为空,PHP此时,不会把数据填入php://input流。所以,可以确定: php://input不能用于读取enctype=multipart/form-data数据。
我们再比较这次通过ngrep抓取的http请求数据包,我们会发现,最大不同的一点是Content-Type后面跟了boundary定义了数据的分界符,bounday是随机生成的。另外一个大不一样的,就是http entity body中的数据组织结构不一样了。
上一节,我们概述了,当Content-Type为application/x-www-form-urlencoded时,php://input和$_POST数据是“一致”的,为其它Content-Type的时候,php://input和$_POST数据数据是不一致的。因为只有在Content-Type为application/x-www-form-urlencoded或者为multipart/form-data的时候,PHP才会将http请求数据包中的body相应部分数据填入$_POST全局变量中,其它情况PHP都忽略。而php://input除了在数据类型为multipart/form-data之外为空外,其它情况都可能不为空。通过这一节,我们更加明白了php://input与$_POST的区别与联系。所以,再次确认,php://input无法读取enctype=multipart/form-data数据,当php://input遇到它时,永远为空,即便http entity body有数据。
php://input VS $http_raw_post_data相信大家对php://input已经有一定深度地了解了。那么$http_raw_post_data是什么呢?$http_raw_post_data是PHP内置的一个全局变量。它用于,PHP在无法识别的Content-Type的情况下,将POST过来的数据原样地填入变量$http_raw_post_data。它同样无法读取Content-Type为multipart/form-data的POST数据。需要设置php.ini中的always_populate_raw_post_data值为On,PHP才会总把POST数据填入变量$http_raw_post_data。
把脚本phpinput_server.php改变一下,可以验证上述内容
<?php$raw_post_data = file_get_contents('php://input', 'r');$rtn = ($raw_post_data == $HTTP_RAW_POST_DATA) ? 1 : 0;echo $rtn;?>执行测试脚本
@php phpinput_post.php@php phpinput_get.php@php phpinput_xmlrpc.php
得出的结果输出都是一样的,即都为1,表示php://input和$HTTP_RAW_POST_DATA是相同的。至于对内存的压力,我们这里就不做细致地测试了。有兴趣的,可以通过xhprof进行测试和观察。
以此,我们这节可以总结如下:
1, php://input 可以读取http entity body中指定长度的值,由Content-Length指定长度,不管是POST方式或者GET方法提交过来的数据。但是,一般GET方法提交数据时,http request entity body部分都为空。
2,php://input 与$HTTP_RAW_POST_DATA读取的数据是一样的,都只读取Content-Type不为multipart/form-data的数据。
1,Coentent-Type仅在取值为application/x-www-data-urlencoded和multipart/form-data两种情况下,PHP才会将http请求数据包中相应的数据填入全局变量$_POST
2,PHP不能识别的Content-Type类型的时候,会将http请求包中相应的数据填入变量$HTTP_RAW_POST_DATA
3, ?只有Coentent-Type不为multipart/form-data的时候,PHP不会将http请求数据包中的相应数据填入php://input,否则其它情况都会。填入的长度,由Coentent-Length指定。
4,只有Content-Type为application/x-www-data-urlencoded时,php://input数据才跟$_POST数据相一致。
5,php://input数据总是跟$HTTP_RAW_POST_DATA相同,但是php://input比$HTTP_RAW_POST_DATA更凑效,且不需要特殊设置php.ini
6,PHP会将PATH字段的query_path部分,填入全局变量$_GET。通常情况下,GET方法提交的http请求,body为空。
