【问题标题】:UTF8 Filenames in PHP and Different Unicode EncodingsPHP 中的 UTF8 文件名和不同的 Unicode 编码
【发布时间】:2010-11-08 13:33:54
【问题描述】:

我在运行 linux 的服务器上有一个包含 Unicode 字符的文件。如果我通过 SSH 连接到服务器并使用制表符完成导航到包含 unicode 字符的文件/文件夹,则访问文件/文件夹没有问题。当我尝试通过 PHP 访问文件时出现问题(我访问文件系统的函数是 stat)。如果我将 PHP 脚本生成的路径输出到浏览器并将其粘贴到终端,则该文件似乎也存在(即使查看终端,文件路径完全相同)。

我通过 php_ini 将 PHP 设置为使用 UTF8 作为其默认编码,并设置了mb_internal_encoding。我检查了 PHP 文件路径字符串编码,它应该是 UTF8。再四处寻找,我决定 hexdump 终端的制表符完成的 é 字符,并将其与 PHP 脚本创建的“常规” é 字符的 hexdump 进行比较,或者通过键盘手动输入字符( os x 上的选项+e+e)。结果如下:

回声-né |十六进制转储 0000000 cc65 0081 0000003 回声-né |十六进制转储 0000000 a9c3 0000002

允许在终端中正确引用文件的 é 字符是 3 字节字符。我不确定从这里去哪里,我应该在 PHP 中使用什么编码?我应该通过iconvmb_convert_encoding 将路径转换为另一种编码吗?

【问题讨论】:

    标签: php unicode encoding utf-8 filepath


    【解决方案1】:

    感谢两个答案中给出的提示,我能够四处寻找并找到一些方法来规范化给定字符的不同 unicode 分解。在我遇到的情况下,我正在访问由 OS X Carbon 应用程序创建的文件。这是一个相当流行的应用程序,因此它的文件名似乎遵循特定的 unicode 分解。

    在 PHP 5.3 中引入了 new set of functions,它允许您将 unicode 字符串规范化为特定的分解。显然,您可以将 unicode 字符串分解为四种分解标准。 Python 自 2.3 版以来通过unicode.normalize 具有 unicode 规范化功能。 This article 关于 python 处理 unicode 字符串有助于更好地理解编码/字符串处理。

    这是一个规范化 unicode 文件路径的简单示例:

    filePath = unicodedata.normalize('NFD', filePath)
    

    我发现 NFD 格式适用于我的所有目的,我想知道这是否是 unicode 文件名的标准分解。

    【讨论】:

      【解决方案2】:

      三字节序列实际上是e (0x65)后跟combining ´ (0xcc 0x81)的utf8表示,而0xc3 0xa9“直接”代表é
      支持 utf-8 的排序规则应该知道可能的分解,但我不知道如何在 mac 上启用它(并且可能重新编译 php 源代码)。
      我能提供的最好的就是"Using UTF-8 with Gentoo" 描述。

      【讨论】:

        【解决方案3】:

        首先:您应该尽量避免对文件名强加语义。我真的不知道为什么 PHP 在你的场景中生成文件名,所以我不能建议你应该如何应用这个规则。

        é 的不同(两个字节和三个字节)表示是 Unicode 中该字符的组合和分解变体的 UTF-8 编码。在 Unicode 中,这些是表示相同视觉字符的不同方式。 Unicode 具有“规范化”的概念,其中同一字符的所有表示都转换为单个表示,有点像将两个字符串压缩为小写以执行无大小写比较。

        Linux 不会对文件名自动执行规范化或任何其他处理,因此文件可以使用预先组合(如两个字节序列)或分解(如三个字节序列)字符或两者的任何混合来命名,它是直到命名该文件的人。如果您正在创建文件,您可以设置一个策略(例如,始终使用预先组合的字符)并编写一些代码来强制执行它。否则,您不能依赖这里的任何特定规则。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-30
          相关资源
          最近更新 更多