Laravelのルーティングファイル web.phpの中で波カッコの中にはてなマーク?
がついた記述を見ることがあります。
波カッコ{ }の中のクエスチョンマーク(?)の意味
例えば以下のように {page?} となっている部分です。
これは、設定が任意のパラメータという意味です(あってもなくても機能する)。
Route::get('/articles/{page?}/',[ArticleController::class, 'list'])
->where('page', '^page-[0-9]+')
->name('articles');
{ }の意味
Laravelではルートの中で{パラメータ名}
を指定すると、パラメータとしてURIのパスを受け取ることができます。
例えば、 Route::get('/articles/{page}/',[ArticleController::class, 'list'])
のように ? がない場合は、パラメータが必須となります。
ここで設定したコントローラのアクションに飛ばすためには、https://example.com/articles/page-2 のようなURLである必要があります。
この時、page
という変数にURLの該当部であるpage-2
が入り、これをコントローラにパラメータとして渡すことができます。
{ パラメータ名? }の場合
{ }
でパラメータ名を指定して、その後ろに ?
をつけるとパスが任意になります。
Route::get('/articles/{page?}/',[ArticleController::class, 'list'])
のように ? がある場合は、パラメータがない場合のURLも、このコントローラとアクションに飛ばすことができます。
以下の2つともがこのルーティングに該当します。
- https://example.com/articles
- https://example.com/articles/page-2
この設定をした場合のルーティングは以下のようになります。
# php artisan route:list
+--------+----------+---------------------------+------------------------+---------------------------------------------------+-----------------------------------------------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+---------------------------+------------------------+---------------------------------------------------+-----------------------------------------------------+
| | GET|HEAD | articles/{page?} | articles.list | App\Http\Controllers\ArticleController@list | web |
生成するのはarticles/{page?}
のひとつです。
受け取ったパラメータが条件にあっているか確認する(whereメソッド)
whereメソッドを使うと、受け取ったパラメータが指定したフォーマットになっているか確認することができます。
whereの条件に合わない場合は、指定したコントローラのアクションには飛ばさないようにできます。
パラメータが1つの場合
->where('パラメータ名', '正規表現')
実例
Route::get('/articles/{page?}/',[ArticleController::class, 'list'])
->where('page', '^page-[0-9]+')
この場合、パラメータがpage-数値の場合のみこのルーティングを使用します。
パラメータが複数の場合
パラメータが複数の場合はwhereの引数に連想配列を渡します。
->where( ['パラメータ名1' => '正規表現1', 'パラメータ名2' => '正規表現2',,,] )
実例
Route::get('/articles/{category}/{page?}/',[ArticleController::class, 'list'])
->where( ['category' => '[a-z]+', 'page' => '^page-[0-9]+'] )
この場合、パラメータがpage-数値の場合のみこのルーティングを使用します。
コントローラでパラメータを受け取る方法
ルーティングで設定したパラメータを受け取るには、コントローラ内のアクションの引数を指定します。
パラメータが1つの場合
パラメータが1つの場合は、アクションの引数に変数名を入れます。ルーティングと連動して、指定した変数名にパラメータの値が入ります。
public function アクション名 ($変数名)
{ 処理 }
実例
Route::get('/articles/{page?}/',[ArticleController::class, 'list'])
->where('page', '^page-[0-9]+')
↓ コントローラで受け取る
public function list ($page)
{ 処理 }
パラメータが複数の場合
パラメータが複数の場合は、パラメータの数だけアクションの引数に変数名を入れます。
public function アクション名 ($変数名1, $変数名2,,,)
{ 処理 }
実例
Route::get('/articles/{category}/{page?}/',[ArticleController::class, 'list'])
->where( ['category' => '[a-z]+', 'page' => '^page-[0-9]+'] )
↓ コントローラで受け取る
public function list ($category, $page)
{ 処理 }
デフォルト値を指定する
{パラメータ?} とした場合、アクションの引数で変数を指定していても何も渡されないことがあります。
そのような時のために、何も渡されていない時の値(デフォルト値)を設定することができます。
public function アクション名 ($変数名 = デフォルト値)
{ 処理 }
実例
次のようにすれば、パラメータが1つもない時は$pageの値はnullとなります。
public function list ($page = null)
{ 処理 }
(参考)PHP 関数の引数
受け取るパラメータの型を指定(変換)する方法
引数の中で変数の前に型を記述することで、渡されるパタメータの型を指定することができます。
変換可能な場合は指定した型に変換します。
public function アクション名 (型 $変数名)
{ 処理 }
実例
以下のようにすると、1つ目のパラメータで渡されるデータは文字列型であることを指定できます。
public function list (string $page)
{ 処理 }
(参考)PHP 型宣言
型指定でnullを許可する方法
通常、型指定をするとnullを許容することができなくなります。
{パラメータ名?}
とした場合は、パラメータがないルーティングの時に、引数で指定した変数の値をnullにしたい場合もあります。
そのような時は、型の前に ? をつけることで、nullを許可する型宣言とすることができます。
public function アクション名 (?型 $変数名)
{ 処理 }
実例
以下のようにすると、1つ目のパラメータで渡されるデータは文字列型または、nullとなることを指定できます。
パラメータが渡されない時のデフォルト値はnullです。
public function list (?string $page = null)
{ 処理 }
(参考)PHP 型宣言