【Laravel】 基本的なルーティングを行おう
LaravelのルーティングでHTTPメソッドの指定、コントローラの指定、名前の付与、ルートパラメータといった基本的な設定を見ていきましょう。
目次
基本的なルーティングの設定
ルーティング関連の一覧は、app/routes/
ディレクトリ内に入っています。基本的にはweb.php
を触ることになると思います。
特定のパスにアクセスが来たら特定のコントローラのメソッドを起動する、といった処理は、次のように書きます。
// /hello-world にgetメソッドでアクセスされたら、HelloControllerのindex()を実行する Route::get('/hello-world', [App\Http\Controllers\HelloController::class, 'index']);
use
するとクラス名を短縮できます。
use App\Http\Controllers\HelloController; Route::get('/hello-world', [HelloController::class, 'index']);
コントローラを使わない場合
静的ページなどでは、コントローラを使用せずに直接ビューを返すことでコード量を減らせます。 (それが良い設計かはともかくとして)
Route::get('/', function () { // app/resources/views/welcome.blade.php を返す return view('welcome'); });
リダイレクト
特定のパスから別のパスにリダイレクトしたい場合、Route::redirect('元ページ', 'リダイレクト先');
のように書きます。第3引数にはステータスコードを入れることができます。
また、ページを移転したなど、永続的なリダイレクトを示したい場合はRoute::permanentRedirect('元ページ', 'リダイレクト先');
のように書きます。
// デフォルトのステータスコードは302 Route::redirect('/hello-world', '/home'); // ステータスコードを指定する場合 (301を入れた場合とpermanentRedirectは同じ) Route::redirect('/hello-world', '/home', 301); // ステータスコードは301 Route::permanentRedirect('/hello-world', '/home');
HTTPメソッド
Laravelのルーティングでは、6種類のHTTPメソッドを利用できます。
Route::get('/hello-world', [HelloController::class, 'index']); Route::post('/hello-world', [HelloController::class, 'index']); Route::put('/hello-world', [HelloController::class, 'index']); Route::patch('/hello-world', [HelloController::class, 'index']); Route::delete('/hello-world', [HelloController::class, 'index']); Route::options('/hello-world', [HelloController::class, 'index']);
それぞれのHTTPメソッドについては、下の記事を参考にしてください。
anyとmatch
HTTPメソッドの部分には、any
やmatch
も指定できます。
any
は全てのHTTPメソッドにマッチさせたい場合に、match
は指定したHTTPメソッドにマッチさせたい場合に使用します。
ここで、any
は他の同じパスの別メソッドより後に宣言する必要があります。
// 同じパスなら、anyを後に宣言 Route::get('/hello-world', [HelloController::class, 'index']); // 先に宣言したget以外にマッチする Route::any('/hello-world', [HelloController::class, 'index']); // POSTとPUTにマッチさせる Route::match(['get', 'post'], '/hello-world2', [HelloController::class, 'index']);
ルートパラメータ (パスパラメータ)
例えば、https://.../user/120/friends
のように、URLの途中にリソースを表す値が入る場合があります。このURLでは、IDが120
であるユーザを示していますね。
このような値を設定して取得したい場合、user/{id}
のように{}
を使用して設定します。これらのパラメータはコントローラの引数に設定し、複数のパラメータがある場合はその順番どおりに格納されます。
もしリクエストボディのようなリクエストがある場合は、それが1番目の引数で、ルートパラメータは2つ目以降に入ります。
Route::get('/notes/{id}', [HelloController::class, 'getNote']); Route::get('/user/{id}/files/{fileId}', [HelloController::class, 'getFile']);
public function getNote($id) { return Note::find($id); } // リクエストがある場合は、第1引数にRequest、第2引数以降にルートパラメータの箱を設定する public function getNote2(Request $request, $id) { Log::debug($request->all()); return Note::find($id); } // ルートパラメータが複数ある場合は順番通りに並べる public function getFile($id, $fileId) { Log::debug($id); Log::debug($fileId); return /*...*/; }
もし入るかどうかがわからないパラメータがある場合、/user/{id?}
のように?
を付与します。
ルートパラメータに制約をつける
正規表現を使用して、ルートパラメータの規則を指定できます。その規則から外れた値が入ってきた場合、404を返します。
設定するには、Route::get('user/{id}')->where(['id' => '[0-9]+')
のようにwhere
をつなぎ、引数には連想配列を入れます。
// idを0~9の数値のみかつ1桁以上に制限 Route::get('/notes/{id}', [HelloController::class, 'getNote']) ->where(['id' => '[0-9]+']); Route::get('/user/{id}/files/{fileId}', [HelloController::class, 'getFile']) ->where(['id' => '[0-9]+', 'fileId' => '[0-9a-zA-Z]{16}']);
ルートパラメータが1つだけの場合、->where('id', '[0-9]+')
のように、配列ではなく実引数2つでも設定できます。
また、->where('id', '[0-9]+')->where('fileId', '[0-9a-zA-Z]{16}');
のようにメソッドチェーンでつなぐこともできます。
名前がついている制約を使う
一部のしばしば利用するような制約は、where
の代わりにwhereNumber
といったメソッドを用いると楽です。
引数は1つで、ルートパラメータ名を入れます。複数のルートパラメータがある場合はメソッドチェーンでつなぎます。
Route::get('/notes/{id}', [HelloController::class, 'getNote']) ->whereNumber('id'); Route::get('/user/{id}/files/{fileId}', [HelloController::class, 'getFile']) ->whereNumber('id') ->whereAlphaNumeric('fileId'); // 同じ制約が複数ある場合は配列で並べられる Route::get('hoge/{id}/{foo}/{bar}', [HelloController::class, 'hogehoge']) ->whereNumber(['id', 'foo', 'bar']);
利用できる制約は4種類あります。
制約名 | 役割 |
---|---|
whereNumber | 任意の桁数の数値 |
whereAlpha | 任意の文字数の大文字小文字 |
whereAlphaNumeric | 任意の桁数の英数字 |
whereUuid | UUID |
グローバル制約
URLでルートパラメータを設定する際に、例えばユーザ名などが何度も出現する場合があります。しかし、出現する度に制約を1つ1つ書いていては大変なことになります。
そこで、app/Providers/RouteServiceProvider.php
のboot
メソッド内に、Route::pattern('id', '[0-9]+')
のような形式で定義できます。定義したら、同名のルートパラメータ全てに反映されます。
public function boot() { Route::pattern('userId', '[0-9]+'); }
// userIdに対し、自動的に [0-9]+ の制約が適用される Route::get('/user/{userId}', [HelloController::class, 'user']);
ルートに名前をつける
ルートに名前をつけることで、URLではなく名前を利用してURLを生成できるようになります。URLは様々な理由によって変化する可能性があり、かつ内容によっては変更するタイミングを選ぶ必要がありますが、名前はそれに縛られません。
名前は、Route::get(...)->name('名前')
のように定義します。
Route::get('/hello-world', [HelloController::class, 'index'])->name('home'); Route::get('/notes/{id}', [HelloController::class, 'getNote'])->name('getNote');
定義した名前は、route('home')
やroute('getNote', ['id' => 10])
のようにするとURLを取得できます。
$url = route('home'); // http://localhost/hello-world
route
関数はビュー側でも利用できます。
@for ($i = 1; $i <= 4; $i++) <!-- ルートパラメータを設定する場合は、routeの第2引数に連想配列で入れる --> <a href="{{ route('getNote', ['id' => $i]) }}">note {{ $i }}</a> @endfor
まとめ
ルーティングでは単にパスを書くだけでなく、ルートパラメータを定義したり、名前をつけて管理できるようにしたりといったことが可能です。
他にもグルーピングしたりと言った操作も可能なので、続きの記事も見ていきましょう。
