几种content-type提交以及$_POST 和php://input

  在表单提交数据时,需要告诉服务端自己的content-type,好让服务端处理。

  默认表单提交是x-www-form-urlencoded,还有一种常见的 multipart/form-data。那这俩的区别是啥呢?

  在postman工具中,很容易看出来二者的区别。

      x-www-form-urlencoded:

  

查看http请求:

POST /hi.php HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: a1054dd4-5f58-038c-6082-326721c85a7a

id=1%2B1&val=44753

在 x-www-form-urlencoded中,body体中是key=value&key=xx形式,并且是urlencode后的。

 

 

 multipart/form-data:

 

查看http请求:

POST /hi.php HTTP/1.1
Host: localhost
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: dddb1f15-348b-5e3f-244c-aa0d8680bd3d

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="id"

1+1
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="val"

44753
------WebKitFormBoundary7MA4YWxkTrZu0gW--

form-data中含有boundary=----***

 

常见的content-type还有一种json形式:

Content-Type: application/json

 

查看http请求:

POST /hi.php HTTP/1.1
Host: localhost
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 38f8844e-bd9f-a892-5107-a3f4e6b81a41

{"a":"xx"}

 

 

再看下$_POST和php://input的区别联系

利用一段测试代码:

<?php
$arr = $_POST;
$raw_post_data = file_get_contents('php://input', 'r');

file_put_contents('hsd.log', "\$_POST\r\n".print_r($arr,true)."\r\n", FILE_APPEND);
file_put_contents('hsd.log', "php://input\r\n".print_r($raw_post_data,true)."\r\n", FILE_APPEND);
file_put_contents('hsd.log', "content_type: ".print_r($_SERVER['HTTP_CONTENT_TYPE'],true)."\r\n", FILE_APPEND);
file_put_contents('hsd.log', print_r("====================",true)."\r\n", FILE_APPEND);

 

在几种content-type表现如下:(php version 5.5.3)

1. 当是x-www-form-urlencoded时,

$_POST
Array
(
    [id] => 1+1
    [val] => 44753
)

php://input
id=1%2B1&val=44753
content_type: application/x-www-form-urlencoded

php://input中的形式和body体中是一样的,同样是urlencode过的。

 

2. 当是 multipart/form-data时,

$_POST
Array
(
    [id] => 1+111
    [val] => 44753
)

php://input

content_type: multipart/form-data; boundary=----WebKitFormBoundaryUUacTtaG65hX7g6y

发现$_POST依然可以获取到参数。此时php://input 获取不到值。

(测试在hhvm HipHop VM 3.0.1;baidu version:1.0.6.4 php://input可以获取到multipart/form-data 提交参数)如下:

$_POST
Array
(
    [id] => 1+111
    [val] => 44753
)

php://input
------WebKitFormBoundaryxHArWQUlukzFfZAb
Content-Disposition: form-data; name="id"

1+111
------WebKitFormBoundaryxHArWQUlukzFfZAb
Content-Disposition: form-data; name="val"

44753
------WebKitFormBoundaryxHArWQUlukzFfZAb--

content_type: multipart/form-data; boundary=----WebKitFormBoundaryxHArWQUlukzFfZAb

 

3. 当是application/json时,

$_POST
Array
(
)

php://input
{"a":"xx"}
content_type: application/json

此时,$_POST获取不到提交参数。php://input 可以获取到。这种json提交数据,php接收参数需要使用 file_get_contents('php://input', 'r')。

 

总结:

$_POST只能获取到form提交的数据,而php://input获取不到  multipart/form-data提交的数据。

 

这里顺便提下,如何提交给php获取$_POST的key=>value是数组形式。

$arrParams = array(
            'person[0][first_name]' => 1,
            'person[0][last_name]' => 1,
            'person[1][first_name]' => 111,
            'person[1][last_name]' => 222,
        );

这样$_POST['person'] 就是个二维数组了。

$_POST
Array
(
    [person] => Array
        (
            [0] => Array
                (
                    [first_name] => a
                    [last_name] => b
                )

            [1] => Array
                (
                    [last_name] => d
                )

        )

)

php://input
person%5B0%5D%5Bfirst_name%5D=a&person%5B0%5D%5Blast_name%5D=b&person%5B1%5D%5Blast_name%5D=c&person%5B1%5D%5Blast_name%5D=d
content_type: application/x-www-form-urlencoded

 

  

 

posted @ 2017-07-11 10:01  根号五  阅读(4270)  评论(0编辑  收藏  举报