PHP如何确定浏览器POST请求数据中的字符编码?

the*_*fog 5 php encoding

当浏览器在 POST 请求正文中发送数据(即name=value来自表单元素的对)时,PHP 如何确定字符编码,以便它可以正确地将位流解码为字符以供其内部使用?
我可以理解,对于某些 PHP 不需要解码的任务,例如对于 SQL INSERT 查询,它可能只是将数据/字符串传递到 DBMS,而不进行额外的处理。
但对于文本处理/正则表达式操作,我想 PHP 需要将位流解码为字符,然后才能对它们执行测试、模式匹配等。
另外,似乎因为编码是由浏览器决定的,所以 PHP 需要浏览器的指导来确定它使用什么字符集来编码 POST 数据。
预计该指导将出现在请求标头中,我设置了一个文本表单

<meta charset="utf-8">
Run Code Online (Sandbox Code Playgroud)

在包含表单的网页的头部,输入一些值并提交表单后,请求标头不包含有关如何编码 POST 数据的明显信息

POST /experiments/foo.php HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 57
Pragma: no-cache
Cache-Control: no-cache
Origin: http://localhost
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://localhost/experiments/how_does_php_encode_data_it_receives_from_browser.php
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Run Code Online (Sandbox Code Playgroud)

还是还有其他事情发生?例如,浏览器是否需要按照某种预先确定的标准对字符进行编码?
PHP 如何知道如何解码从浏览器 POST 请求接收到的数据?

the*_*fog 2

关于 GET 数据,W3C 标准规定

笔记。“get”方法将表单数据集值限制为 ASCII 字符。
仅指定“post”方法(带有 enctype="multipart/form-data")来覆盖整个 [ISO10646] 字符集。

因此,使用 GET 时,浏览器似乎被锁定为 ASCII,如果表单元素具有该属性enctype="multipart/form-data",则似乎标准支持更大的 charset [ISO10646]
我猜因为它更接近纯比特流,所以默认Content-type支持application/x-www-form-url-encoded所有字符编码。特别是这篇文章指出:
http ://www.herongyang.com/PHP/Non-ASCII-Form-Basic-Rules.html

URL编码将所有非ASCII字节转换为“%xx”的形式,“xx”是字节的HEX值。

因此,这似乎解释了浏览器可能发送的字符集,但没有解释它如何指示 PHP 发送的实际字符集。(GET 除外,PHP 知道它只能是 ASCII)。O 从我的理解来看,浏览器基本上没有关于其发送的表单数据的字符编码的直接指导。
但我可能是错的,并且会对这个理论的任何反馈/替代方案感兴趣。
否则,据我所知,该方案的完整性本质上依赖于服务器简单地“记住”什么

<meta charset="utf-8">
Run Code Online (Sandbox Code Playgroud)

或者

<form ... accept-charset="utf-8">
Run Code Online (Sandbox Code Playgroud)

它发送给用户的值(并希望用户没有通过浏览器“设置”更改字符编码)并期望浏览器将忠实地以该字符集发送后续请求。
换句话说,如果您的团队中有一位网页设计师负责 HTML,并且他们设置了 HTML 元标记,<meta charset="utf-8">他们需要通知数据库管理员,嘿,您需要设置数据库架构、表等以期望 UTF- 8 编码
这是因为服务器端开发人员/DBA 将无法动态检查编码(例如,如果表单提交来自不同国家/地区的用户,其浏览器可能设置为某些不同的字符集)。
并可能拒绝或记录警告等...
基本上,开发人员似乎需要为每个包含表单的 HTML 页面显式设置字符集,例如<meta charset="utf-8">,然后只需相信浏览器将以与 HTML 包含的相同字符集发送 POST 数据表单被编码在.

进一步阅读