文档章节

php://input、$_POST 和 $HTTP_RAW_POST_DATA 的区别与详解

big_cat
 big_cat
发布于 2016/03/04 14:55
字数 1495
阅读 396
收藏 5

        PHP 用于开发 webservice 的 API 接口与客户端做数据交互时不一定会使用 PHP 可以处理的数据格式进行通信,比如 API 常用的 json xml,在此场景下我们需要使用其他的方式获取客户端发来的数据然后进行处理,下面我们就实例模拟下客户端请求 PHP API 场景下的数据交互方式。

        同时要理解 get 请求并未携带表单数据,get 请求的本质是请求服务器的某一资源,其向服务器发送的数据都位于请求头的 Query String/Query Path 中,请求头是 uri,注意理解 get 请求的语意,是去服务器获取资源而不是向服务器发送“数据”。 post 请求则是载有 Form Data 即表单数据的, 是想服务器发送 “数据” 的

    get                                                                               post

        

    可以看出get的参数都是附在请求头中,并不像post中有content-length /content-type /from data 这些描述请求携带的数据内容的属性值

php支持的数据类型

PHP 支持的数据格式(注意:这里说的支持不是指简单的获取到,意为可以进行自动处理,自动填充到 $_POST/ $_FILES中去,再次强调,get 请求并没有向服务器发送“数据”,它是取,不是存,所以 $_GET 的是参数而不是数据)

    application/x-www-form-urlencoded 普通的表单数据

    multipart/form-data 上传文件的表单 enctype="multipart/form-data"

PHP 不支持的数据格式

     application/json

     application/xml


不能处理但可以获取到,你可以自己手动处理,参照表



application/x-www-form-urlencoded multipart/form-data  application/json application/xml
php://input 可获取 不可获取 可获取 可获取
$_POST 可获取 可获取 不可获取 不可获取
$HTTP_RAW_POST_DATA 可获取 不可获取 可获取 可获取


PS: $HTTP_RAW_POST_DATA 已经被 PHP7 废弃,原因是 php://input 完全囊括了它的所有功能,且其对服务器的压力要比 php://input 大很多,最懦弱的是它默认配置下是让位 $_POST 的,如果 $_POST 能处理数据的话他就得靠边站,当然你可以配置 php.ini 将 always_populate_raw_post_data  配置项打开,则会一直填充其所能识别的数据,即便 $_POST 的也能处理。


PHP的数据处理方式

php://input: 除数据类型为 multipart/form-data 的不能识别外,其他格式都可以获取,而后我们可以根据数据类型处理

$_POST: 可以识别 application/x-www-form-urlencoded multipart/form-data 格式,json xml 无法识别

$HTTP_RAW_POST_DATA :识别能力与 php://input 相同,默认配置下与 $_POST 互斥且优先级低于 $_POST


实例

先贴出服务端代码

注意当发送的数据为 multipart/form-data 时 PHP 会将文件类型的数据存放在 $_FILES 中,文本的存放于 $_POST 中,但他们是同一组的,都是 from data 中的数据,与 $_GET 是不同的,$_GET 中填充的是请求头中 Query String 的参数

<?php
/**
 * @author sallency
 * @date 2016-3-4 11:03:23
 * @desc 简单模拟PHP作为API时如何处理各种格式的数据
 */

error_reporting(0);

echo "==== 客户端发送的数据格式 =====" . PHP_EOL;
echo "REQUEST_METHOD: " . $_SERVER['REQUEST_METHOD'] . PHP_EOL;
echo "ACCEPT: " . $_SERVER['HTTP_ACCEPT'] . PHP_EOL;
echo "CONTENT_TYPE: " . ($_SERVER['CONTENT_TYPE'] ? $_SERVER['CONTENT_TYPE'] : "null") . PHP_EOL;

echo PHP_EOL . "===== php://input 数据 ========" . PHP_EOL;
echo file_get_contents('php://input') . PHP_EOL;

echo PHP_EOL . '===== $_POST 数据 =============' . PHP_EOL;
print_r($_POST);

//当 multipart/form-data 类型时文件数据是存放在 $_FILES 中的 文本则 $_POST 中
echo PHP_EOL . '===== $_FILES 数据 =============' . PHP_EOL;
print_r($_FILES);

echo PHP_EOL . '===== $HTTP_RAW_POST_DATA =====' . PHP_EOL;
echo $HTTP_RAW_POST_DATA ? $HTTP_RAW_POST_DATA : 'null' . PHP_EOL;

?>

1、发送 application/x-www-form-urlencoded 标准数据 

    

            可以看出 php://input 和  $_POST/$_FILES 里都能正常识别接收此类型的数据,其实 $_HTTP_RAW_POST_DATA 也能接受,但我们说过默认情况下它和 $_POST/$_FILES 是互斥且优先级低,所以 $_POST/$_FILES 中有数据时它就不会被填充了,可修改配置让他一直填充自己可识别的数据。

