您的位置:首页 > 编程语言 > PHP开发

php://input

2014-01-22 10:18 288 查看
在使用xml-rpc的时候,server端获取client数据,主要是通过php输入流input,而不是$_POST数组。所以,这里主要探讨php输入流php://input

  对一php://input介绍,PHP官方手册文档有一段话对它进行了很明确地概述。

  “php://input allows you to read raw POST data. It is a less memory intensive alternative to $HTTP_RAW_POST_DATA and does not need any special php.ini directives. php://input is not available with enctype=”multipart/form-data”.

  翻译过来,是这样:

  “php://input可以读取没有处理过的POST数据。相较于$HTTP_RAW_POST_DATA而言,它给内存带来的压力较小,并且不需要特殊的php.ini设置。php://input不能用于enctype=multipart/form-data”。

  1,Content-Type取值为application/x-www-form-urlencoded时,php会将http请求body相应数据会填入到数组$_POST,填入到$_POST数组中的数据是进行urldecode()解析的结果。(其实,除了该Content-Type,还有multipart/form-data表示数据是表单数据,稍后我们介绍)

  2,php://input数据,只要Content-Type不为multipart/form-data(该条件限制稍后会介绍)。那么php://input数据与http entity body部分数据是一致的。该部分相一致的数据的长度由Content-Length指定。

  3,仅当Content-Type为application/x-www-form-urlencoded且提交方法是POST方法时,$_POST数据与php://input数据才是”一致”(打上引号,表示它们格式不一致,内容一致)的。其它情况,它们都不一致。

  4,php://input读取不到$_GET数据。是因为$_GET数据作为query_path写在http请求头部(header)的PATH字段,而不是写在http请求的body部分。

  相信大家对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。

  学习笔记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为空。

模拟服务端程序如下:

[php] view
plaincopy

<?php

//@file phpinput_server.php

$raw_post_data = file_get_contents('php://input', 'r');

echo "-------\<pre class="php" name="code">{1}</pre><br>

POST------------------\n";echo var_dump(<pre class="php" name="code">{1}</pre><br>

POST) . "\n";echo "-------php://input-------------\n";echo $raw_post_data . "\n";?>

<pre></pre>

<p><br>

</p>

<p>模拟客户端脚本如下:</p>

<p> </p>

<pre class="php" name="code"><?php

//@file phpinput_post.php

$http_entity_body = 'n=' . urldecode('perfgeeks') . '&=' . urlencode('7788');

$http_entity_type = 'application/x-www-form-urlencoded';

$http_entity_length = strlen($http_entity_body);

$host = 'localhost';

$port = 80;

$path = '/ceshi/phpinput_server.php';

$fp = fsockopen($host, $port, $error_no, $error_desc, 30);

if ($fp) {

fputs($fp, "POST {$path} HTTP/1.1\r\n");

fputs($fp, "Host: {$host}\r\n");

fputs($fp, "Content-Type: {$http_entity_type}\r\n");

fputs($fp, "Content-Length: {$http_entity_length}\r\n");

fputs($fp, "Connection: close\r\n\r\n");

fputs($fp, $http_entity_body . "\r\n\r\n");

while (!feof($fp)) {

$d .= fgets($fp, 4096);

}

fclose($fp);

echo $d;

}

?>

</pre>

<p><br>

</p>

<p> </p>

<p>执行客户端结果如下:</p>

<p> </p>

<pre class="plain" name="code">HTTP/1.1 200 OK Date: Fri, 19 Aug 2011 06:37:13 GMT Server: Apache/2.2.17 (Win32) PHP/5.3.5 X-Powered-By: PHP/5.3.5 Content-Length: 387 Connection: close Content-Type: text/html -------<pre class="plain" name="code">{1}</pre><br>

POST------------------array 'n' => string 'perfgeeks' (length=9) 'amp' => string '7788' (length=4)-------php://input------------- n=perfgeeks&=7788

<pre></pre>

<p><br>

</p>

</pre>

附加转载一篇 :

在看接受flash传过来的图片这个功能的时候,看到了这个

php://input allows you to read raw data from the request body. In case of POST requests, it preferrable to $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives. Moreover, for those cases where $HTTP_RAW_POST_DATA is not populated by default,
it is a potentially less memory intensive alternative to activating always_populate_raw_post_data. php://input is not available with enctype=mio_quot;multipart/form-datamio_quot;.

Note: A stream opened with php://input can only be read once; the stream does not support seek operations. However, depending on the SAPI implementation, it may be possible to open another php://input stream and restart reading. This is only possible if the
request body data has been saved. Typically, this is the case for POST requests, but not other request methods, such as PUT or PROPFIND.

理解

1.符号的理解:与符号”http://“对比。可以理解php://表示这是一种协议。不同的是它是php自己定义与使用的协议。

输入域名的时候,htt://后面输入的是域的名字。那么php://后面的mio_quot;inputmio_quot;也可以表示一个文件。是一个php已经定义好的文件。比如有ouput。php自己知道去哪里找这个文件。

2.相关联知识: 常量$HTTP_RAW_POST_DATA是获取post提交的原始数据(contains the raw POST data)。php://input 的所完成的功能与它一样:都是包含post过来的原始数据。

使用php://input比$HTTP_RAW_POST_DATA更好。因为:使用php://inpu不受到配置文件的影响。常量$HTTP_RAW_POST_DATA受到php.ini配置的影响。在php.ini中有个选项,always_populate_raw_post_data = On。该配置决定是否生成常量$HTTP_RAW_POST_DATA(保存post数据)。

php://input的方式与$HTTP_RAW_POST_DATA数据都同样不适用于表单提交的mio_quot;multipart/form-datamio_quot;类型的数据。所以,两种的区别就是在于是否受到配置文件的影响。另外,内存消耗更少,这个怎么理解?

3.怎么得到其内容:使用file_get_contents(mio_#39;php://inputmio_#39;)得到输入流的内容。php://input的结果只读。

4.使用规则:必须是post方式提交的数据。而且提交的不能是multipart/form-data类型的数据(当需要上传文件,就会在form标签中添加属性enctype=mio_quot;multipart/form-datamio_quot;)

想更好地理解它是怎么使用的。做个试验就明白:

html文件输入内容:

提交后,得到结果:

string(97) mio_quot;username=%E5%90%8D%E5%AD%97mio_password=%E5%AF%86%E7%A0%81mio_name=%E6%8F%90%E4%BA%A4%E6%95%B0%E6%8D%AEmio_quot;

接下来改为get方式提交,结果为:

string(0) mio_quot;mio_quot;

说明没有任何数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: