代码之家  ›  专栏  ›  技术社区  ›  moo

什么因素使PHP Unicode不兼容?

  •  40
  • moo  · 技术社区  · 17 年前

    我能够在脚本中很好地使用UTF-8字符。

    事实上,有可能 have names of variables and functions contain Unicode characters .

    还有 mb_string extension 它处理多字节字符串,但在无数文章中,PHP因缺乏Unicode支持而受到批评。

    7 回复  |  直到 13 年前
        1
  •  45
  •   Leigh    13 年前

    当PHP在几年前启动时,UTF-8并没有得到真正的支持。我们谈论的是一个非Unicode操作系统(如Windows 98/Me)仍然流行的时代,以及其他大型语言(如Delphi)也是非Unicode的时代。并不是所有的语言从第一天起就考虑到了Unicode,在不破坏很多东西的情况下完全将语言更改为Unicode是很困难的。例如,Delphi在一两年前才与Unicode兼容,而Java或C#等其他语言从第一天起就采用Unicode设计。

    编辑:好的,我把问题看错了。问题是:字符串如何在内部存储?如果我输入“W·hrung”或“criture”,使用哪种编码来创建所使用的字节?对于PHP,它是带有代码页的ASCII码。这意味着:如果我用ISO-8859-15编码字符串,你用一些中文代码页解码,你会得到奇怪的结果。另一种选择是在C#或Java等语言中,所有内容都存储为Unicode,这意味着:不再有代码页,理论上你不能搞砸。我推荐 Joel's article 关于Unicode和字符集,但本质上可以归结为:字符串如何在内部存储,PHP的答案是“不使用Unicode”,这意味着您在处理字符串时必须非常小心和明确,以确保在输入、存储(数据库)和输出期间始终以正确的编码保存字符串,这很容易出错。

        2
  •  37
  •   flow    15 年前

    我认为这主要是一个文化上的困难,而不是技术上的困难。

    至于技术问题——在一个基于“一个字符等于一个字节”假设的生态系统中实现unicode并不是一件小事——开发人员本可以复制java或python的大部分成果(后者自2001年左右以来就具备了相当好的和基本上正常工作的unicode兼容性),但他们从来没有这样做过。

    the discussion thread attached to the official, current documentation for php's utf8_encode() function

    首先,调用该函数 utf8_编码() ; 但是,文件中指出,预期的字符串应为ISO-8859-1(又称拉丁语-1)。这就是sooo php,这就是sooo 80年代。

    大多数评论者似乎认为unicode是一种负担。有许多建议如何转换“未知内容”字符串,如何处理s“混合编码字符串”(wtf?),或处理通常会导致中断的代码点,因为它们超出了该函数的每个代码点四个字节的限制。

    讨论集中在修复上,以消除扭曲或避免该函数行为中有问题的部分。对我来说,这就是sooophp:每个人都在做修复,很少有事情是以基本正确的方式实现的。如果你认为这是对我的诽谤,以下是一些花絮:

    虽然如果文件已经是UTF-8,这似乎打破了德国的统一规则。

    看看iconv()函数,它提供了一种将8859和可怕的1252转换为UTF8的方法

    (好的方面:php开发人员忽略了现有技术;相反,他们自己的实现有缺陷)

    使用preg_匹配检测是否需要utf8_编码[…]不包括代理[…]不包括超长

    utf8_编码() ; 这可能会使文本无法阅读(或完全消失),但嘿,不再有错误消息)

    仅当字符串尚未为UTF-8[…]时才对其进行编码 mb_detect_encoding($s, "UTF-8")

    (如前所述) by another commenter ,这是行不通的:

    $str = 'áéóú'; // ISO-8859-1
    mb_detect_encoding($str, 'UTF-8'); // 'UTF-8'
    mb_detect_encoding($str, 'UTF-8', true); // false
    

    utf8|[encode | decode]实际上也将翻译windows-1252字符,而不仅仅像文档中所说的那样从/到ISO-8859-1

    (你永远不能指望官方的php文档是清晰的或详尽的——你必须阅读多年的用户经验,没有人会反馈给文档)

    我一直在研究一个is_utf8函数,并想把它发布在这里,除了其他函数外,我还考虑了5000字符的错误

    utf8_编码() 函数放弃每个代码点超过4字节,如果结果(或输出?)文本超过5000个字符的限制,它也将中断)

    看到这条特定的线索活跃了八年,并不完全能让人相信八年后情况会有所好转。

        3
  •  12
  •   user8599 user8599    17 年前

    “多字节字符”的概念是问题的核心。

    1. 这是一个难题:除了我们都“真正知道”字符串是字节序列这一过时的思维习惯之外,我们现在必须知道,有时字节会聚集在一起形成Unicode字符,并且各地都有处理它的特殊情况。
    2. 这就像一只老鼠试图吃掉一头大象。通过将Unicode框架化为ASCII的扩展(我们有普通字符串,我们有mb_字符串),它会把事情弄得一团糟,并且会纠结于需要哪些特殊情况来处理需要超过一个字节的有趣扭曲字符。如果将Unicode视为为为所需的任何字符提供了一个抽象空间,那么就可以容纳ASCII,而无需将其视为特例。
        4
  •  5
  •   postfuturist    17 年前

    还有一些 extremely popular encodings 由PHP支持,可能是因为不可能这样做并保持向下兼容。

        5
  •  3
  •   VolkerK    17 年前


        6
  •  3
  •   user42092 user42092    17 年前

    许多字符串函数只是C库等价物的精简包装,它也将所有内容都视为字节序列。另一个原因是PHP带来了很多不必要的向后兼容性负担,因此被3&4.

    也许有了5.3的名称空间,他们终于可以逐步淘汰旧功能了。

        7
  •  2
  •   muratgu    17 年前

    “支持”是指“本地支持”。看看 this