id:otn:20060529の続き。
結局リライトルールは、
RewriteEngine on RewriteBase /CMD RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*[^/])/?$ index.php?$1 [L]
となった。ファイルやディレクトリで無いとき、末尾に / があればそれを取った上で、先頭に index.php? をつける。途中の / は、%2F に復元せずにそのまま QUERY_STRING に渡すことになるが、特に問題なく動いている。
PATH_INFOの解釈部分の変更は以下の通り。
*** init.php.org Sun Sep 11 14:58:33 2005 --- init.php Sun May 28 23:53:51 2006 *************** *** 274,279 **** --- 274,281 ---- $arg = ''; if (isset($_SERVER['QUERY_STRING']) && $_SERVER['QUERY_STRING']) { $arg = & $_SERVER['QUERY_STRING']; + } else if (isset($_SERVER['ORIG_PATH_INFO']) && $_SERVER['ORIG_PATH_INFO']) { + $arg = ltrim(rtrim($_SERVER['ORIG_PATH_INFO'],'/'),'/'); } else if (isset($_SERVER['argv']) && ! empty($_SERVER['argv'])) { $arg = & $_SERVER['argv'][0]; }
cgiのため、直接にPATH_INFOは参照できず、php.iniに、
cgi.fix_pathinfo=1
を指定した上で、ORIG_PATH_INFOを参照する。先頭と末尾の / を削除した上で、QUERY_STRING で渡されたかのごとく扱う。いずれのケースにおいても途中の / はそのままで問題はおきていない。また、PATH_INFOと違ってOROG_PATH_INFO はURLデコードされた状態で渡ってくるようだが*1、これも再度URLエンコードすることなくデコード済みの状態のまま渡しても問題は起きていない。今後のバージョンアップでもし問題が起きるようなら rawurlencode してから $arg に設定する必要があるかもしれない。
これで、受け側はできた。あとは、html生成側を整形後形式にすればよい。
つづく。
*1:これがcgiの時一般の動作なのか、さくらインターネット固有の事情なのかは未調査