代码之家  ›  专栏  ›  技术社区  ›  Manos Dilaverakis

如果只将有效的utf-8编码字符串作为参数,str_replace能否安全地用于utf-8编码字符串?

  •  22
  • Manos Dilaverakis  · 技术社区  · 16 年前

    PHP的 str_replace() 仅用于ANSI字符串,因此可能会损坏UTF-8字符串。但是,考虑到它是二进制安全的,如果只将有效的utf-8字符串作为参数,它是否可以正常工作?

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

    5 回复  |  直到 14 年前
        1
  •  19
  •   bobince    16 年前

    对。UTF-8是专门为允许这种和其他类似的非Unicode感知处理而设计的。

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

    对于旧的多字节编码来说,情况并非如此,因为一个字节序列的不同部分是不可区分的。这导致了很多问题,例如试图替换shift-jis字符串中的ASCII反斜杠(其中byte \x5C 可能是表示其他内容的字符序列的第二个字节)。

        2
  •  5
  •   Community Mohan Dere    9 年前

    这是正确的,因为utf-8多字节字符是专门的非ASCII(128+字节值)字符,以一个字节开始,该字节定义了后面的字节数,所以您不能意外地将一个utf-8多字节字符的一部分与另一个字符匹配。

    使(抽象地)形象化:

    • a 对于ASCII字符
    • 2x 对于2字节字符
    • 3xx 对于3字节字符
    • 4xxx 对于4字节字符

    如果你匹配,说, a2x3xx ( 字节在ASCII范围内),因为 &; x 2X 不能是的子集 3XX 4xxx ,等等,如果所有字符串都是绝对有效的UTF-8,那么您的UTF-8将正确匹配是安全的。

    编辑:参见 bobince 不那么抽象的解释的答案。

        3
  •  1
  •   karvonen    16 年前

    嗯,我 举个反例:我有一个utf8编码的设置“.ini”文件,它指定了电子邮件发送者名称等应用设置。它的意思是:

    email_from = Märta
    

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

    当做 {发送器}

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

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

    编辑 事实上, explode() 参与分析.ini文件,因此问题可能就在于该函数,因此 str_replace() 很可能是无辜的。

        4
  •  0
  •   Kevin    14 年前

    不,你不能。
    从实践中我告诉你,如果你有一些多字节符号,如_㬢等,而其他的是非多字节的,它将无法正常工作,因为有一些符号需要2-4来放置它们, str_replace 接受固定字节,并替换…结果我们得到的东西不是任何符号垃圾等。

        5
  •  0
  •   Kevin    14 年前

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

    推荐文章