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

在PHP中,如何处理HFS+上的编码文件名与其他地方的编码文件名之间的差异?

  •  1
  • neu242  · 技术社区  · 16 年前

    这在Linux中非常有效,但是 not on Mac when non-ascii characters are used

    <?php
    $mystring = "abcóüÚdefå";
    file_put_contents($mystring, "");
    $h = dir('.');
    $h->read(); // "."
    $h->read(); // ".."
    $filename = $h->read();
    
    print "string: $mystring and filename: $filename are ";
    
    if ($mystring == $filename) print "equal\n";
    else print "different\n";
    

    运行MacOSX时:

    $ php test.php
    string: abcóüÚdefå and filename: abcóüÚdefå are different
    $ php test.php |cat -evt
    string: abcóü?M-^Zdefå$ and filename: abco?M-^Au?M-^HU?M-^Adefa?M-^J are different$
    

    在Linux(或MacOSX上安装了nfs的ext3文件系统)上运行时:

    $ php test.php
    string: abcóüÚdefå and filename: abcóüÚdefå are equal
    $ php test.php |cat -evt
    string: abcM-CM-3M-CM-<M-CM-^ZdefM-CM-% and filename: abcM-CM-3M-CM-<M-CM-^ZdefM-CM-% are equal$
    

    3 回复  |  直到 9 年前
        1
  •  4
  •   neu242    8 年前

    MacOSX使用规范化格式D(NFD)对UTF-8进行编码,而 most other systems use NFC .

    NFC vs NFD

    ( from unicode.org )

    several implementations 关于NFD到NFC的转换。这里我使用了PHP Normalizer class 检测NFD字符串并将其转换为NFC。它在PHP5.3中或通过 PECL Internationalization extension

    ...
    $filename = $h->read();
    if (!normalizer_is_normalized($filename)) {
       $filename = normalizer_normalize($filename);
    }
    ...
    
        2
  •  3
  •   Gumbo    16 年前

    Mac OS X/HFS+似乎正在使用字符组合而不是单个字符。所以 ó (U+00F3)改为编码为 o (U+006F)+ ´ Apple’s Unicode Decomposition Table .

        3
  •  0
  •   Ben S    16 年前

    您是否检查过两个系统使用相同的语言环境?

    我也会尝试使用 strcmp 而不是equals运算符。我不确定equals操作符是否在内部使用strcmp,但在您的案例中,这是一个简单的测试。