Windows版PHPで日本語ファイル名が正しく扱えない問題について

Windows版のPHP(5.3~7.0)では、日本語等の全角文字(非ASCII文字)を含むファイル名の取得や指定に失敗することがあります。
例えば glob()や scandir()、RecursiveDirectoryIteratorなどのイテレータを使ってファイル名一覧を取得した時、一部のファイルが抜け落ちてしまいます。

原因

原因はどうやら二つあるようです。
一つは、Windows版PHPはShift_JISでファイル名を扱うようで、Unicodeを含むファイル名を無視してしまう為です。
もう一つは、いわゆる5c問題です。Shift_JISでは全角文字の2バイト目が \記号(16進の0x5c, バックスラッシュ)を含むことがあり、これがエスケープ文字やディレクトリ名の区切りと誤認識されてしまう事に起因する不具合です。

解決策

これに対する解決策はないかと、様々試行錯誤してみたのですが解決できませんでした。
glob()を使ってもイテレータを使ってもダメだったので、setlocale(LC_ALL, 'Japanese_Japan.932')や mb_internal_encoding('CP932')等で5c問題だけでも解決するかもしれないと思い試してみましたが、こちらもダメでした。
よって、Windows版PHP(5.3~7.0)では非ASCII文字のファイル名を全て正しく扱うことは残念ながら出来ないというのが結論です。

ただ、色々調べていて解ったことがあります。
実は、PHP5.2までは(恐らく5c問題については)大丈夫だったようなのです。
つまりこれは、PHP5.3以降、PHP7.0までに固有のバグだということです。
更にこちらの記事によれば、このバグはPHP7.1で遂に修正され、喜ばしいことにShift_JISの0x5cやUnicodeを含むファイル名もUTF-8で正しく扱えるようになるとの事です!やったー(´;ω;`)ウッ…

サーバ運用では日本語ファイル名をどうしても扱わなければならないケースというのはあまり無いとは思いますが、やはり正しく扱えれば有り難い事ですね。

テスト環境

PHP 5.6.15
Windows 10

参考


多元配列の内容でソート出来るPHP関数

PHPには、2次元配列の任意のキーの内容でソートが出来る大変便利な関数があります。
array_multisort() がソレですが、公式マニュアルの説明ではいまいち使い方が解りにくい。
で、検索してみたら使い方を解り易く説明してあるサイトがいくつかありました。

Blog.okuryu : PHP の array_multisort で多次元配列をソートする
PHP array_multisortの例文 - Blog::R.1000Leaf
PHPのarray_multisort関数が激便利だったので紹介 : akiyan.com

Blog.okuryuさんの説明が個人的には理解しやすかったです。
foreachで予め準備しなきゃいけないのが多少面倒ではありますが、それでもこれだけ簡潔に書けるのは有り難いですね。

テーマ: プログラミング - ジャンル: コンピュータ

[PHP] リファラ付きでURLからデータを取得

PHPを使って、リファラ(Referer)付きでURLにアクセスしてデータを取得するには、下記のようにすればOKのようです。

$option = array(
'http' => array(
'method' => 'GET',
#参照元URLを設定
'header' => 'Referer: '.'http://参照元URL'."\r\n"
)
);
$context = stream_context_create($option);

#対象URLから$strにファイル内容を取得
$str = file_get_contents('http://対象URL', FALSE, $context);

>> "[PHP] リファラ付きでURLからデータを取得"の続き

テーマ: Webデザイン - ジャンル: コンピュータ

PHPの関数 mb_convert_kanaによる英数字変換の挙動

PHPのmbstring関数の一つ mb_convert_kana()は、全角文字と半角文字の変換を行う大変便利な関数だ。
しかし、英数字の全角半角変換に関しては注意しなければならない点が有る。

>> "PHPの関数 mb_convert_kanaによる英数字変換の挙動"の続き

テーマ: PHP - ジャンル: コンピュータ