2019独角兽企业重金招聘Python工程师标准>>>

最近一直在写接口,顺便把 php 输入输出流相关知识点学习了一遍

理论知识

php://input

php://input 数据输入流存放着 post 请求发送过来的原生数据,但 Content-Type:multipart/form-data(上传文件或图片的表单)的数据则不会载入其中,其他类型:

application/x-www-form-urlencode    foo1=bar1&foo2=bar2 普通的表单数据

application/json   {"foo1":"bar1", "foo2":"bar2",}

application/xml   <xml version="1.0"><data><foo1>bar1</foo1><foo2>bar2</foo2></data>

都会被载入其中

$HTTP_RAW_POST_DATA

$HTTP_RAW_POST_DATA 中的内容与 php://input 并无区别,同样无法识别

Content-Type:multipart/form-data 的请求数据,且默认情况下它与 $_POST 互斥,即若请求数据格式可以填充至 $_POST 中去,即便它也能识别,也不会填充数据,比如 application/x-www-form-urlencode 类型的请求数据, php://input $_POST 和 它都能识别,但 $_POST 填充后默认配置下它是不会被填充的,除非修改 php.ini 文件将  always_populate_raw_post_data 配置参数使能,即只要能识别,就填充,不管 $_POST 是否被填充

$_POST

php 能自动识别处理填充到 $_POST 数组中的只有:

application/x-www-form-urlencode    不含有文件的表单

