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

        PHP 用于开发 webservice 的 API 接口与客户端作数据交互时不必定会使用 PHP 能够处理的数据格式进行通讯,好比 API 经常使用的 json xml,在此场景下咱们须要使用其余的方式获取客户端发来的数据而后进行处理,下面咱们就实例模拟下客户端请求 PHP API 场景下的数据交互方式。
php

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

    get                                                                               postjson

        

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

php支持的数据类型

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

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

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

PHP 不支持的数据格式url

     application/jsonspa

     application/xml
code


不能处理但能够获取到,你能够本身手动处理,参照表



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;

?>

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

    

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

二、发送 multipart/form-data

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

三、发送 application/json 格式

    

        数据体:   

        

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

四、发送 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 请求则返回响应头信息

           

相关文章
相关标签/搜索