先週末にPHPを5.2.0から5.2.8にアップデートしたら,急にバックアップに失敗するようになりました.全てではなく4つのコースのみです.そのうちの一つは少なくともここしばらくは誰もコースに入っていないと思われる動きの少ないコースです.でも,まぁ,そういうこともあるかな?程度に軽く考えていました.
それとは別件で,Wikiのエクスポートを久しぶりに使ったらzip書庫の作成に失敗しました.そして調査を進めて行くと,どうやらバックアップの失敗も同じzip書庫の作成に失敗していることが原因のようであることが分かってきました.
近頃はpclzipライブラリではなく,外部のzipプログラムを使っています.これを試しにpclzipを使うように,$CFG->zipを空に設定してみたところ,バックアップもエクスポートも成功します.内部と外部のzip手順の違いを調べて行く過程で,escapeshellarg()関数の挙動がおかしいことに気付きました.
以下に簡単に再現するコードを示します.
<?php
$str = "情処応用";
echo $str."<br />";
for ($i = 0; $i < strlen($str); $i++) echo "[".bin2hex($str[$i])."]";
echo "<br/>";
$str = escapeshellarg($str);
echo $str."<br />";
for ($i = 0; $i < strlen($str); $i++) echo "[".bin2hex($str[$i])."]";
echo "<br/>";
?>
マルチバイト文字はシフトJISではなくUTF-8です.PHP5.2.8(Windows/32bit)の実行結果は,
情処応用
[e6][83][85][e5][87][a6][e5][bf][9c][e7][94][a8]
"��処応用"
[22][e6][83][e5][87][a6][e5][bf][9c][e7][94][a8][22]
0x85が1個,消えています.両端をシングルクオートではなくダブルクオート(0x22)で括るのはWindows的には正しい動作です.これをPHP5.2.5(Windows/32bit)で実行すると,
情処応用
[e6][83][85][e5][87][a6][e5][bf][9c][e7][94][a8]
"情処応用"
[22][e6][83][85][e5][87][a6][e5][bf][9c][e7][94][a8][22]
と出力されます.もちろん,二つのWindowsの環境が完全に一致している訳ではありません.php.iniもhttpd.confも違います.ただ,いままで問題なく動いていた側のPCが,PHPを5.2.8に変えただけで異常な症状を示しましたので,やはりPHP5.2.8を疑いたくなります.Webで情報を探しましたが,該当する報告は見当たりませんので,当方の環境だけなのかも知れませんが...どなたかLinuxの環境でPHP5.2.8(あるいはPHP5.2.9)を実行可能な方,先に示したコードを実行して結果を教えて頂けないでしょうか.
なお,escapeshellarg()にまつわるトラブルの中に,ロケールの問題を挙げている方もいました.
setlocale(LC_ALL, 'ja_JP.UTF-8');
で改善したという報告(この現象とは別の現象です)があったので試してみましたが,効果はありませんでした.
#2時間くらい悩んでしまいました...
#あ,もちろん,Windows環境のPHP5.2.8や5.2.9,あるいはPHP5.2.6, 5.2.7での動作報告もお待ちしております.