我正在创建一个非常简单的文件搜索,其中搜索数据库是一个文本文件,每行一个文件名。数据库是用PHP构建的,通过grepping文件(也使用PHP)可以找到匹配项。
这在Linux中很有用,但是not on Mac when non-ascii characters are used。看起来HFS +(MacOSX)上的名称编码方式与例如ext3(Linux)。这是test.php:
<?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$
有没有办法让这个脚本在两个平台上都“平等”?
答案 0 :(得分:4)
MacOSX使用标准化形式D(NFD)编码UTF-8,而most other systems use NFC。
NFD到NFC转换有several implementations。在这里,我使用PHP Normalizer class来检测NFD字符串并将其转换为NFC。它可以在PHP 5.3或PECL Internationalization extension中使用。以下修订将使脚本有效:
...
$filename = $h->read();
if (!normalizer_is_normalized($filename)) {
$filename = normalizer_normalize($filename);
}
...
答案 1 :(得分:3)
似乎Mac OS X / HFS +使用的是字符组合而不是单个字符。因此,ó
(U + 00F3)被编码为o
(U + 006F)+ ´
(U + CC81,COMBINING ACUTE ACCENT)。另请参阅Apple’s Unicode Decomposition Table。
答案 2 :(得分:0)
您是否检查过两个系统都使用相同的区域设置?
PHP脚本在两个系统上使用什么编码?
我也会尝试使用strcmp而不是equals运算符。我不确定equals运算符是否在内部使用strcmp,但在你的情况下测试是一件简单的事情。