HTTP 协议是建立在 TCP/IP 协议之上的应用层规范,它把 HTTP 请求分为三个部分:请求行、请求头、消息主体。协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据使用什么编码方式。
服务端通常是根据请求头(headers)中的 Content-Type 来获知请求中的消息主体是用何种方式编码的,再对消息主体进行解析。
当客户端通过 POST 请求访问服务器时,可通过下面三种方式来获取 POST 提交的数据 :
$_POST
$_POST是我们最常用的获取POST数据的方式,它是以关联数组方式组织提交的数据,仅当请求头中的 Content-Type 为 application/x-www-data-urlencoded 或 multipart/form-data时,PHP 才会将 POST 数据填充到全局变量 $_POST。
如:表单数据的POST方式提交或curl模拟POST请求时传入数组格式的POST数据(不要使用二维数组)。
> 无法解析如text/xml,application/json等非 application/x-www.form-urlencoded 数据类型的内容
$HTTP_RAW_POST_DATA
$HTTP_RAW_POST_DATA - 原生POST数据
警告:这个特性在PHP 5.6.0中是过时的,从PHP 7.0.0开始已经被删除了。
当请求头中的 Content-Type不是PHP能够识别的(如:xml、json),且 php.ini中已经配置always_populate_raw_post_data = On,
才可以使用 $HTTP_RAW_POST_DATA。但对于enctype="multipart/form-data",它是无效的。
$HTTP_RAW_POST_DATA 或 $GLOBALS['HTTP_RAW_POST_DATA']中包含的是原生的 POST 数据。
> 需要设置 php.ini 中的 always_populate_raw_post_data 值为 On 才会生效
> 当$_POST 与 php://input可以取到值时 $HTTP_RAW_POST_DATA 为空
> 不能用于 enctype="multipart/form-data"
> PHP7中已经移除了这个全局变量,用 php://input 替代
> 相当于:$foo = $HTTP_RAW_POST_DATA;
$foo = file_get_contents("php://input");
php: //input
它通过输入流以文件读取方式取得未经处理的POST原始数据,允许读取 POST 的原始数据。和 $HTTP_RAW_POST_DATA 比起来,
它给内存带来的压力较小,当请求头中的 Content-Type 不是 PHP 能够识别的(如:xml、json),就可以使用 php: //input。
> 如:curl模拟POST请求时传入的json格式的字符串(可以是二维json)或任意字符串。