multipart/form-data   含有文件的表单(此时 php://input 和 $HTTP_RAW_POST_DATA 是无法识别数据流的)

两种php的标准数据类型

客户端的GET/POST的本质区别

GET 不包含数据流

GET请求并不像POST请求会有 form body 数据,GET请求的所有信息都包含在了请求的header中 query string 中,通过url进行传递,说白了它所代表的是一个标识而不含有数据流,所以PHP并不会把 GET 请求装入数据流中,而只是简单的将其解析填充到$_GET数组当中

请求头:

GET url HTTP/1.1

Accept:期待服务器返回什么格式的数据 text/html application/json application/xml image/jpeg video/mp4 等等

POST 含有数据流

POST请求包括header和from body,header头指明请求的url,form body 中存放数据提交给服务端,PHP 会根据提交的数据类型动态的将数据流转化为相应的模式,比如一下两种PHP能识别处理POST请求的数据类型

Content-Type:application/x-www-form-urlencoded //普通的表单
Content-Type:multipart/form-data //encrypt mutiple/form-data

=====================================================================

=====================================================================

其实你会发现普通的表单提交 from data 所携带的数据编码同 get 请求中的 query string 完全一样,但这也是他们的本质区别, get 并不携带数据流 ,它完全整合到 header 流中去,php 将其填充到 $_GET 数组中 , $_POST 数组中则是能被 PHP 识别并处理的 请求中的 from body (呃,就是 from data)中的数据

=====================================================================

=====================================================================

服务器端对POST请求的处理

PHP能识别并处理的POST请求的数据类型只有

application/x-www-form-urlencode

multipart/form-data

注意是识别并处理,将 POST 过来的数据识别处理填充到全局 $_POST 数组中去,其他类型的数据则无法填充 $_POST 数组

但在工作中我们不可能一直用表单请求服务器,APP开发时请求服务端往往发送的是 applicantion/json 或 applicant/xml 类型的参数数据,这时 PHP 无法识别处理此类数据流,但 PHP 会将此数据流存放在 php://input 数据流中

php://input 数据流

php://input 数据流存放的内容和 $HTTP_RAW_POST_DATA 的内容完全一样 但牵扯到性能方面的问题我们这里不推荐使用 $HTTP_RAW_POST_DATA  你可以认为 php://input 是一个资源

$input_stream = file_get_contents("php://input");

这样就获取到了此数据流中的内容

实例

服务器端

<?php
$input_stream =file_get_contents("php://input");
echo "==============this is php://input data===============\n";
echo $input_stream . "\n";
echo "==============this is post array data===============\n";
echo var_export($_POST, true);
?>

application/x-www-form-urlencoded post请求

curl -H "Content-Type:application/x-www-form-urlencoded" -X POST -d 'name=sallency&age=25' -o data.txt http://192.168.30.50:8082/curl.php//result
==============this is php://input data===============
name=sallency&age=25
==============this is post data===================
array ('name' => 'sallency','age' => '25',
)

application/json post请求

curl -H "Content-Type:application/json" -X POST --data '{"name":"sallency", "age":"25"}' -o data.txt http://192.168.30.50:8082/curl.php//result
==============this is php://input data===============
{"name":"sallency", "age":"25"}
==============this is post data===================
array (
)

application/xml post请求

curl -H "Content-Type:application/xml" -X POST -d '<?xml version="1.0" encoding="utf-8"?><user><name>sallency</name><age>25</age></user>' -o data.txt //result
<?xml version="1.0" encoding="utf-8"?><user><name>sallency</name><age>25</age></user>
==============this is post data===================
array (
)

由于模拟mutipart/form-data的表单提交比较复杂我们这里就不做模拟了

总结:

1、php 能识别处理的标准数据类型为:application/x-www-form-urlencoded(普通的表单) 和 mutipart/form-data(encrypt="mutipart/form-data" 的表单),其他的比如 application/json application/xml 是没有办法处理好填充到 $_POST 中去的,但它们会被填充到 php://input 流中(所谓处理是 php 自动解析好给你 拿来就用的意思 注意我文章中多次提到识别和处理 )

2、php://input 能识别处理 mutipart/form-data 外的所有类型的数据,将其填充到自己的数据流, 我们可以通过它获取数据手动解析

=====================================================================

这些为数据流资源符

php://input php://output
php://stdin php://stdout php://stderr

CLI下

STDIN = $stdin = fopen("php://stdin", "r") 是一样的 标准输入的句柄
STDOUT = $stdout = fopen("php://stdout", 'w')
STDERR = $stderr = fopen("php://stderr", 'w')
fread(STDIN, 1024)
fgets(STDIN)
while ($line = fgets(STDIN)) {echo $line;
}
fwrite(STDOUT, "hello world!")
file_get_contents("php://stdin")
file_put_contents("php://stdout", "hello world!")
STDIN STDOUT STDERR 为句柄 可以直接被fread fwrite fgets使用
file_get_contents()/file_put_contents()打开或写入的是资源而不是资源句柄

转载于:https://my.oschina.net/sallency/blog/536889

PHP的php://input和$HTTP_RAW_POST_DATA 和$_POST的关系相关推荐

  1. $GLOBALS['HTTP_RAW_POST_DATA'] 和$_POST的区别

    使用 $GLOBALS['HTTP_RAW_POST_DATA'] 要在php.ini里配置,也就是说要去always_populate_raw_post_data = On前的分号;  . $_PO ...

  2. php提交raw_PHP中$GLOBALS['HTTP_RAW_POST_DATA']和$_POST的区别分析

    本文分析了PHP中$GLOBALS['HTTP_RAW_POST_DATA']和$_POST的区别.分享给大家供大家参考,具体如下: $_POST:通过 HTTP POST 方法传递的变量组成的数组. ...

  3. php input 只接收文件内容,一文搞懂$_POST和file_get_contents(“php://input”)的区别

    今天来说一说 $_POST.file_get_contents("php://input")和$GLOBALS['HTTP_RAW_POST_DATA']的区别,这三个方法都是用来 ...

  4. PHP输入流php://input介绍

    在使用xml-rpc的时候,server端获取client数据,主要是通过php输入流input,而不是$_POST数组.所以,这里主要探讨php输入流php://input 对一php://inpu ...

  5. file_get_contents(php://input)的使用方法

    $data = file_get_contents("php://input");     php://input 是个可以访问请求的原始数据的只读流. POST 请求的情况下,最 ...

  6. php://input和php://output

    2019独角兽企业重金招聘Python工程师标准>>> php://input 简介 php://input 是个可以访问请求的原始数据的只读流. POST 请求的情况下,最好使用 ...

  7. PHP输入流 php://input 相关【转】

    为什么xml_rpc服务端读取数据都是通过file_get_contents('php://input', 'r').而不是从$_POST中读取,正是因为xml_rpc数据规格是xml,它的Conte ...

  8. 【转】file_get_contents(php://input)的使用方法

    $data = file_get_contents("php://input");     php://input 是个可以访问请求的原始数据的只读流. POST 请求的情况下,最 ...

  9. file_get_contents(php://input)

    $data = file_get_contents("php://input"); php://input 是个可以访问请求的原始数据的只读流. POST 请求的情况下,最好使用 ...

最新文章

  1. 函数assert()详解
  2. 三十七、下篇 | tkinter实现一个翻译软件
  3. 使用idea编写消费者,接收生产者的持续日志输出【小案例】(三)
  4. AMD桌面处理器Roadmap也已泄露
  5. 软件设计模式之单例模式
  6. CO2 convex sets
  7. python计算正弦值_Python科学计算(二)——正弦信号的时域波形与频谱图
  8. 图形化开发(五)041-Three.js之Camera相机——target焦点和lookAt()方法、OrthographicCamera正交相机、PerspectiveCamera透视相机、相机插件
  9. 手机浏览器打不开php,php 判断是否是手机浏览器访问?
  10. Phaser2.0 tween动画
  11. 史上最强模型 GPT-4 上线:一张手绘草图能生一个网站、60 秒搞定一个游戏开发!
  12. Wireshark抓包原理(ARP劫持、MAC泛洪)及数据流追踪和图像抓取(二)
  13. The Shawshank Redemption-20
  14. DTRO垃圾渗滤液处理设备技术要点详解
  15. 笔记本电脑设备管理器中'符合USBxHCI的主机控制器'出现感叹号,所有的USB接口失灵--解决
  16. 分享简单易用的配网终端加密模块
  17. Python 打印菱形
  18. 百度干部轮岗:沈抖领军智能云 何俊杰任百度移动生态事业群组负责人
  19. 预测模型 | 8. 一致性指数 (Concordance Index, C-index) ci值 cox
  20. Adobe Premiere Pro CC 2015打不开闪退

热门文章

  1. 学好C++能够从事哪些岗位?
  2. Visual Studio 代码风格约束
  3. centos(7.0) 上 crontab 计划任务
  4. Centos6.3 PHP编译安装JSON模块报错解决
  5. cocos2d-x内存自动释放机制
  6. Enterprise Library:Unity的几个注意事项
  7. 您已登录了一个相同的QQ账号,不能重复登录”的解决办法
  8. 《.NET框架程序设计》第5章 基元类型、引用类型与值类型
  9. 【重点】LeetCode 143. Reorder List
  10. TCP连接发送窗口问题思考