当浏览器在 POST 请求正文中发送数据时(即name=value
来自表单元素的对),PHP 如何确定字符编码,以便它可以正确地将位流解码为字符以供其内部使用?
我可以理解 PHP 不需要解码的某些任务,例如对于 SQL INSERT 查询,它可能只是将数据/字符串传递到 DBMS,而不进行额外的处理。
但对于文本处理/正则表达式操作,我想 PHP 需要将位流解码为字符,然后才能对它们执行测试、模式匹配等。
另外,似乎因为编码是由浏览器决定的,所以 PHP 需要浏览器的指导来确定它使用什么字符集来编码 POST 数据。
预计该指导将出现在请求标头中,我设置了一个文本表单
<meta charset="utf-8">
在包含表单的网页的头部,输入一些值并提交表单后,请求标头不包含有关如何编码 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
还是还有其他事情发生?例如浏览器是否需要按照某种预先确定的标准对字符进行编码?
PHP 如何知道如何解码从浏览器 POST 请求接收到的数据?
对于 GET 数据,W3C 标准规定 https://www.w3.org/TR/html401/interact/forms.html#h-17.13
笔记。 “get”方法将表单数据集值限制为 ASCII 字符。
仅指定“post”方法(带有 enctype="multipart/form-data")来覆盖整个 [ISO10646] 字符集。
因此,如果表单元素具有该属性,则使用 GET 浏览器似乎会被锁定为 ASCIIenctype="multipart/form-data"
看来该标准支持更大的字符集[ISO10646]
.
我猜因为它更接近纯比特流,所以默认Content-type
of application/x-www-form-url-encoded
支持所有字符编码。这篇文章特别指出:
http://www.herongyang.com/PHP/Non-ASCII-Form-Basic-Rules.html http://www.herongyang.com/PHP/Non-ASCII-Form-Basic-Rules.html
URL编码将所有非ASCII字节转换为“%xx”的形式,“xx”是字节的HEX值。
因此,这似乎解释了浏览器可能发送的字符集,但没有解释它如何指示 PHP 发送的实际字符集。 (GET 除外,PHP 知道它只能是 ASCII)。氧
另一方面,据我所知,浏览器基本上没有关于其发送的表单数据的字符编码的直接指导。
但我可能是错的,并且会对这个理论的任何反馈/替代方案感兴趣。
否则,据我所知,该方案的完整性本质上依赖于服务器简单地“记住”什么
<meta charset="utf-8">
or
<form ... accept-charset="utf-8">
它发送给用户的值(并希望用户没有通过浏览器“设置”更改字符编码)并期望浏览器将忠实地以该字符集发送后续请求。
换句话说,如果您的团队中有一位网页设计师负责 HTML 并且他们设置了 HTML 元标记<meta charset="utf-8">
他们需要通知数据库管理员,嘿,您需要设置数据库架构、表等以期望 UTF-8 编码.
这是因为服务器端开发人员/DBA 将无法动态检查编码(例如,如果表单提交来自不同国家/地区的用户,其浏览器可能设置为某些不同的字符集)。
并可能拒绝或记录警告等...
基本上,开发人员似乎需要为每个包含表单的 HTML 页面显式设置字符集,例如和<meta charset="utf-8">
然后只需相信浏览器将使用与包含表单的 HTML 编码相同的字符集发送 POST 数据。
进一步阅读
- https://www.w3.org/TR/html401/interact/forms.html https://www.w3.org/TR/html401/interact/forms.html
- 全程UTF-8 https://stackoverflow.com/questions/279170/utf-8-all-the-way-through
- http://www.herongyang.com/PHP/Non-ASCII-Form-Basic-Rules.html http://www.herongyang.com/PHP/Non-ASCII-Form-Basic-Rules.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)