mb_internal_encoding() 到底是什么意思?
What does mb_internal_encoding() actually mean?
According to the PHP website 它是这样做的:
encoding
is the character encoding name used for the HTTP input
character encoding conversion, HTTP output character encoding
conversion, and the default character encoding for string functions
defined by the mbstring module. You should notice that the internal
encoding is totally different from the one for multibyte regex.
但我觉得这样的解释对我来说还不够理解。
有一次我在 PHP 中用 CURL 请求了一些 API。我正在解析响应数据。响应 header 包含 Content-Length
。所以我相信 Content-Length
显示了完全正确的值。此外,mb_strlen($responseData)
的结果值与 Content-Length
值相同。
如果我把内部编码值设置成mb_internal_encoding('UTF-8')
,顺便说一下,mb_strlen($responseData)
的结果值和以前不一样了!。
实际上,该值比以前小。
我的网络服务器编码、文件编码和接受编码都设置为UTF-8。
为什么会出现这个问题?
Content-Length 是以 字节 为单位的响应大小。在 ASCII 中,Content-Length == character-count。在UTF-8中,单个字符可以由多个字节组成,因此character-count将等于或小于Content-Length。
例如:
A
in ASCII = 0x41
(一个字节)
€
in UTF-8 = 0x20A0
(两个字节)
mb_strlen
returns 给定编码类型的字符数(不是字节数)。
strlen("€")
>> 2
mb_strlen("€", 'UTF-8')
>> 1
strlen("A")
>> 1
mb_strlen("A", 'UTF-8')
>> 1
PHP 将字符串视为 字节数组 ,就像愚蠢的 collection 字节一样。它不知道编码或 "characters"。 mb_* 函数是一组编码感知工具,可以在 character-by-character 基础上处理字符串。例如,UTF-8 中的字符串“汉字”有 6 个字节长,但只表示两个字符。为了能够逐个字符地处理字符串,mb_* 函数需要知道给定字符串的编码。每个 mb_* 接受一个 $encoding
参数,因此您可以告诉它。例如:
mb_strlen('漢字', 'UTF-8') // 2
要一劳永逸地全局设置此编码,而不必将其传递给每个函数,有 mb_internal_encoding
。它只是记住编码设置,每个想要的函数都可以从它那里得到这个设置。哪些功能使用它的手册详细信息。
您的特殊 "issue" 是 HTTP Content-Length header 以字节为单位指定内容长度。该值是编码不可知的,事实上它的唯一目的是提醒客户端将跟随的有效负载的大小字节。此有效负载可以是任何内容,因此大小以字节为单位。如果您将其解释为给定编码中的字符,结果将有所不同。
有关更多基础知识,请参阅 What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text。
According to the PHP website 它是这样做的:
encoding
is the character encoding name used for the HTTP input character encoding conversion, HTTP output character encoding conversion, and the default character encoding for string functions defined by the mbstring module. You should notice that the internal encoding is totally different from the one for multibyte regex.
但我觉得这样的解释对我来说还不够理解。
有一次我在 PHP 中用 CURL 请求了一些 API。我正在解析响应数据。响应 header 包含 Content-Length
。所以我相信 Content-Length
显示了完全正确的值。此外,mb_strlen($responseData)
的结果值与 Content-Length
值相同。
如果我把内部编码值设置成mb_internal_encoding('UTF-8')
,顺便说一下,mb_strlen($responseData)
的结果值和以前不一样了!。
实际上,该值比以前小。
我的网络服务器编码、文件编码和接受编码都设置为UTF-8。
为什么会出现这个问题?
Content-Length 是以 字节 为单位的响应大小。在 ASCII 中,Content-Length == character-count。在UTF-8中,单个字符可以由多个字节组成,因此character-count将等于或小于Content-Length。
例如:
A
in ASCII = 0x41
(一个字节)
€
in UTF-8 = 0x20A0
(两个字节)
mb_strlen
returns 给定编码类型的字符数(不是字节数)。
strlen("€")
>> 2
mb_strlen("€", 'UTF-8')
>> 1
strlen("A")
>> 1
mb_strlen("A", 'UTF-8')
>> 1
PHP 将字符串视为 字节数组 ,就像愚蠢的 collection 字节一样。它不知道编码或 "characters"。 mb_* 函数是一组编码感知工具,可以在 character-by-character 基础上处理字符串。例如,UTF-8 中的字符串“汉字”有 6 个字节长,但只表示两个字符。为了能够逐个字符地处理字符串,mb_* 函数需要知道给定字符串的编码。每个 mb_* 接受一个 $encoding
参数,因此您可以告诉它。例如:
mb_strlen('漢字', 'UTF-8') // 2
要一劳永逸地全局设置此编码,而不必将其传递给每个函数,有 mb_internal_encoding
。它只是记住编码设置,每个想要的函数都可以从它那里得到这个设置。哪些功能使用它的手册详细信息。
您的特殊 "issue" 是 HTTP Content-Length header 以字节为单位指定内容长度。该值是编码不可知的,事实上它的唯一目的是提醒客户端将跟随的有效负载的大小字节。此有效负载可以是任何内容,因此大小以字节为单位。如果您将其解释为给定编码中的字符,结果将有所不同。
有关更多基础知识,请参阅 What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text。