1

検索データベースが 1 行に 1 つのファイル名を持つテキスト ファイルである、非常に単純なファイル検索を作成しています。データベースは PHP で構築されており、ファイルを grep することで一致が検出されます (これも PHP を使用します)。

これは Linux ではうまく機能しますが、非 ASCII 文字が使用されている Mac では機能しません。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$

このスクリプトが両方のプラットフォームで「等しい」を返すようにする方法はありますか?

4

3 に答える 3

4

MacOSX は正規化形式 D (NFD) を使用して UTF-8 をエンコードしますが、他のほとんどのシステムは NFC を使用します

NFC対NFD

( unicode.org より)

NFD から NFC への変換にはいくつかの 実装があります。ここでは、PHP Normalizer クラスを使用してNFD 文字列を検出し、NFC に変換しています。PHP 5.3 またはPECL Internationalization extensionで利用できます。次の修正により、スクリプトが機能します。

...
$filename = $h->read();
if (!normalizer_is_normalized($filename)) {
   $filename = normalizer_normalize($filename);
}
...
于 2009-04-21T18:46:43.590 に答える
3

Mac OS X/HFS+ は、単一の文字ではなく文字の組み合わせを使用しているようです。そのため、ó(U+00F3) はo(U+006F) + ´(U+CC81, COMBINING ACUTE ACCENT) としてエンコードされます。Apple の Unicode Decomposition Tableも参照してください。

于 2009-04-21T17:38:29.633 に答える
0

両方のシステムが同じロケールを使用していることを確認しましたか?

両方のシステムで PHP スクリプトが使用しているエンコーディングは何ですか?

また、等号演算子の代わりにstrcmpを使用してみます。equals 演算子が内部で strcmp を使用しているかどうかはわかりませんが、あなたの場合は簡単にテストできます。

于 2009-04-21T17:08:57.910 に答える