あまりUTF-8の環境でPHPを動かすということがなかったのではまったんですが、BOM(Byte Order Mark)ありのUTF-8で保存したPHPって動作に問題が出るんですね・・・。
要はBOMの先頭バイトが邪魔をしてPHPスクリプトと認識してくれなかったり、文字化けを起すような弊害が出てきます。
じゃあ、事前にBOM付きのUTF-8をBOMなしのUTF-8に変換すればいいとiconvコマンドで変換しようとしても
$ iconv -f UTF-8 -t EUC-JP hoge.php iconv: 位置 0 で不正な入力シーケンスがありました
と、iconvコマンドはBOM付きのUTF-8に対応していない模様・・・。
nkfコマンドもうまくBOMを取り除くということが出来ませんでした。
vimコマンドでは
:set nobomb
として保存することでBOMを取り除くことができます。
ただし、大量にBOM付きのPHPコードが合った場合、ちまちまやってられないので、BOMを取り除くPHPスクリプトを書いてみました。
UTF-8(BOMあり)からBOMだけを取り除くPHPスクリプト
ファイルの先頭に来るBOMコードは0xEFBBBFとなるため、該当ファイルからそれを除去して同じパス上に保存するという動作をします。
<?php $target_dir = "/var/www/html/"; if (is_dir($target_dir)) { if ($dh = opendir($target_dir)) { while (($file = readdir($dh)) !== false) { $path_parts = pathinfo($file); // 拡張子がphpのファイルのみが対象 if ($file != '.' && $file != '..' && ($path_parts['extension'] == 'php')) { $path = $target_dir . $file; // kccコマンドでUTF-8のファイルかどうか判断 $cmd = `kcc -c $path`; list($fname, $enc) = explode(':', $cmd); if (trim($enc) == 'data') { $contents = file_get_contents($path); // BOMありの場合 if (preg_match("/^efbbbf/", bin2hex($contents[0] . $contents[1] . $contents[2])) === 1) { // 先頭3バイトのBOMコードを除去して同名で保存 $contents = substr($contents, 3); file_put_contents($path, $contents); } } } }closedir($dh); } }
対象は拡張子が.phpのファイルのみとしていますが、違えばお好みで変更できます。
また、kccコマンドでUTF-8のファイルかどうか判別(厳密にkccコマンドではUTF-8コードかを判別できず、結果はdataと返ってきます)をしていますが、全てがBOM付きUTF-8のファイルだということであれば、特にその条件判定は必要ないかもしれません。
ツールを使ってPHPファイルを保存した場合、意図しないところで勝手にBOMが挿入されてたりもするのですが、大量に保存してしまったPHPファイルを再度保存しなおすのは手間となるので、こういったスクリプトで一気に除去してしまえば便利かもしれません。
[PR]
[PR]
関連記事
PHPのセッションアダプションによって任意のセッションIDが受入れられる
[PHP] pChartの使い方 - 棒グラフとレーダーチャートを描いてみる
ノンプログラミングでも利用可能!PHPで多様なグラフを作れるpChart
ApacheのプロセスがどのPHPプログラムの処理をしているか調べる方法
レベル3までの文字コード入門 UTF-8の冗長なエンコードの問題へ続く道
[PHP] inotify関数を使ってログを監視するスクリプトを作ろう
NFSマウントした領域内でPHPのsession_startを実行すると異様に重い件