str_replace是否可以安全地用于UTF-8编码的字符串,如果它只给出有效的UTF-8编码字符串作为参数?

时间:2010-04-16 10:33:24

标签: php utf-8

PHP的str_replace()仅用于ANSI字符串,因此可以破坏UTF-8字符串。但是,如果只有有效的UTF-8字符串作为参数,那么它是二进制安全的吗?

编辑:我不是在寻找替代函数,我只想知道这个假设是否正确。

5 个答案:

答案 0 :(得分:19)

是。 UTF-8经过精心设计,允许进行此类和其他类似的非Unicode感知处理。

在UTF-8中,表示有效字符的任何非ASCII字节序列始终以\xC0-\xFF范围内的字节开头。此字节可能不会出现在序列中的任何其他位置,因此您无法生成与字符的一部分匹配的有效UTF-8序列。

对于较旧的多字节编码不是这种情况,其中字节序列的不同部分是无法区分的。这导致了很多问题,例如尝试替换Shift-JIS字符串中的ASCII反斜杠(其中字节\x5C可能是表示其他内容的字符序列的第二个字节)。

答案 1 :(得分:5)

这是正确的,因为UTF-8多字节字符是非ASCII(128+字节值)字符,以一个字节开头,该字节定义了后面的字节数,因此您不会意外地最终匹配一个UTF-8的一部分多字节角色与另一个角色。

可视化(抽象地):

  • a表示ASCII字符
  • 2x表示2字节字符
  • 3xx表示3字节字符
  • 4xxx表示4字节字符

如果你匹配,比如a2x3xx(ASCII范围内的a个字节),那么a< x2x不能是3xx4xxx的子集,等等,您可以安全地确保您的UTF-8正确匹配,前提条件是所有字符串绝对是有效的UTF-8。

编辑:有关不太抽象的解释,请参阅bobince的答案。

答案 2 :(得分:1)

好吧,我有一个反例:我有一个UTF8编码的设置“.ini”文件,指定了电子邮件发件人姓名之类的应用设置。它说的是:

email_from = Märta

我从那里读到变量$sender。现在我替换了消息体(再次使用UTF8)

问候 {发件人}

$message = str_replace("{sender}",$sender_name,$message);

电子邮件在各个方面都是绝对正确的,但发件人完全被打破了。当UTF字符串出现问题时,还有其他情况(如explode())。它在转换之前是健康的,但不是之后。很抱歉,似乎没有办法纠正这种行为。

编辑:实际上,explode()涉及解析.ini文件,因此问题很可能在于这个功能,因此str_replace()可能是无辜的。< / p>

答案 3 :(得分:0)

是的,我认为这是正确的,至少我找不到任何反例。

答案 4 :(得分:0)

不,你不能。
从实践中我告诉你,如果你有一些多字节符号,如◊等,其他非多字节,它不能正常工作,因为有符号需要2-4来放置它们, str_replace获取固定的字节,并替换...结果我们有一些东西不是任何符号垃圾等。