PHP “php://input” vs $_POST
我被指示使用该方法,而不是在与来自JQuery的Ajax请求交互时。我不明白的是,与 or 的全局方法相比,使用此方法的好处是什么。php://input
$_POST
$_POST
$_GET
我被指示使用该方法,而不是在与来自JQuery的Ajax请求交互时。我不明白的是,与 or 的全局方法相比,使用此方法的好处是什么。php://input
$_POST
$_POST
$_GET
原因是,无论内容类型如何,都会在请求的 HTTP 标头之后返回所有原始数据。php://input
PHP 超全局 ,只应该包装以下数据$_POST
application/x-www-form-urlencoded
(简单表单帖子的标准内容类型)或multipart/form-data
(主要用于文件上传)这是因为这些是用户代理必须支持的唯一内容类型。因此,服务器和PHP传统上不希望接收任何其他内容类型(这并不意味着它们不能)。
因此,如果您只是发布一个很好的旧HTML,则请求如下所示:form
POST /page.php HTTP/1.1
key1=value1&key2=value2&key3=value3
但是,如果您经常使用Ajax,这可能还包括使用类型(字符串,int,bool)和结构(数组,对象)交换更复杂的数据,因此在大多数情况下,JSON是最佳选择。但是,具有 JSON 有效负载的请求将如下所示:
POST /page.php HTTP/1.1
{"key1":"value1","key2":"value2","key3":"value3"}
内容现在是(或者至少没有上面提到的内容),所以PHP的-wrapper不知道如何处理它(还没有)。application/json
$_POST
数据仍然存在,您只是无法通过包装器访问它。因此,您需要自己以原始格式获取它(只要它不是多部分/表单数据
编码的)。file_get_contents('php://input')
这也是访问 XML 数据或任何其他非标准内容类型的方式。
PHP并不是为了明确地给你一个纯粹的REST(GET,POST,PUT,PATCH,DELETE)这样的接口来处理HTTP请求。
但是,、 、 、 和超全局函数以及函数 filter_input_array()
对于普通人/外行人的需求非常有用。$_SERVER
$_COOKIE
$_POST
$_GET
$_FILES
(和)的头号隐藏优势是您的输入数据由PHP自动进行URL解码。您甚至从未考虑过必须这样做,特别是对于标准请求中的查询字符串参数或随请求提交的HTTP正文数据。$_POST
$_GET
GET
POST
那些研究底层HTTP协议及其各种请求方法的人开始明白,有许多HTTP请求方法,包括经常引用的,(在Google的Apigee中未使用)和。PUT
PATCH
DELETE
在 PHP 中,没有超全局或输入筛选器函数,用于在不使用时获取 HTTP 请求正文数据。罗伊·菲尔丁的弟子们要做什么?;-)POST
话虽如此,随着PHP编程知识的进步,并希望使用JavaScript的对象(对某些人来说是jQuery),你会看到这个方案的局限性。XmlHttpRequest
$_POST
限制您在 HTTP 标头中使用两种媒体类型:Content-Type
application/x-www-form-urlencoded
和multipart/form-data
因此,如果你想将数据值发送到服务器上的PHP,并让它显示在$_POST
超全局中,那么你必须在客户端对它进行urlencode,并将所述数据作为键/值对发送 - 对于新手来说是一个不方便的步骤(特别是当试图弄清楚URL的不同部分是否需要不同形式的urlencoding时: 正常,原始等)。
对于所有jQuery用户,$.ajax()
方法是在将JSON传输到服务器之前将其转换为URL编码的键/值对。您可以通过设置 processData:false
来覆盖此行为。只需阅读 $.ajax() 文档,不要忘记在 Content-Type 标头中发送正确的媒体类型。
即使您使用而不是HTTP请求正文数据,它也不会与HTTP一起使用 这是您想要允许文件上传时在HTML表单上使用的内容类型!php://input
$_POST
POST
Content-Type
multipart/form-data
<form enctype="multipart/form-data" accept-charset="utf-8" action="post">
<input type="file" name="resume">
</form>
因此,在传统的PHP中,要处理来自HTTP请求的多种内容类型,您将学习使用或,,和。在 PHP 中,没有办法只对 HTTP 请求使用一个通用输入源。POST
$_POST
filter_input_array(POST)
$_FILES
php://input
POST
您无法通过 、 或 获取文件,也无法在 或 中获取 JSON/XML/YAML。$_POST
filter_input_array(POST)
php://input
filter_input_array(POST)
$_POST
php://input 是一个只读流,允许您从请求正文中读取原始数据...php://input 不适用于 enctype=“multipart/form-data”。
像Codeigniter 4和Laravel这样的PHP框架使用外观来为上述内容提供更清晰的接口(或对象)。这就是为什么专业的PHP开发人员使用框架而不是原始PHP的原因。IncomingRequest
Request
当然,如果你喜欢编程,你可以设计自己的门面对象来提供框架的作用。正是因为我花时间调查了这个问题,我才能够写出这个答案。
通常,如果您使用 HTML 表单执行正常的同步(当整个页面重绘时)HTTP 请求,则用户代理(Web 浏览器)将为您对表单数据进行 url 编码。如果要使用该对象执行异步 HTTP 请求,则必须设置 urlencoded 字符串并发送它,如果希望该数据显示在 $_POST
超全局中。XmlHttpRequest
从 JavaScript 数组或对象转换为 urlencoded 字符串会困扰许多开发人员(即使使用新的 API,如 Form Data)。他们宁愿只能够发送JSON,并且客户端代码这样做会更有效率。
请记住(眨眼,眨眼),普通的Web开发人员不会像你和我一样学习直接使用对象,全局函数,字符串函数,数组函数和正则表达式;-)。对他们来说,Urlencoding是一场噩梦。;-)XmlHttpRequest
PHP缺乏直观的XML和JSON处理,这让很多人望而却步。你可能会认为它现在已经是PHP的一部分(叹息)。
XML,JSON和YAML都有可以放入HTTP标头中的媒体类型。Content-Type
查看 IANA 定义了多少媒体类型(以前称为 MIME 类型)。
看看有多少个HTTP标头。
使用 php://input
流可以规避 PHP 强加给世界的婴儿看护/手持抽象级别。:-)权力越大,责任越大!
现在,在处理流经的数据值之前,您应该/必须做一些事情。php://input
啊,哈!是的,您可能希望发送到应用程序中的数据流采用 UTF-8 编码,但您如何知道它是否是 UTF-8 编码?
php://input
您是否打算在不知道首先有多少数据的情况下尝试处理流数据?这是一个可怕的想法。您不能完全依赖 HTTP 标头来获取有关流输入大小的指导,因为它可能是欺骗性的。Content-Length
您将需要一个:
您是否打算在不知道流的当前编码的情况下尝试将流数据转换为 UTF-8?如何?iconv 流过滤器(iconv 流过滤器示例)似乎需要一个开始和结束编码,就像这样。
'convert.iconv.ISO-8859-1/UTF-8'
因此,如果您尽职尽责,您将需要:
(更新:将强制所有内容都设置为UTF-8,但您仍然必须考虑iconv库可能不知道如何翻译的字符。换句话说,您必须如何定义当字符无法翻译时要执行的操作:1)插入虚拟字符,2)失败/抛出和异常)。'convert.iconv.UTF-8/UTF-8'
您不能完全依赖 HTTP 标头,因为这可能表示类似压缩的内容,如下所示。这不是你想在iconv上做出决定的。Content-Encoding
Content-Encoding: gzip
第一部分:HTTP请求相关
第二部分:流数据相关
第 III 部分:数据类型相关
(请记住,数据仍然可以是URL编码的字符串,然后您必须对其进行解析和URL解码)。
第 IV 部分:数据值相关
筛选输入数据。
验证输入数据。
超全局,以及php.ini输入限制设置,对于外行人来说更简单。但是,在使用流时,处理字符编码更加直观和高效,因为不需要遍历超全局(或数组,通常)来检查输入值的正确编码。$_POST