ルーティングで名前付きパラメーターを2つ利用し、例外を利用して404ページを表示しようとすると、404ではなく、名前付き2つのパターンへ飛んでしまうというお話です。
これは、ルーティングのコツの記事の一番最後に追加した内容と同じものです。限定的ですが、起き得る話なので、知っていて損はないと思います。バッドノウハウでしょうか。
名前付きパラメーターとは、ルーティングで、マッチさせる時に名前を付け、その名前でコントローラーからアクセスできるというものです。
通常のルーティングは、可変部がなければ、
'blog' => 'blog/index',
'about' => 'fix/about',
と指定し、それぞれ、ドメイン/blog、ドメイン/aboutに一致します。
可変部があるときは、
'blog/(:num)' => 'blog/index/$1',
'search/(:any)' => 'blog/search/$1',
と指定します。ドメイン/blog/数字、ドメイン/search/続いて指定された場合に何でもマッチします。
この場合、$1を受けるコントローラーのアクションメソッドへの引数として受け取ります。
class Controller_Blog extends Controller {
function action_index($post_id) {
}
function action_search($search_param) {
}
}
この:anyに名前をつける方法があります。意味づけをしてわかりやすくなります。
'search/:strings' = > 'blog/search',
名前付パラメーターを利用した場合、コントローラの中で$this->param('strings')で、指定内容を参照できます。
ここまでが、名前付きパラメーターを理解するまでの知識です。
続いて、エラー処理の話。ルーティングで一致しない場合は、自動的に404で指定した、コントローラー/アクションが実行されますが、パラメーターで指定された内容が不正であったり、存在していない場合、自分で404へ飛ばしたい時があると思います。
自分で飛び先がわかっているときは、そのコントローラー/アクションを呼び出せばいいのでしょうが、ハードコードすることになり、変更する場合大変ですし、何かを出力しようとした場合など、そのキャッシュがどうなっているとか、調べる必要が出てきます。そこまで調べたくないというのも人情ですね。
ですから、FuelPHPでは、例外を投げてくれれば、自動的にルーティングして、404ページを出しますよと書かれています。
throw new HttpNotFoundException;
そう書かれているのですが、次のパターンがルーティングに指定されている場合、404ではなくて、そのパターンに移動してしまいます。
例えば:
'(:any)' => 'all/accept/$1',
':one/:two' => 'count/plus',
なぜ、こうなるかというと、この例外が投げられると、まず404に指定したコントローラー/アクションへルートしようとするそうです。それは、'action/index'という形式でルーチングへ依頼され、上記で指定したパターンに一致してしまい、その結果404でなく、一致したパターンが実行されてしまうそうです。
実は、1.1からこうなったそうです。ドキュメントが修正されていないとのこと。404が404エラーを呼んでループすることへの、対処としてこうなったそうです。
そうすると、上記で示したパターンから、404を呼び出したときにもループするんじゃないかと、質問したら、内部でカウントしているから、ループしないそうです。
ここで、それ以上尋ねるのはやめましたが、だったら404もループをカウントして、無限ループを断ち切ればいいだけでないのかと思いますけどね。
対処法としては、public/index.phpの一行を変更します。
前:$response = Request::forge($route)->execute()->response();
後:$response = Request::forge($route, true)->execute()->response();
正直な話、404が404になりループするのは、言ってしまえば自然ですが、それに対処するために、他の機能が制限されるのは、不自然な仕様変更だと思います。
404の処理でもルーティングで単にカウントして、何度もループしているようなら、メッセージ出してdieすればいいんじゃないでしょうかね。根本的な何かが悪くて404で404になってしまうということなんでしょうか。
そこら辺の話は把握できません。
| FuelPHP、メール送信タイムアウトが例外で受け取れない< 前 | 次 >FuelPHP、DBへレッツアクセス |
|---|
| < 前 | 次 > |
|---|