我被指示使用该方法php://input而不是$_POST与来自JQuery的Ajax请求交互时.我不明白的是使用这个VS的全局法的优点$_POST或$_GET.
Qua*_*unk 437
原因是php://input返回请求的HTTP标头之后的所有原始数据,而不管内容类型如何.
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
Run Code Online (Sandbox Code Playgroud)
但是如果你正在使用Ajax,那么这个probaby还包括用类型(string,int,bool)和结构(数组,对象)交换更复杂的数据,所以在大多数情况下JSON是最好的选择.但是带有JSON-payload的请求看起来像这样:
POST /page.php HTTP/1.1
{"key1":"value1","key2":"value2","key3":"value3"}
Run Code Online (Sandbox Code Playgroud)
现在内容将是application/json(或者至少没有上述内容),因此PHP的$_POST-wrapper不知道如何处理(尚未).
数据仍然存在,您无法通过包装器访问它.所以你需要自己以原始格式获取它file_get_contents('php://input')(只要它不是multipart/form-data-encoded).
这也是您访问XML数据或任何其他非标准内容类型的方式.
Ant*_*dge 55
PHP 的设计目的不是明确地为您提供一个纯 REST(GET、POST、PUT、PATCH、DELETE)之类的接口来处理 HTTP 请求。
然而,$_SERVER,$_COOKIE,$_POST,$_GET,和$_FILES 超全局变量和函数filter_input_array()是一般人的/外行的需求是非常有用的。
$_POST(and $_GET)的第一个隐藏优势是您的输入数据由 PHP 自动进行 url 解码。您甚至从未想过必须这样做,尤其是对于标准GET请求中的查询字符串参数或随POST请求提交的 HTTP 正文数据。
那些研究底层 HTTP 协议及其各种请求方法的人会了解到,有许多 HTTP 请求方法,包括经常被引用的PUT、PATCH(在 Google 的 Apigee 中未使用)和DELETE。
在 PHP 中,POST没有用于在不使用时获取 HTTP 请求正文数据的超全局变量或输入过滤器函数。罗伊菲尔丁的弟子要做什么?;-)
话虽如此,随着您在 PHP 编程知识方面的进步并想要使用 JavaScript 的XmlHttpRequest对象(对于某些人为 jQuery),您会看到这种方案的局限性。
$_POST限制您在 HTTPContent-Type标头中使用两种媒体类型:
application/x-www-form-urlencoded, 和multipart/form-data因此,如果您想将数据值发送到服务器上的 PHP,并将其显示在$_POSTsuperglobal 中,那么您必须在客户端对其进行urlencode并将所述数据作为键/值对发送——这对新手来说是一个不方便的步骤(尤其是在尝试确定 URL 的不同部分是否需要不同形式的 urlencoding:正常、原始等时......)。
对于所有 jQuery 用户,该$.ajax()方法是将您的 JSON 转换为 URL 编码的键/值对,然后再将它们传输到服务器。您可以通过设置覆盖此行为processData: false。只需阅读$.ajax() 文档,不要忘记在 Content-Type 标头中发送正确的媒体类型。
即使您使用php://input代替$_POSTHTTPPOST请求正文数据,它也不会与 HTTP 一起使用Content-Type。multipart/form-data这是您在 HTML 表单上使用的内容类型,当您希望允许文件上传时!
<form enctype="multipart/form-data" accept-charset="utf-8" action="post">
<input type="file" name="resume">
</form>
Run Code Online (Sandbox Code Playgroud)
因此,在传统的PHP,要处理的内容类型从HTTP多样性POST的要求,您将学习如何使用$_POST或filter_input_array(POST),$_FILES和php://input。无法POST在 PHP 中为 HTTP请求只使用一个通用输入源。
您无法通过$_POST、filter_input_array(POST) 或获取文件php://input,并且无法在filter_input_array(POST)或 中获取 JSON/XML/YAML $_POST。
php://input 是一个只读流,允许您从请求正文中读取原始数据...php://input不适用于enctype="multipart/form-data"。
像 Codeigniter 4 和 Laravel 这样的 PHP 框架使用 Facade 来为上述内容提供更清晰的界面(IncomingRequest或Request对象)。这就是专业 PHP 开发人员使用框架而不是原始 PHP 的原因。
当然,如果你喜欢编程,你可以设计自己的外观对象来提供框架的功能。正是因为我花了时间调查这个问题,我才能够写出这个答案。
通常,如果您使用 HTML 表单执行正常的同步(当整个页面重绘时)HTTP 请求,则用户代理(Web 浏览器)将为您对表单数据进行 urlencode。如果您想使用该XmlHttpRequest对象执行异步 HTTP 请求,那么您必须构造一个 urlencoded 字符串并发送它,如果您希望该数据显示在$_POSTsuperglobal 中。
从 JavaScript 数组或对象转换为 urlencoded 字符串困扰着许多开发人员(即使使用新的 API,如Form Data)。他们更希望能够发送 JSON,并且客户端代码这样做会更有效率。
请记住(眨眼,眨眼),一般的 Web 开发人员不会XmlHttpRequest像您和我一样学习直接使用对象、全局函数、字符串函数、数组函数和正则表达式 ;-)。Urlencoding 对他们来说是一场噩梦。;-)
PHP 缺乏直观的 XML 和 JSON 处理让很多人望而却步。你会认为它现在是 PHP 的一部分(叹气)。
XML、JSON 和 YAML 都有可以放入 HTTPContent-Type标头的媒体类型。
看看IANA 定义了多少媒体类型(以前称为 MIME 类型)。
看看有多少HTTP 标头。
使用php://input流允许您绕过 PHP 强加给世界的婴儿看护/手持抽象级别。:-) 拥有权利的同时也被赋予了重大的责任!
现在,在处理通过 流式传输的数据值之前php://input,您应该/必须做一些事情。
啊,哈!是的,您可能希望发送到您的应用程序的数据流是 UTF-8 编码的,但是您怎么知道它是否是这样?
php://input。您是否打算在不知道流数据的情况下尝试处理流数据?这是一个可怕的想法。您不能完全依赖 HTTPContent-Length标头来指导流输入的大小,因为它可能被欺骗。
你将需要一个:
您是否打算在不知道流的当前编码的情况下尝试将流数据转换为 UTF-8?如何?iconv 流过滤器(iconv 流过滤器示例)似乎想要一个开始和结束的编码,就像这样。
'convert.iconv.ISO-8859-1/UTF-8'
Run Code Online (Sandbox Code Playgroud)
因此,如果您有良心,您将需要:
(更新:'convert.iconv.UTF-8/UTF-8'将强制所有内容为 UTF-8,但您仍然必须考虑 iconv 库可能不知道如何翻译的字符。换句话说,您必须如何定义当一个字符无法翻译时要采取的操作: 1) 插入一个虚拟字符,2) 失败/抛出和异常)。
您不能完全依赖 HTTPContent-Encoding标头,因为这可能表示如下所示的压缩。这不是您想要就 iconv 做出决定的原因。
Content-Encoding: gzip
Run Code Online (Sandbox Code Playgroud)
第一部分:HTTP 请求相关
第二部分:流数据相关
第三部分:数据类型相关
(请记住,数据仍然可以是 URL 编码的字符串,然后您必须对其进行解析和 URL 解码)。
第四部分:数据价值相关
过滤输入数据。
验证输入数据。
该$_POST超全局,与输入范围的php.ini设置一起,是外行简单。然而,在使用流时处理字符编码更加直观和有效,因为不需要循环遍历超全局变量(或数组,通常)来检查输入值是否正确编码。
Rob*_*gar 50
php://input可以为您提供数据的原始字节.如果POSTed数据是JSON编码结构(通常是AJAX POST请求的情况),这将非常有用.
这是一个功能:
/**
* Returns the JSON encoded POST data, if any, as an object.
*
* @return Object|null
*/
private function retrieveJsonPostData()
{
// get the raw POST data
$rawData = file_get_contents("php://input");
// this returns null if not valid json
return json_decode($rawData);
}
Run Code Online (Sandbox Code Playgroud)
$_POST当您从传统POST提交的表单处理键值数据时,该数组更有用.这仅适用于POSTed数据采用可识别格式的情况(通常application/x-www-form-urlencoded请参阅http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4).
Nam*_*ess 24
如果发布数据格式错误,$ _POST将不包含任何内容.然而,php://输入将具有格式错误的字符串.
例如,有一些ajax应用程序,它们不能形成用于上传文件的正确的后键值序列,只是将所有文件作为发布数据转储,没有变量名称或任何东西.$ _POST将为空,$ _FILES也为空,而php://输入将包含精确文件,写为字符串.
| 归档时间: |
|
| 查看次数: |
193481 次 |
| 最近记录: |