2、发送 multipart/form-data

    php://input 和 $HTTP_RAW_POST_DATA 为空,说明它俩无法识别此类行的数据流(其实也只是不能识别此类行的,其他的都没问题),$_POST/$_FILES 则可以正常识别

3、发送 application/json 格式

    

        数据体:   

        

    php://input 和 $HTTP_RAW_POST_DATA 可识别, $_POST 则无法识别

4、发送 application/xml 格式

       

            数据体:

               

            php://input 和 $HTTP_RAW_POST_DATA 可识别, $_POST 则无法识别

总结

        当然还有很多其他的数据类型我们就不做测试了,大家可以自己动手。

        application/x-www-form-urlencoded 是 PHP 的标准数据流类型, 可以被三者识别

        multipart/form-data 只能被 $_POST/$_FILES 识别处理,另外的两者无法识别

        application/json application/xml 等就只能被 php://input 和 $HTTP_RAW_POST_DATA 识别了,这也是我们日常开发接口时往往使用 php://input 数据输入流来获取客户端请求携带的数据

        PS:    除了 POST 动作可携带数据体, PUT/PATCH/OPTIONS/HEAD/DELETE动作也都可以携带数据体,它们不像 POST 动作数据会被自动填充处理, 没有对应的全局变量,这时我们就可以使用 php://input 来获取此类动作所携带的原始数据。

        GET/VIEW 动作不携带数据流所以三者都会是空,但 $_GET 会被填充

                    PHP 的 $_POST 中只会填充数据格式OK的 POST 动作的数据, 但 POST/PUT/PATCH/DELETE/OPTION 在数据格式符合的前提下请求会填充到 php://input 中,$HTTP_RAW_POST_DATA 则无法响应 PUT/PATCH/DELETE/OPTION 动作的数据,例如:

          PUT 请求

        

            PATCH 请求

          

                 DELETE请求

          

                OPTIONS 请求

           

                HEAD 请求则返回响应头信息

           

            

© 著作权归作者所有

big_cat
粉丝 49
博文 237
码字总数 162865
作品 0
长宁
后端工程师
私信 提问
php://input,$_POST,$HTTP_RAW_POST_DATA区别

我们先来看两个demo 例子:php://input 代码如下 post.php 代码如下 例子:$_post 代码如下 welcome.php 代码如下 再来看$GLOBALS ["HTTP_RAW_POST_DATA"] 通过 HTTP POST 发送的变量不会显示...

Grace_
2017/10/20
15
0
php获取输入流

uc中的用到的代码(在api/uc.php)代码: $post = xmlunserialize(fileget_contents('php://input')); php手册(http://cn.php.net/manual/zh/wrappers.php.php)说明: php://input allows ......

wangtaotao
2011/02/16
0
0
PHP的"php://input"和$HTTP_RAW_POST_DATA 和$_POST的关系

最近一直在写接口,顺便把 php 输入输出流相关知识点学习了一遍 理论知识 php://input php://input 数据输入流存放着 post 请求发送过来的原生数据,但 Content-Type:multipart/form-data(...

big_cat
2015/11/28
386
0
深入剖析PHP输入流 php://input

PHP输入流php://input在使用xml-rpc的时候,server端获取client数据,主要是通过php输入流input,而不是$POST数组。所以,这里主要探讨php输入流php://input对于php://input介绍,PHP官方手册...

xuanskyer
2016/07/03
141
0
php://input和php://output

php://input 简介 php://input 是个可以访问请求的原始数据的只读流。 POST 请求的情况下,最好使用 php://input 来代替 $HTTPRAWPOST_DATA(原生的post数据),因为它不依赖于特定的 php.in...

echojson
04/05
128
0

没有更多内容

加载失败,请刷新页面

加载更多

Java集合类常见面试知识点总结

Java集合类学习总结 这篇总结是基于之前博客内容的一个整理和回顾。 这里先简单地总结一下,更多详细内容请参考我的专栏:深入浅出Java核心技术 https://blog.csdn.net/column/details/21930...

Java技术江湖
28分钟前
5
0
怎么用for循环打出爱心

先上效果图: 这是用*组成的爱心,下面讲讲思路: 首先这个图形可以拆分成三部分:第一部分是上面三行的两个梯形,第二部分是中间三行的长方形,第三部分是最下面的倒三角形。 其实图形拆分好...

INEVITABLE
34分钟前
4
0
用HttpUrlConnection伪造成HttpClient

https://www.jianshu.com/p/27ad06cc39d2

shzwork
40分钟前
4
0
Golang net/http处理表单请求

代码示范: package mainimport ("fmt""html/template""net/http")const tpl = `<html><head><title>Hey</title></head><body><form method="POST" action="/">......

听夜深窗外风
47分钟前
5
0
博客迁移 开源中国博客不再更新 之后考虑关停

博客迁移 开源中国博客不再更新 之后考虑关停 我的博客地址:blog.mrpei.cc

MrPei
47分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部