Routing
基本的なルーティング
一番基本のLaravelルートはシンプルにURIと「クロージャ」により定義され、単純で記述しやすいルートの定義方法を提供しています。
Route::get('foo', function () {
return 'Hello World';
});
デフォルトルート定義ファイル
Laravelの全ルートは、routes
ディレクトリ下に設置されている、ルートファイルで定義されます。これらのファイルはフレームワークにより、自動的に読み込まれます。routes/web.php
ファイルで、Webインターフェイスのルートを定義します。定義されたルートはweb
ミドルウェアグループにアサインされ、セッション状態やCSRF保護などの機能が提供されます。routes/api.php
中のルートはステートレスで、api
ミドルウェアグループにアサインされます。
ほとんどのアプリケーションでは、routes/web.php
のルート定義から始めることになるでしょう。
使用可能なルート定義メソッド
ルータはHTTP動詞に対応してルートを定義できるようにしています。
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
複数のHTTP動詞に対応したルートを登録する必要が起きることもあります。match
メソッドが利用できます。もしくは全HTTP動詞に対応するany
メソッドを使い、ルート登録することもできます。
Route::match(['get', 'post'], '/', function () {
//
});
Route::any('foo', function () {
//
});
CSRF保護
web
ルートファイル中で定義され、POST
、PUT
、DELETE
ルートへ送信されるHTMLフォームはすべて、CSRFトークンフィールドを含んでいる必要があります。含めていないと、そのリクエストは拒否されます。CSRF保護についての詳細は、CSRFのドキュメントをご覧ください。
<form method="POST" action="/profile">
{{ csrf_field() }}
...
</form>
ルートパラメーター
必須パラメータ
もちろん、ルートの中のURIセグメントを取り出す必要が起きることもあります。たとえば、URLからユーザIDを取り出したい場合です。ルートパラメーターを定義してください。
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
ルートで必要なだけのルートパラメーターを定義することができます。
Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
//
});
ルートパラメータは、いつも{}
括弧で囲み、アルファベット文字で構成してください。ルートパラメータには、ハイフン(-
)を使えません。下線(_
)を代わりに使用してください。
任意パラメータ
ルートパラメータを指定してもらう必要があるが、指定は任意にしたいこともよく起こります。パラメータ名の後に?
を付けると、任意指定のパラメータになります。対応するルートの引数に、デフォルト値を必ず付けてください。
Route::get('user/{name?}', function ($name = null) {
return $name;
});
Route::get('user/{name?}', function ($name = 'John') {
return $name;
});
名前付きルート
名前付きルートは特定のルートへのURLを生成したり、リダイレクトしたりする場合に便利です。ルート定義にname
メソッドをチェーンすることで、そのルートに名前がつけられます。
Route::get('user/profile', function () {
//
})->name('profile');
コントローラーアクションに対しても名前を付けることができます。
Route::get('user/profile', 'UserController@showProfile')->name('profile');
名前付きルートへのURLを生成する
ルートに一度名前を付ければ、その名前をグローバルなroute
関数で使用することで、URLを生成したり、リダイレクトしたりできます。
// URLの生成
$url = route('profile');
// リダイレクトの生生
return redirect()->route('profile');
そのルートでパラメーターを定義してある場合は、route
関数の第2引数としてパラメーターを渡してください。指定されたパラメーターは自動的にURLの正しい場所へ埋め込まれます。
Route::get('user/{id}/profile', function ($id) {
//
})->name('profile');
$url = route('profile', ['id' => 1]);
ルートグループ
ルートグループは多くのルートで共通なミドルウェアや名前空間のようなルート属性をルートごとに定義するのではなく、一括して適用するための手法です。Route::group
メソッドの最初の引数には、共通の属性を配列で指定します。
ミドルウェア
グループの中の全ルートにミドルウェアを指定するには、middleware
キーをグループ属性配列に使用します。この配列で指定した順番にミドルウェアは実行されます。
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// Authミドルウェアを使用
});
Route::get('user/profile', function () {
// Authミドルウェアを使用
});
});
名前空間
ルートグループのもう一つのよくあるユースケースは、グループ内のコントローラーに同じPHP名前空間を指定する場合です。グループ中の全コントローラーに対して適用する名前空間をグループ配列のnamespace
キーを使用し指定します。
Route::group(['namespace' => 'Admin'], function() {
// "App\Http\Controllers\Admin"名前空間下のコントローラ
});
App\Http\Controllers
名前空間をコントローラールート登録時に毎回指定しなくても済むように、デフォルトでRouteServiceProvider
が名前空間グループの中でroutes.php
ファイルを読み込み、指定していることを覚えておいてください。これにより、先頭のApp\Http\Controllers
名前空間を省略でき、続きの部分を指定するだけで済みます。
サブドメインルーティング
ルートグループはワイルドカードサブドメインをルート定義するためにも使えます。サブドメインの部分を取り出しルートやコントローラーで使用するために、ルートURIにおけるルートパラメーターのように指定できます。サブドメインはグループ属性配列でdomain
キーにより指定します。
Route::group(['domain' => '{account}.myapp.com'], function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
ルートプレフィックス
prefix
グループ配列属性はグループ内の各ルートに対して、指定されたURIのプレフィックスを指定するために使用します。たとえばグループ内の全ルートのURIにadmin
を付けたければ、次のように指定します。
Route::group(['prefix' => 'admin'], function () {
Route::get('users', function () {
// Matches The "/admin/users" URL
});
});
モデル結合ルート
ルートかコントローラアクションへモデルIDが指定される場合、IDに対応するそのモデルを取得するため、大抵の場合クエリします。Laravelのモデル結合はルートへ直接、そのモデルインスタンスを自動的に注入する便利な手法を提供しています。つまり、ユーザのIDが渡される代わりに、指定されたIDに一致するUser
モデルインスタンスが渡されます。
暗黙の結合
Laravelは変数名とルートセグメント名が一致する場合、LaravelはルートかコントローラアクションでEloquentモデルが定義されていると、自動的に依存解決します。
Route::get('api/users/{user}', function (App\User $user) {
return $user->email;
});
この例の場合、ルート上で定義されているEloquentの$user
変数と、ルートのURIの中の{User}
セグメントが一致しているため、Laravelは、リクエストされたURIの対応する値に一致するIDを持つ、モデルインスタンスを自動的に注入します。一致するモデルインスタンスがデータベースへ存在しない場合、404
HTTPレスポンスが自動的に生成されます。
キー名のカスタマイズ
指定されたモデルクラス取得時に、id
以外のデータベースカラムをモデル結合で使用したい場合、EloquentモデルのgetRouteKeyName
メソッドをオーバーライドしてください。
/**
* モデルのルートキーの取得
*
* @return string
*/
public function getRouteKeyName()
{
return 'slug';
}
明示的な結合
明示的に結合を登録するには、ルータのmodel
メソッドで、渡されるパラメータに対するクラスを指定します。RouteServiceProvider
クラスのboot
メソッドの中で明示的なモデル結合を定義してください。
public function boot()
{
parent::boot();
Route::model('user', App\User::class);
}
次に{user}
パラメーターを含むルートを定義します。
$router->get('profile/{user}', function(App\User $user) {
//
});
{user}
パラメーターをApp\User
モデルへ結合しているため、User
インスタンスはルートへ注入されます。ですからたとえば、profile/1
のリクエストでは、IDが1
のUser
インスタンスが注入されます。
一致するモデルインスタンスがデータベース上に見つからない場合、404 HTTPレスポンスが自動的に生成されます。
依存解決ロジックのカスタマイズ
独自の依存解決ロジックを使いたい場合は、Route::bind
メソッドを使います。bind
メソッドに渡す「クロージャ」は、URIセグメントの値を受け取るので、ルートへ注入したいクラスのインスタンスを返してください。
$router->bind('user', function ($value) {
return App\User::where('name', $value)->first();
});
擬似フォームメソッド
HTLMフォームはPUT
、PATCH
、DELETE
アクションをサポートしていません。ですから、HTMLフォームから呼ばれるPUT
、PATCH
、DELETE
ルートを定義する時、フォームに_method
隠しフィールドを追加する必要があります。_method
フィールドとして送られた値は、HTTPリクエストメソッドとして使用されます。
<form action="/foo/bar" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
_method
入力フィールドを生成するために、method_field
ヘルパ関数を使用することもできます。
{{ method_field('PUT') }}
現在のルートへのアクセス
送信されたリクエストを処理しているルートに関する情報へアクセスするには、Route
ファサードへcurrent
、currentRouteName
、currentRouteAction
メソッドを使用します。
$route = Route::current();
$name = Route::currentRouteName();
$action = Route::currentRouteAction();
組み込まれている全メソッドを確認するには、Routeファサードの裏で動作しているクラスと、Routeインスタンスの2つについてのAPIドキュメントを参照してください。