5

Linux を実行しているサーバーに Unicode 文字を含むファイルがあります。サーバーにSSHで接続し、タブ補完を使用してUnicode文字を含むファイル/フォルダーに移動すると、ファイル/フォルダーに問題なくアクセスできます。PHP経由でファイルにアクセスしようとすると問題が発生します(ファイルシステムにアクセスしていた関数は でしたstat)。PHPスクリプトによって生成されたパスをブラウザに出力してターミナルに貼り付けると、ファイルも存在するように見えます(ターミナルを見てもファイルパスはまったく同じです)。

php_ini と set を介して、デフォルトのエンコーディングとして UTF8 を使用するように PHP を設定しましmb_internal_encodingた。PHP ファイルパスの文字列エンコーディングを確認したところ、本来の UTF8 として出力されます。もう少し突っ込んhexdumpで、端末のタブ補完であるé文字を決定し、PHPスクリプトによって作成された「通常の」é文字と比較するhexdumpか、キーボードを介して文字を手動で入力します(option + e + e on os x)。結果は次のとおりです。

エコー -n é | 16進ダンプ
0000000 cc65 0081                              
0000003
エコー -n é | 16進ダンプ
0000000 a9c3                                   
0000002

ターミナルで正しいファイル参照を可能にする é 文字は 3 バイトのものです。ここからどこへ行けばよいかわかりません。PHP ではどのエンコーディングを使用すればよいですか? またはを介し​​てパスを別のエンコーディングに変換する必要がありますiconvmb_convert_encoding?

4

3 に答える 3

6

2つの回答に記載されているヒントのおかげで、特定の文字のさまざまなUnicode分解を正規化するためのいくつかの方法を見つけることができました。私が直面した状況では、OSXCarbonアプリケーションによって作成されたファイルにアクセスしていました。これはかなり人気のあるアプリケーションであるため、そのファイル名は特定のUnicode分解に準拠しているように見えました。

PHP 5.3では、Unicode文字列を特定の分解に正規化できる新しい関数セットが導入されました。どうやら、Unicode文字列を分解できる4つの分解標準があります。Pythonには、バージョン2.3以降、unicode.normalizeを介したUnicode正規化機能があります。PythonによるUnicode文字列の処理に関するこの記事は、エンコーディング/文字列の処理を少しよく理解するのに役立ちました。

Unicodeファイルパスを正規化する簡単な例を次に示します。

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

NFD形式は私のすべての目的で機能することがわかりました。これが、Unicodeファイル名の標準的な分解であるかどうか疑問に思います。

于 2009-12-19T20:25:12.770 に答える
3

3 バイト シーケンスは、実際にはe (0x65)の utf8 表現であり、その後に結合 ´ (0xcc 0x81)が続きますが、0xc3 0xa9 はéを「直接」表します。
utf-8 対応の照合は可能な分解を認識する必要がありますが、Mac でそれを有効にする (そしておそらく php ソースを再コンパイルする) 方法がわかりません。
私が提供できる最善の方法は、「Gentoo で UTF-8 を使用する」という説明です。

于 2009-07-07T08:26:13.377 に答える