以下の話は推測に過ぎません.
$_SERVERはWebサーバ(IIS, Apache)が値をセットするようです.
ここで,IISは日本向けにカスタマイズされていると仮定します.例えば日本語URLへの対応を含めて.Webブラウザから送られてくる'HTTP_ACCEPT_LANGUAGE'や'HTTP_ACCEPT_CHARSET'(IEは送出しない!)の如何に関わらず,IIS(日本版Windows2000/XP/Server用)はPATH_INFOなどのパラメータを強制的にシフトJISに変換してしまうのではないかという疑いが濃厚です.
IEはIE5より,URLを(サーバへ)UTF-8で送信する,がデフォルトになっていると聞きます.そしてfs_moodleで苦慮したように,日本版Windowsのファイルシステムは原則的にシフトJISです.当然,IIS(Webサーバ)側に保管されるHTMLその他のファイル名/フォルダ名にマルチバイト文字を使う場合,シフトJISで取り扱う必要があります.「HTMLファイルなどの名前には英数文字を使うべき」という原則論は一般ユーザに強制できませんので,IISを使って手軽にWebサーバを構築しようとする日本語WindowsユーザはHTMLファイル名に日本語を使う場合が多々あるでしょう.その際に,PHPやPerlやJavaScriptなどの動的なWebページだけではなく,静的なWebページを作成しても問題にならないように,UTF-8をシフトJISに自動変換する仕組みが日本版IISには仕様として随所に組み込まれているのではないでしょうか.$_SERVERスーパーグローバル変数の要素の一つであるPATH_INFOも同じ理由でUTF-8からシフトJISに(意図的かつ自動的に)変換されていると予想されます.
Firefoxでは,'HTTP_ACCEPT_LANGUAGE'は日本語抜きに設定することができました.それでも日本版IISはPATH_INFOをシフトJISに変換しています.'HTTP_ACCEPT_CHARSET'からShift-JISを除外することは標準的な操作ではできませんでしたし,そもそもIEは送出していません.したがって,Webブラウザからの制御で,日本版IISがPATH_INFOをシフトJISに変換するのを防ぐことは無理でしょう.
では,日本版IISがPATH_INFOを御親切にもシフトJISに自動変換するのを何らかの方法で抑制できないのか.IISの設定を見た限りでは分かりません.レジストリを操作することで抑制できるのかも知れませんが,システムを不安定にさせる危険や他のWebサービスに悪影響が生じる恐れがあることを考えると避けなくてはいけない.
本件を通して日本版IISと日本版IEの間のマルチバイト文字コードの取り扱いが何となく見えてきました.
IE:サーバへの情報の送出はUTF-8で行なうが,サーバから受け取る情報はシフトJISである.
IIS:ブラウザから受け取る情報はUTF-8で受け,ブラウザおよびPHPなどの実行プログラムにはシフトJISに変換して提供する.
全ては日本語WindowsのファイルシステムがシフトJISである,という点に根源があるようです.
では,どう対策するか.$_SERVER変数をvar_dump()してみると分かるのですが,
- $_SERVER['PATH_TRANSLATED']
- $_SERVER['REQUEST_URI']
- $_SERVER['URL']
- $_SERVER['ORIG_PATH_INFO']
- $_SERVER['PATH_INFO']
- $_SERVER['ORIG_PATH_TRANSLATED']
以上の変数が自動変換されています.
もし,URL部に日本語を含む(Moodleの場合は心配しなくて良いでしょう)場合は,
- $_SERVER['SCRIPT_NAME']
- $_SERVER['SCRIPT_FILENAME']
- $_SERVER['PHP_SELF']
も自動変換されます.
$_SERVER['HTTP_COOKIE']は自動変換などの処理から逃れられているようです.
Moodleのソースリストの早い段階で,$_SERVER['PATH_TRANSLATED'],_$SERVER['REQUEST_URI'],$_SERVER['URL'],$_SERVER['ORIG_PATH_INFO'],$_SERVER['PATH_INFO'],$_SERVER['ORIG_PATH_TRANSLATED']をUTF-8に再エンコーディングして元に戻す.サーバが日本版IISかどうかは,$_SESSION["SERVER_SOFTWARE"]="Microsoft-IIS/5.1"だけですので判断が出来ませんので,シフトJISからUTF-8と明示しないで,'auto'に任せた方が良いかも知れません.
場所としては,config.phpで必ず読み込まれるlib/setup.phpの冒頭あたりで手を打つべきでしょうか.あるいはlib/setup.phpから比較的速やかに呼び出されるlib/setuplib.php,fs_moodleですとlib/setuplib.phpの冒頭でlib/fs_moodle/fs_index.phpを読み込みますので,ここで対策を施しても間に合いそうです.
原因が分からずに対策だけを打つのはイヤでしたが,大体のメカニズムが読めてきましたので,以上の方針でfs_moodleは対策を行ないます.