PHP 接收 POST数据方法汇总

前言

众所周知PHP是世界上最好的语言(笑),作为一种脚本语言,除了内嵌HTML 编码的独特方式,它对HTTP请求的处理能力(发送和接收)也是很强的,下面就是关于接收POST请求的一些方法汇总。

Content-Type类型

常见的POST请求差异一般就在于Content-Type的类型,Content-Type类型也就基本定义了这个请求是做什么的,在实际的业务开发中常见的Content-Type类型如下:

1. application/x-www-form-urlencoded

application/x-www-form-urlencoded 是大部分POST请求工具默认的设置,包括浏览器,requests,POSTman诸如此类。
这种编码格式会使用&分割数据,使用=连接数据,对于这种类型的数据可以以下方式来获得

$_POST 和 file_get_contents('php://input')

PHP:

<?php
echo(file_get_contents('php://input') . "\r\n");
var_dump($_POST);
?>

requests

import requests
x = requests.post('http://127.0.0.1/web.php',data={
    'hello': 'world',
    '汉字': '汉字测试',
    'list': 'one',
})
print(x.text)

接收到的数据:

hello=world&%E6%B1%89%E5%AD%97=%E6%B1%89%E5%AD%97%E6%B5%8B%E8%AF%95&list=one
------------------------
array(3) {
  ["hello"]=>
  string(5) "world"
  ["汉字"]=>
  string(12) "汉字测试"
  ["list"]=>
  string(3) "one"
}

这里收到的数据中%E6%B1%89%E5%AD%97=%E6%B1%89%E5%AD%97%E6%B5%8B%E8%AF%95是PHP对汉字数据进行了UrlDecode解码/UrlEncode编码操作。解码结果为:汉字=汉字测试

2. multipart/form-data

multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。当上传的字段是文件时,会有Content-Type来表名文件类型;content-disposition,用来说明字段的一些信息;
由于有boundary隔离,所以multipart/form-data既可以上传文件,也可以上传键值对,它采用了键值对的方式,所以可以上传多个文件。
如果没有上传文件,PHP后端会提示:

<br /><b>Warning</b>:  Missing boundary in multipart/form-data POST data in <b>Unknown</b> on line <b>0</b><br />

同样的PHP代码:

<?php
echo(file_get_contents('php://input') . "\r\n");
echo "------------------------". "\r\n";
var_dump($_POST);
?>

请求的客户端代码:

import requests
x = requests.post('http://127.0.0.1/web.php',data={
    'hello': 'world',
    '汉字': '汉字测试',
    'list': 'one',
},headers={'Content-Type': 'multipart/form-data'},files={'file': open("ddos.txt", 'rb')})
print(x.text)

请求结果:

<br />
<b>Warning</b>:  Missing boundary in multipart/form-data POST data in <b>Unknown</b> 
on line <b>0</b><br />
--240a892658c675fe7898f67be0dac002
Content-Disposition: form-data; name="hello"

world
--240a892658c675fe7898f67be0dac002
Content-Disposition: form-data; name="汉字"

汉字测试
--240a892658c675fe7898f67be0dac002
Content-Disposition: form-data; name="list"

one
--240a892658c675fe7898f67be0dac002
Content-Disposition: form-data; name="file"; filename="ddos.txt"

测试文本
--240a892658c675fe7898f67be0dac002--

------------------------
array(0) {
}

这里Content-Type 设定为multipart/form-data,同时上传file文件,使用file_get_contents('php://input')
同样可以接收,但是$POST 变量无法进行接收,同时因为Content-Type改变了,分隔符号不再是&,而是boundary,在上述的结果中可以看到服务器使用--240a892658c675fe7898f67be0dac002--进行分割。

总结

1.接收数据的变量和语句有:

2.对于application/x-www-form-urlencoded数据可以使用file_get_contents('php://input') 或者是$_POST来接收,两者各有好处,一个是原始的数据一个是已经编码好的数组数据,可以按照需求选择。需要注意,如果是使用file_get_contents('php://input')接收汉字数据,PHP会进行UrlDecode解码/UrlEncode编码操作。

3.接收multipart/form-data数据的时候需要使用file_get_contents('php://input')来接收,同时接收的数据无需进行UrlDecode解码/UrlEncode编码操作

按照需要使用file_get_contents('php://input'),可以满足90%的需求,后面如果发现新的方法会进行补充

最后更新 2022-08-15