ルート定義の制約なしのパラメータ設定には危険が潜んでいます。
制約をつけておかないと、意図していないURLまで通ってしまうことがあります。
自分一人で開発していて小規模の案件であればURLを把握しているかもしれませんが、把握しきれていない場合に自分の担当ページのことだけを考えてルート定義に制約なしのパラメータを設定すると、既存のページに影響を及ぼすことがあります。(ありました。←)
本記事ではLaravel5.5を例に挙げて記載していきます。
##制約なしのパラメータの記述
// 必須パラメータの場合
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
// 任意パラメータの場合 ? を記載します
Route::get('user/{id?}', function ($id = null) {
return $id;
});
参照:https://readouble.com/laravel/5.5/ja/routing.html
見出し【必須パラメータ / 任意パラメータ】
上記のように、制約なしのルート定義の場合、例えばURLの『user/hoge
』hoge
の部分に何が入っても、上記のルート定義を通るようになってしまいます。
idなので、数字のみ通るように制約を付けておきたいと思います。
##パラメータの制約設定
制約をつけるには、ルートインスタンスのwhere
メソッドを使用し、定義する正規表現を引数に設定します。
Route::get('user/{id}', function ($id) {
// {id}が数値の場合のみ実行される
})->where('id', '[0-9]+');
参照:https://readouble.com/laravel/5.5/ja/routing.html
見出し【正規表現制約】
->where('id', '[0-9]+')
の追記により、URLが『user/数値』の場合のみ、上記のルート定義を通るようになります。
正規表現で定義することが出来るので、特定のアルファベット+数値、とかも設定できます。
##グローバル制約
『グローバル制約』を設定しておけば、毎回制約を記述する必要がなくなります。RouteServiceProvider
のboot
メソッドの中で、このようなパターンを定義します。
/**
* ルートモデル結合、パターンフィルタなどの定義
*
* @return void
*/
public function boot()
{
Route::pattern('id', '[0-9]+');
parent::boot();
}
パターンを定義すると、パラメータ名を使用している全ルートで、自動的に提供されます。
Route::get('user/{id}', function ($id) {
// {id}が数値の場合のみ実行される
});
参照:https://readouble.com/laravel/5.5/ja/routing.html
見出し【グローバル制約】
##最後に
『グローバル制約』については、本記事を作成する際にドキュメントを見て初めて知りました。(知らんかったんかい)
Laravel学び始めの頃はドキュメントを読んでみても何のことだかさっぱり分からない、という感じでしたが、触るようになってやっと少しは理解できる所が出てきたのだなと思います。他にも色々勉強してみたいと思います。