为什么在PHP中使用多字节字符串函数?

为什么在PHP中使用多字节字符串函数?,php,utf-8,multibyte,Php,Utf 8,Multibyte,目前,我不明白为什么在处理UTF-8时在PHP中使用mbstring函数真的很重要?我在linux下的语言环境已经设置为UTF-8,那么为什么像strlen、preg\u replace等函数在默认情况下不能正常工作呢?所有的PHP都不会处理多字节字符串,不管操作系统的语言环境如何。这就是为什么需要使用多字节字符串函数的原因 从: 操作(修剪、拆分、拼接等)以 多字节编码,需要使用特殊函数,因为两个或多个 在这种情况下,更多的连续字节可以表示单个字符 编码方案。否则,如果应用非多字节感知字符串

目前,我不明白为什么在处理UTF-8时在PHP中使用mbstring函数真的很重要?我在linux下的语言环境已经设置为UTF-8,那么为什么像strlen、preg\u replace等函数在默认情况下不能正常工作呢?

所有的PHP都不会处理多字节字符串,不管操作系统的语言环境如何。这就是为什么需要使用多字节字符串函数的原因

从:

操作(修剪、拆分、拼接等)以 多字节编码,需要使用特殊函数,因为两个或多个 在这种情况下,更多的连续字节可以表示单个字符 编码方案。否则,如果应用非多字节感知字符串 函数,它可能无法检测到字符串的开头或结尾 多字节字符的结尾,并以损坏的垃圾结尾 最有可能失去其原始含义的字符串


这是我用简单的英语回答的。 一个日文、中文和韩文字符占用的空间超过一个字节。例如,一个典型的字符t说,
x
在英语中需要1个字节,而在日语、汉语和朝鲜语中则需要超过
1
字节。现在PHP的标准字符串函数将单个字符视为1字节。所以,如果你试图比较两个日文、中文或韩文字符,它们将不会像预期的那样工作。例如,日语、汉语或韩语的“Hello World!”的长度将超过12个字节


阅读

这里的人不理解UTF-8

您不需要使用UTF-8感知代码来处理UTF-8。大部分情况下

我甚至编写了一个Unicode大小写程序,以及NFC和NFD转换,只使用字节感知函数。很难想象还有比这更复杂的事情,需要对UTF-8进行如此细致的处理。但它仍然可以使用纯字节函数

很少需要UTF-8感知代码。可以计算字符数,或者将插入点向前移动1个字符。但实际上,即使这样,您的代码也无法工作;)因为分解的字符

但如果您所做的只是替换、查找内容,甚至解析语法,那么您只需要字节感知函数

我会解释原因的

这是因为在任何其他UTF-8字符中都找不到UTF-8字符。它就是这样设计的

试着向我解释一下,在一个多字节系统中,在另一个字符中找不到任何字符时,如何会出现文本处理错误?只是一个例子!你能想到的最简单的方法。

多字节=>multi+字节

1) 它用于处理其他语言(非英语)格式的字符串

2) 默认PHP字符串函数仅适用于英语(或与其相关的语言)。

3) 如果要对特殊字符使用strlen()或strpos()或大写()或strreplace(),
假设我们需要在“Hello”上应用字符串函数。
中文(你好), 阿拉伯语、日语(こんにちは), 印地语( नमस्ते), 古吉拉特邦(હેલો).
不同的语言可以创建自己的字符集


因此,mbstring被引入用于与各种语言(如中文、日语等)进行通信。

PHP字符串只是简单的字节序列。它们本身没有任何意义。它们也不使用任何特定的字符编码

因此,如果您使用读取文件,您将获得文件的二进制安全表示形式。可能是图像的(二进制)表示形式,也可能是人类可读的文本文件-PHP不在乎

现在,只要您只需要对字符串进行基本处理,就根本不需要知道字符编码。因此,如果您想使用将字符串存储回文件中,或者希望使用获取其长度(而不是字符数),则可以

但是,一旦您开始进行更奇特的字符串操作,就需要知道字符编码。无法将其存储为字符串的一部分,因此您必须单独跟踪它,或者,大多数人所做的,使用具有全部(文本)的约定常用字符编码的字符串,如US-ASCII或现在的UTF-8

因此,由于无法为字符串设置字符编码,PHP不知道字符串使用的是哪个字符编码。因此,
strlen()
唯一明智的做法是返回字节数,因为这是PHP唯一确定的事

如果提供所用字符编码的附加信息,则需要使用另一个函数-在本例中调用该函数

这同样适用于:如果要替换umlaut-a,或匹配一行中的三个相同字符,则需要了解umlaut-a的编码方式,以及通常情况下字符的编码方式

因此,如果你有一个假设的字符编码,它将小写的
a
编码为
a1
,大写的
a
编码为
a2
,a
b
编码为
b1
b
编码为
b2
(等等),你可以有一个(编码的)字符串
a1a1a1
,由一行中的三个相同字符组成。但是,如果不知道编码,只查看字节序列,就无法检测到这一点

总结:

由于PHP字符串不包含字符编码,因此不可能使用“默认值”。即使使用单个函数,如
strlen()
不能返回
内容长度所需的字节序列长度
HTTP头和同时返回用于表示博客文章长度的字符数

这就是为什么它天生就是坏的,即使它一开始看起来不错,
public function test_substr(): void
{
    $name = 'Raul González';
    $user = factory(User::class)->create(['name' => $name]);
    try {
        $name1      = substr($name, 0, 10);
        $user->name = $name1;
        $user->save();
    } catch (Exception $ex) {

    }
    $this->assertTrue(isset($ex));

    $name2      = mb_substr($name, 0, 10);
    $user->name = $name2;
    $user->save();

    $this->assertTrue(true);
}