CodeIgniter1.7.3がQueryStringを含むパスを扱えるようにする

仕事で、CodeIgniter1.7.3 を触り始めました。基本的に素晴しいフレームワークだと思うのですが、いくつか、個人的に気に入らない動作があります。

不満点

おせっかいなInputクラス

GET、POST、および クッキーデータ

単純に、システムが通例のクエリ文字列ではなくURIセグメントを利用可能にしているので、CodeIgniter では、GETメソッドでのデータ(クエリ文字列)の使用は許可されません (設定ファイルでクエリ文字列オプションを有効にした場合はこの限りではありません)。システムが初期化される過程で、グローバルなGET配列($_GET)は入力クラスによってクリアされます。 (1.7.3 ユーザガイドより)

設定ファイルでクエリ文字列オプションを指定してても、なぜか正しいコントローラのメソッド呼び出されず、404になってしまいました。

コントローラのメソッド解析する前に、query_string(?より後ろ)を除外するようにするパッチ

--- system/libraries/URI.php.org        2011-03-30 21:36:00.730915376 +0800
+++ system/libraries/URI.php    2011-03-30 21:56:32.270865996 +0800
@@ -228,7 +228,9 @@
         */
        function _explode_segments()
        {
-               foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
+               //befor parse segments, omit query_string.
+               $uri_string = preg_replace("/\?.*/", '', $this->uri_string);
+               foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $uri_string)) as $val)
                {
                        // Filter segments for security
                        $val = trim($this->_filter_uri($val));

Register_globals

$_POST および $_COOKIE 配列 以外の全グローバル変数は、システムが初期化されるときにクリアされます。このクリア処理はregister_globals = off と同等の効果を発揮します。 (1.7.3 ユーザガイドより)

別に消すこたないのにと思った。

REST風アクセス時のURLエンコードされたURL解釈

よくあるREST風のURLを実現するために、コントローラクラス名とメソッド名に続けてパラメータを指定できるようになってます。

    /<コントローラクラス名>/<メソッド名>/<パラメータ1>/<パラメータ2>/
class Book extends Controller {
  function search($name) {
    //...
  }
}

このような時、/book/search/%E3%81%BB%E3%81%92 というURIにアクセスした時、searchメソッドの引数の$nameには、URLデコードされた物が渡されると思ってたら、%E3%81%BB%E3%81%92 というエンコードされた状態の文字列が設定されていた。更に、第一パラメータのところに、URLエンコードされた / が入るとそのリスエストは、404になってしまった。これは、ちょっと調べたけど、CodeIgniterの問題なのかよくわからない。他のPHPフレームワークではできたと思うんだけどな。未調査。

追記 2011-03-31

http://kawama.jp/archives/2007/04/path_info2f404a.html

たとえば上記の例。apacheの設定がデフォルト状態だと404エラーになります。 これを解消するにはAllowEncodedSlashesをOnにします。

多分続く。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください