echoとcatとfopen
PHP, Tuit May 10th, 2007
サーバ側で受信したメールをincludeを使ってPHPのスクリプトに食わせた後、処理実行後に今度はRubyのスクリプトに渡す機能を実装したら、日本語のメールが文字化けしていた。
どうやら原因はechoだったようだ。
#!/usr/bin/env php
<?php
/**
* echo
でJISの文字列を書き込むとおかしなことになる。
* 再現環境LANGはja_JP.eucJPかja_JP.utf8
**/
$str = 'これは日本語EUC-JPの文字列です。これからJISに変換します。';
$file = '/tmp/test';
//JISに変換
$str = mb_convert_encoding($str, 'JIS', 'EUC-JP');
/**
* echoを使ってファイルに書き込んでみる
* 失敗する
**/
//echoとcat
$cmd = 'echo "' . $str . '" > ' . $file . ' | cat ' . $file;
$result = `$cmd`;
//EUC-JPに戻して表示
print('結果その1:' . mb_convert_encoding($result, 'EUC-JP', 'JIS'));
//nkfを使って表示
$cmd = 'cat ' . $file . ' | nkf -e -J';
$result = `$cmd`;
print('結果その2:' . $result);
//catのせいではない
$cmd = 'echo "' . $str . '" | nkf -e -J';
$result = `$cmd`;
print('結果その3:' . $result);
/**
* fopenを使ってファイルに書き込んでみる
* うまくいく
**/
//fopenでファイルに書き込んでから表示
$fp = fopen($file, 'w');
fputs($fp, $str);
fclose($fp);
$cmd = 'cat ' . $file . ' | nkf -e -J';
$result = `$cmd`;
print('結果その4:' . $result . "\n");
//PHPのmb_convert_encodingが原因ではない
$cmd = 'cat ' . $file;
$result = `$cmd`;
print('結果その5:' . mb_convert_encoding($result, 'EUC-JP', 'JIS') . "\n");
?>
実行結果は以下の通り:
結果その1:K\8lEUC-JPzNs!#$+JIS^!# 結果その2:K\8lEUC-JPzNs!#$+JIS^!# 結果その3:K\8lEUC-JPzNs!#$+JIS^!# 結果その4:これは日本語EUC-JPの文字列です。これからJISに変換します。 結果その5:これは日本語EUC-JPの文字列です。これからJISに変換します。
echoを実行する前にexportでLANGをいじってみたけど無駄だった。結局、直ったのでfopenで処理することにした。