基本ルーティング

最も基本的なLaravelのルートはURIとクロージャを受け入れ、複雑なルーティング設定ファイルなしでルートと動作を定義する非常にシンプルで表現力豊かな方法を提供します:

  1. use Illuminate\Support\Facades\Route;
  2. Route::get('/greeting', function () {
  3. return 'Hello World';
  4. });

デフォルトのルートファイル

すべてのLaravelのルートは、routesディレクトリにあるルートファイルで定義されています。これらのファイルは、アプリケーションのbootstrap/app.phpファイルに指定された設定を使用してLaravelによって自動的に読み込まれます。routes/web.phpファイルは、Webインターフェース用のルートを定義します。これらのルートには、セッション状態やCSRF保護などの機能を提供するweb ミドルウェアグループが割り当てられています。

ほとんどのアプリケーションでは、routes/web.phpファイルでルートを定義することから始めます。routes/web.phpで定義されたルートには、ブラウザで定義されたルートのURLを入力することでアクセスできます。たとえば、ブラウザでhttp://example.com/userに移動することで、次のルートにアクセスできます:

  1. use App\Http\Controllers\UserController;
  2. Route::get('/user', [UserController::class, 'index']);

APIルート

アプリケーションがステートレスAPIも提供する場合、install:api Artisanコマンドを使用してAPIルーティングを有効にできます:

  1. php artisan install:api

install:apiコマンドは、Laravel Sanctumをインストールし、サードパーティのAPI消費者、SPA、またはモバイルアプリケーションを認証するために使用できる堅牢でシンプルなAPIトークン認証ガードを提供します。さらに、install:apiコマンドはroutes/api.phpファイルを作成します:

  1. Route::get('/user', function (Request $request) {
  2. return $request->user();
  3. })->middleware('auth:sanctum');

routes/api.phpのルートはステートレスであり、api ミドルウェアグループに割り当てられています。さらに、/api URIプレフィックスはこれらのルートに自動的に適用されるため、ファイル内のすべてのルートに手動で適用する必要はありません。プレフィックスは、アプリケーションのbootstrap/app.phpファイルを変更することで変更できます:

  1. ->withRouting(
  2. api: __DIR__.'/../routes/api.php',
  3. apiPrefix: 'api/admin',
  4. // ...
  5. )

利用可能なルーターメソッド

ルーターは、任意のHTTP動詞に応答するルートを登録することを許可します:

  1. Route::get($uri, $callback);
  2. Route::post($uri, $callback);
  3. Route::put($uri, $callback);
  4. Route::patch($uri, $callback);
  5. Route::delete($uri, $callback);
  6. Route::options($uri, $callback);

時には、複数のHTTP動詞に応答するルートを登録する必要があるかもしれません。その場合は、matchメソッドを使用できます。また、anyメソッドを使用して、すべてのHTTP動詞に応答するルートを登録することもできます:

  1. Route::match(['get', 'post'], '/', function () {
  2. // ...
  3. });
  4. Route::any('/', function () {
  5. // ...
  6. });

同じURIを共有する複数のルートを定義する場合、getpostputpatchdelete、およびoptionsメソッドを使用するルートは、anymatch、およびredirectメソッドを使用するルートの前に定義する必要があります。これにより、受信リクエストが正しいルートに一致することが保証されます。

依存性注入

ルートのコールバックシグネチャ内で、ルートに必要な依存関係を型ヒントすることができます。宣言された依存関係は、Laravelのサービスコンテナによって自動的に解決され、コールバックに注入されます。たとえば、Illuminate\Http\Requestクラスを型ヒントすることで、現在のHTTPリクエストが自動的にルートコールバックに注入されます:

  1. use Illuminate\Http\Request;
  2. Route::get('/users', function (Request $request) {
  3. // ...
  4. });

CSRF保護

  1. ``````php
  2. <form method="POST" action="/profile">
  3. @csrf
  4. ...
  5. </form>
  6. `

リダイレクトルート

別のURIにリダイレクトするルートを定義する場合、Route::redirectメソッドを使用できます。このメソッドは、単純なリダイレクトを実行するために完全なルートやコントローラーを定義する必要がない便利なショートカットを提供します:

  1. Route::redirect('/here', '/there');

デフォルトでは、Route::redirect302ステータスコードを返します。オプションの3番目のパラメータを使用してステータスコードをカスタマイズできます:

  1. Route::redirect('/here', '/there', 301);

また、Route::permanentRedirectメソッドを使用して301ステータスコードを返すこともできます:

  1. Route::permanentRedirect('/here', '/there');

リダイレクトルートでルートパラメータを使用する場合、次のパラメータはLaravelによって予約されており、使用できません:destinationおよびstatus

ビューのルート

ルートがビューを返すだけでよい場合、Route::viewメソッドを使用できます。redirectメソッドと同様に、このメソッドは完全なルートやコントローラーを定義する必要がないシンプルなショートカットを提供します。viewメソッドは、最初の引数としてURIを、2番目の引数としてビュー名を受け取ります。さらに、オプションの3番目の引数としてビューに渡すデータの配列を提供できます:

  1. Route::view('/welcome', 'welcome');
  2. Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

ビューのルートでルートパラメータを使用する場合、次のパラメータはLaravelによって予約されており、使用できません:viewdatastatus、およびheaders

ルートの一覧表示

route:list Artisanコマンドを使用すると、アプリケーションによって定義されたすべてのルートの概要を簡単に提供できます:

  1. php artisan route:list

デフォルトでは、各ルートに割り当てられたルートミドルウェアはroute:list出力に表示されません。ただし、-vオプションをコマンドに追加することで、Laravelにルートミドルウェアとミドルウェアグループ名を表示させることができます:

  1. php artisan route:list -v
  2. # ミドルウェアグループの展開...
  3. php artisan route:list -vv

特定のURIで始まるルートのみを表示するようにLaravelに指示することもできます:

  1. php artisan route:list --path=api

さらに、--except-vendorオプションを提供することで、サードパーティパッケージによって定義されたルートを非表示にするようにLaravelに指示できます。route:listコマンドを実行するとき:

  1. php artisan route:list --except-vendor

同様に、--only-vendorオプションを提供することで、サードパーティパッケージによって定義されたルートのみを表示するようにLaravelに指示できます。route:listコマンドを実行するとき:

  1. php artisan route:list --only-vendor

ルーティングのカスタマイズ

デフォルトでは、アプリケーションのルートはbootstrap/app.phpファイルによって構成され、読み込まれます:

  1. <?php
  2. use Illuminate\Foundation\Application;
  3. return Application::configure(basePath: dirname(__DIR__))
  4. ->withRouting(
  5. web: __DIR__.'/../routes/web.php',
  6. commands: __DIR__.'/../routes/console.php',
  7. health: '/up',
  8. )->create();

ただし、時にはアプリケーションのルートのサブセットを含むまったく新しいファイルを定義したい場合があります。これを実現するには、thenクロージャをwithRoutingメソッドに提供できます。このクロージャ内で、アプリケーションに必要な追加のルートを登録できます:

  1. use Illuminate\Support\Facades\Route;
  2. ->withRouting(
  3. web: __DIR__.'/../routes/web.php',
  4. commands: __DIR__.'/../routes/console.php',
  5. health: '/up',
  6. then: function () {
  7. Route::middleware('api')
  8. ->prefix('webhooks')
  9. ->name('webhooks.')
  10. ->group(base_path('routes/webhooks.php'));
  11. },
  12. )

また、usingクロージャをwithRoutingメソッドに提供することで、ルート登録を完全に制御することもできます。この引数が渡されると、フレームワークによってHTTPルートは登録されず、すべてのルートを手動で登録する責任があります:

  1. use Illuminate\Support\Facades\Route;
  2. ->withRouting(
  3. commands: __DIR__.'/../routes/console.php',
  4. using: function () {
  5. Route::middleware('api')
  6. ->prefix('api')
  7. ->group(base_path('routes/api.php'));
  8. Route::middleware('web')
  9. ->group(base_path('routes/web.php'));
  10. },
  11. )

ルートパラメータ

必須パラメータ

時には、ルート内でURIのセグメントをキャプチャする必要があります。たとえば、URLからユーザーのIDをキャプチャする必要があるかもしれません。その場合は、ルートパラメータを定義することで実現できます:

  1. Route::get('/user/{id}', function (string $id) {
  2. return 'User '.$id;
  3. });

ルートに必要な数だけルートパラメータを定義できます:

  1. Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
  2. // ...
  3. });

ルートパラメータは常に{}ブレース内に囲まれ、アルファベット文字で構成される必要があります。アンダースコア(_)もルートパラメータ名内で許可されます。ルートパラメータは、その順序に基づいてルートコールバック/コントローラーに注入されます - ルートコールバック/コントローラー引数の名前は重要ではありません。

パラメータと依存性注入

ルートに依存関係があり、Laravelのサービスコンテナが自動的にルートのコールバックに注入することを希望する場合、依存関係の後にルートパラメータをリストする必要があります:

  1. use Illuminate\Http\Request;
  2. Route::get('/user/{id}', function (Request $request, string $id) {
  3. return 'User '.$id;
  4. });

オプションのパラメータ

時には、URIに常に存在しない可能性のあるルートパラメータを指定する必要があります。その場合は、パラメータ名の後に?マークを置くことで実現できます。ルートの対応する変数にデフォルト値を設定することを忘れないでください:

  1. Route::get('/user/{name?}', function (?string $name = null) {
  2. return $name;
  3. });
  4. Route::get('/user/{name?}', function (?string $name = 'John') {
  5. return $name;
  6. });

正規表現制約

ルートインスタンスのwhereメソッドを使用して、ルートパラメータの形式を制約できます。whereメソッドは、パラメータの名前と、パラメータが制約される方法を定義する正規表現を受け取ります:

  1. Route::get('/user/{name}', function (string $name) {
  2. // ...
  3. })->where('name', '[A-Za-z]+');
  4. Route::get('/user/{id}', function (string $id) {
  5. // ...
  6. })->where('id', '[0-9]+');
  7. Route::get('/user/{id}/{name}', function (string $id, string $name) {
  8. // ...
  9. })->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

便利なことに、一般的に使用される正規表現パターンには、ルートにパターン制約を迅速に追加できるヘルパーメソッドがあります:

  1. Route::get('/user/{id}/{name}', function (string $id, string $name) {
  2. // ...
  3. })->whereNumber('id')->whereAlpha('name');
  4. Route::get('/user/{name}', function (string $name) {
  5. // ...
  6. })->whereAlphaNumeric('name');
  7. Route::get('/user/{id}', function (string $id) {
  8. // ...
  9. })->whereUuid('id');
  10. Route::get('/user/{id}', function (string $id) {
  11. // ...
  12. })->whereUlid('id');
  13. Route::get('/category/{category}', function (string $category) {
  14. // ...
  15. })->whereIn('category', ['movie', 'song', 'painting']);
  16. Route::get('/category/{category}', function (string $category) {
  17. // ...
  18. })->whereIn('category', CategoryEnum::cases());

受信リクエストがルートパターン制約に一致しない場合、404 HTTPレスポンスが返されます。

グローバル制約

ルートパラメータが常に特定の正規表現によって制約されるようにしたい場合、patternメソッドを使用できます。これらのパターンは、アプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッドで定義する必要があります:

  1. use Illuminate\Support\Facades\Route;
  2. /**
  3. * Bootstrap any application services.
  4. */
  5. public function boot(): void
  6. {
  7. Route::pattern('id', '[0-9]+');
  8. }

パターンが定義されると、それは自動的にそのパラメータ名を使用するすべてのルートに適用されます:

  1. Route::get('/user/{id}', function (string $id) {
  2. // Only executed if {id} is numeric...
  3. });

エンコードされたフォワードスラッシュ

Laravelのルーティングコンポーネントは、ルートパラメータの値内に/以外のすべての文字を含むことを許可します。プレースホルダーの一部として/を明示的に許可する必要があります。where条件の正規表現を使用します:

  1. Route::get('/search/{search}', function (string $search) {
  2. return $search;
  3. })->where('search', '.*');

エンコードされたフォワードスラッシュは、最後のルートセグメント内でのみサポートされます。

名前付きルート

名前付きルートは、特定のルートのURLやリダイレクトを便利に生成することを可能にします。ルート定義にnameメソッドをチェーンすることで、ルートに名前を指定できます:

  1. Route::get('/user/profile', function () {
  2. // ...
  3. })->name('profile');

コントローラーアクションのルート名を指定することもできます:

  1. Route::get(
  2. '/user/profile',
  3. [UserProfileController::class, 'show']
  4. )->name('profile');

ルート名は常に一意である必要があります。

名前付きルートへのURL生成

特定のルートに名前を付けたら、Laravelのrouteおよびredirectヘルパー関数を使用してURLやリダイレクトを生成する際にそのルートの名前を使用できます:

  1. // Generating URLs...
  2. $url = route('profile');
  3. // Generating Redirects...
  4. return redirect()->route('profile');
  5. return to_route('profile');

名前付きルートがパラメータを定義している場合、route関数の2番目の引数としてパラメータを渡すことができます。指定されたパラメータは、生成されたURLの正しい位置に自動的に挿入されます:

  1. Route::get('/user/{id}/profile', function (string $id) {
  2. // ...
  3. })->name('profile');
  4. $url = route('profile', ['id' => 1]);

配列に追加のパラメータを渡すと、それらのキー/値ペアは生成されたURLのクエリ文字列に自動的に追加されます:

  1. Route::get('/user/{id}/profile', function (string $id) {
  2. // ...
  3. })->name('profile');
  4. $url = route('profile', ['id' => 1, 'photos' => 'yes']);
  5. // /user/1/profile?photos=yes

時には、現在のロケールなどのURLパラメータのリクエスト全体に対するデフォルト値を指定したい場合があります。これを実現するには、URL::defaultsメソッドを使用できます。

現在のルートの検査

現在のリクエストが特定の名前付きルートにルーティングされたかどうかを判断したい場合、ルートインスタンスのnamedメソッドを使用できます。たとえば、ルートミドルウェアから現在のルート名を確認できます:

  1. use Closure;
  2. use Illuminate\Http\Request;
  3. use Symfony\Component\HttpFoundation\Response;
  4. /**
  5. * Handle an incoming request.
  6. *
  7. * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
  8. */
  9. public function handle(Request $request, Closure $next): Response
  10. {
  11. if ($request->route()->named('profile')) {
  12. // ...
  13. }
  14. return $next($request);
  15. }

ルートグループ

ルートグループを使用すると、多くのルートにわたってミドルウェアなどのルート属性を共有できます。各個別のルートでそれらの属性を定義する必要はありません。

ネストされたグループは、親グループと属性を「マージ」しようとします。ミドルウェアとwhere条件はマージされ、名前とプレフィックスは追加されます。名前空間の区切り文字とURIプレフィックス内のスラッシュは、適切な場所に自動的に追加されます。

ミドルウェア

ミドルウェアをグループ内のすべてのルートに割り当てるには、グループを定義する前にmiddlewareメソッドを使用できます。ミドルウェアは、配列にリストされた順序で実行されます:

  1. Route::middleware(['first', 'second'])->group(function () {
  2. Route::get('/', function () {
  3. // Uses first & second middleware...
  4. });
  5. Route::get('/user/profile', function () {
  6. // Uses first & second middleware...
  7. });
  8. });

コントローラー

ルートのグループがすべて同じコントローラーを利用する場合、controllerメソッドを使用して、グループ内のすべてのルートの共通コントローラーを定義できます。次に、ルートを定義する際には、呼び出すコントローラーメソッドを指定するだけで済みます:

  1. use App\Http\Controllers\OrderController;
  2. Route::controller(OrderController::class)->group(function () {
  3. Route::get('/orders/{id}', 'show');
  4. Route::post('/orders', 'store');
  5. });

サブドメインルーティング

ルートグループは、サブドメインルーティングを処理するためにも使用できます。サブドメインは、ルートURIと同様にルートパラメータを割り当てることができ、ルートやコントローラーで使用するためにサブドメインの一部をキャプチャできます。サブドメインは、グループを定義する前にdomainメソッドを呼び出すことで指定できます:

  1. Route::domain('{account}.example.com')->group(function () {
  2. Route::get('/user/{id}', function (string $account, string $id) {
  3. // ...
  4. });
  5. });

サブドメインルートが到達可能であることを確認するために、ルートドメインルートを登録する前にサブドメインルートを登録する必要があります。これにより、同じURIパスを持つルートドメインルートがサブドメインルートを上書きするのを防ぎます。

ルートプレフィックス

  1. ``````php
  2. Route::prefix('admin')->group(function () {
  3. Route::get('/users', function () {
  4. // Matches The "/admin/users" URL
  5. });
  6. });
  7. `

ルート名プレフィックス

  1. ``````php
  2. Route::name('admin.')->group(function () {
  3. Route::get('/users', function () {
  4. // Route assigned name "admin.users"...
  5. })->name('users');
  6. });
  7. `

ルートモデルバインディング

ルートまたはコントローラーアクションにモデルIDを注入する場合、そのIDに対応するモデルを取得するためにデータベースをクエリすることがよくあります。Laravelのルートモデルバインディングは、モデルインスタンスをルートに直接自動的に注入する便利な方法を提供します。たとえば、ユーザーのIDを注入する代わりに、指定されたIDに一致するUserモデルインスタンス全体を注入できます。

暗黙のバインディング

Laravelは、型ヒントされた変数名がルートセグメント名と一致するルートまたはコントローラーアクションで定義されたEloquentモデルを自動的に解決します。たとえば:

  1. use App\Models\User;
  2. Route::get('/users/{user}', function (User $user) {
  3. return $user->email;
  4. });

$user変数がApp\Models\User Eloquentモデルとして型ヒントされ、変数名が{user} URIセグメントと一致するため、Laravelは自動的にリクエストURIから対応する値に一致するIDを持つモデルインスタンスを注入します。データベースに一致するモデルインスタンスが見つからない場合、404 HTTPレスポンスが自動的に生成されます。

もちろん、コントローラーメソッドを使用する場合も暗黙のバインディングは可能です。再度、{user} URIセグメントが$user変数と一致し、App\Models\User型ヒントを含むコントローラー内で:

  1. use App\Http\Controllers\UserController;
  2. use App\Models\User;
  3. // Route definition...
  4. Route::get('/users/{user}', [UserController::class, 'show']);
  5. // Controller method definition...
  6. public function show(User $user)
  7. {
  8. return view('user.profile', ['user' => $user]);
  9. }

ソフト削除されたモデル

通常、暗黙のモデルバインディングはソフト削除されたモデルを取得しません。ただし、ルートの定義にwithTrashedメソッドをチェーンすることで、暗黙のバインディングにこれらのモデルを取得させることができます:

  1. use App\Models\User;
  2. Route::get('/users/{user}', function (User $user) {
  3. return $user->email;
  4. })->withTrashed();

キーのカスタマイズ

時には、id以外の列を使用してEloquentモデルを解決したい場合があります。その場合は、ルートパラメータ定義で列を指定できます:

  1. use App\Models\Post;
  2. Route::get('/posts/{post:slug}', function (Post $post) {
  3. return $post;
  4. });

特定のモデルクラスを取得する際に、常にid以外のデータベース列を使用するようにモデルバインディングを設定したい場合は、EloquentモデルのgetRouteKeyNameメソッドをオーバーライドできます:

  1. /**
  2. * Get the route key for the model.
  3. */
  4. public function getRouteKeyName(): string
  5. {
  6. return 'slug';
  7. }

カスタムキーとスコーピング

単一のルート定義で複数のEloquentモデルを暗黙的にバインディングする場合、前のEloquentモデルの子である必要があるように2番目のEloquentモデルをスコープしたい場合があります。たとえば、特定のユーザーのスラッグによってブログ投稿を取得するこのルート定義を考えてみてください:

  1. use App\Models\Post;
  2. use App\Models\User;
  3. Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
  4. return $post;
  5. });

カスタムキーの暗黙のバインディングをネストされたルートパラメータとして使用する場合、Laravelは自動的に親の関係名を推測するための慣例を使用して、ネストされたモデルを親によって取得するためのクエリをスコープします。この場合、Userモデルには、posts(ルートパラメータ名の複数形)という名前の関係があると仮定されます。Postモデルを取得するために使用できます。

必要に応じて、カスタムキーが提供されていない場合でも、Laravelに「子」バインディングをスコープするように指示できます。これを実現するには、ルートを定義する際にscopeBindingsメソッドを呼び出すことができます:

  1. use App\Models\Post;
  2. use App\Models\User;
  3. Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
  4. return $post;
  5. })->scopeBindings();

また、ルート定義のグループ全体にスコープバインディングを使用するように指示できます:

  1. Route::scopeBindings()->group(function () {
  2. Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
  3. return $post;
  4. });
  5. });

同様に、withoutScopedBindingsメソッドを呼び出すことで、バインディングをスコープしないようにLaravelに明示的に指示できます:

  1. Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
  2. return $post;
  3. })->withoutScopedBindings();

見つからないモデルの動作のカスタマイズ

通常、暗黙的にバインディングされたモデルが見つからない場合、404 HTTPレスポンスが生成されます。ただし、ルートを定義する際にmissingメソッドを呼び出すことで、この動作をカスタマイズできます。missingメソッドは、暗黙的にバインディングされたモデルが見つからない場合に呼び出されるクロージャを受け取ります:

  1. use App\Http\Controllers\LocationsController;
  2. use Illuminate\Http\Request;
  3. use Illuminate\Support\Facades\Redirect;
  4. Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
  5. ->name('locations.view')
  6. ->missing(function (Request $request) {
  7. return Redirect::route('locations.index');
  8. });

暗黙のEnumバインディング

PHP 8.1はEnumsのサポートを導入しました。この機能を補完するために、Laravelはルート定義でバックエンドEnumを型ヒントすることを許可し、そのルートセグメントが有効なEnum値に対応する場合にのみルートを呼び出します。そうでない場合、404 HTTPレスポンスが自動的に返されます。たとえば、次のEnumを考えてみてください:

  1. <?php
  2. namespace App\Enums;
  3. enum Category: string
  4. {
  5. case Fruits = 'fruits';
  6. case People = 'people';
  7. }

{category}ルートセグメントがfruitsまたはpeopleの場合にのみ呼び出されるルートを定義できます。そうでない場合、Laravelは404 HTTPレスポンスを返します:

  1. use App\Enums\Category;
  2. use Illuminate\Support\Facades\Route;
  3. Route::get('/categories/{category}', function (Category $category) {
  4. return $category->value;
  5. });

明示的バインディング

モデルバインディングを使用するために、Laravelの暗黙的な慣習に基づくモデル解決を使用する必要はありません。ルートパラメータがモデルにどのように対応するかを明示的に定義することもできます。明示的なバインディングを登録するには、ルーターのmodelメソッドを使用して、特定のパラメータのクラスを指定します。bootクラスのAppServiceProviderメソッドの最初に明示的なモデルバインディングを定義する必要があります:

  1. use App\Models\User;
  2. use Illuminate\Support\Facades\Route;
  3. /**
  4. * Bootstrap any application services.
  5. */
  6. public function boot(): void
  7. {
  8. Route::model('user', User::class);
  9. }

次に、{user}パラメータを含むルートを定義します:

  1. use App\Models\User;
  2. Route::get('/users/{user}', function (User $user) {
  3. // ...
  4. });

すべての{user}パラメータがApp\Models\Userモデルにバインドされているため、そのクラスのインスタンスがルートに注入されます。たとえば、users/1へのリクエストは、IDが1のデータベースからUserインスタンスを注入します。

データベースに一致するモデルインスタンスが見つからない場合、404 HTTPレスポンスが自動的に生成されます。

解決ロジックのカスタマイズ

独自のモデルバインディング解決ロジックを定義したい場合、Route::bindメソッドを使用できます。bindメソッドに渡すクロージャは、URIセグメントの値を受け取り、ルートに注入されるべきクラスのインスタンスを返す必要があります。このカスタマイズは、アプリケーションのAppServiceProviderメソッド内で行う必要があります:

  1. use App\Models\User;
  2. use Illuminate\Support\Facades\Route;
  3. /**
  4. * Bootstrap any application services.
  5. */
  6. public function boot(): void
  7. {
  8. Route::bind('user', function (string $value) {
  9. return User::where('name', $value)->firstOrFail();
  10. });
  11. }

または、EloquentモデルのresolveRouteBindingメソッドをオーバーライドすることもできます。このメソッドは、URIセグメントの値を受け取り、ルートに注入されるべきクラスのインスタンスを返す必要があります:

  1. /**
  2. * Retrieve the model for a bound value.
  3. *
  4. * @param mixed $value
  5. * @param string|null $field
  6. * @return \Illuminate\Database\Eloquent\Model|null
  7. */
  8. public function resolveRouteBinding($value, $field = null)
  9. {
  10. return $this->where('name', $value)->firstOrFail();
  11. }

ルートが暗黙のバインディングスコーピングを利用している場合、resolveChildRouteBindingメソッドは親モデルの子バインディングを解決するために使用されます:

  1. /**
  2. * Retrieve the child model for a bound value.
  3. *
  4. * @param string $childType
  5. * @param mixed $value
  6. * @param string|null $field
  7. * @return \Illuminate\Database\Eloquent\Model|null
  8. */
  9. public function resolveChildRouteBinding($childType, $value, $field)
  10. {
  11. return parent::resolveChildRouteBinding($childType, $value, $field);
  12. }

フォールバックルート

  1. ``````php
  2. Route::fallback(function () {
  3. // ...
  4. });
  5. `

フォールバックルートは、アプリケーションによって登録される最後のルートである必要があります。

レート制限

レートリミッターの定義

Laravelには、特定のルートまたはルートグループのトラフィック量を制限するために利用できる強力でカスタマイズ可能なレート制限サービスが含まれています。始めるには、アプリケーションのニーズに合ったレートリミッターの設定を定義する必要があります。

レートリミッターは、アプリケーションのApp\Providers\AppServiceProviderクラスのbootメソッド内で定義できます:

  1. use Illuminate\Cache\RateLimiting\Limit;
  2. use Illuminate\Http\Request;
  3. use Illuminate\Support\Facades\RateLimiter;
  4. /**
  5. * Bootstrap any application services.
  6. */
  7. protected function boot(): void
  8. {
  9. RateLimiter::for('api', function (Request $request) {
  10. return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
  11. });
  12. }

レートリミッターは、RateLimiterファサードのforメソッドを使用して定義されます。forメソッドは、レートリミッター名と、レートリミッターに割り当てられるルートに適用される制限設定を返すクロージャを受け取ります。制限設定は、Illuminate\Cache\RateLimiting\Limitクラスのインスタンスです。このクラスには、制限を迅速に定義できる便利な「ビルダー」メソッドが含まれています。レートリミッター名は、任意の文字列を使用できます:

  1. use Illuminate\Cache\RateLimiting\Limit;
  2. use Illuminate\Http\Request;
  3. use Illuminate\Support\Facades\RateLimiter;
  4. /**
  5. * Bootstrap any application services.
  6. */
  7. protected function boot(): void
  8. {
  9. RateLimiter::for('global', function (Request $request) {
  10. return Limit::perMinute(1000);
  11. });
  12. }

受信リクエストが指定されたレート制限を超えた場合、Laravelによって429 HTTPステータスコードのレスポンスが自動的に返されます。レート制限によって返されるレスポンスを定義したい場合は、responseメソッドを使用できます:

  1. RateLimiter::for('global', function (Request $request) {
  2. return Limit::perMinute(1000)->response(function (Request $request, array $headers) {
  3. return response('Custom response...', 429, $headers);
  4. });
  5. });

レートリミッターコールバックは受信HTTPリクエストインスタンスを受け取るため、受信リクエストや認証されたユーザーに基づいて適切なレート制限を動的に構築できます:

  1. RateLimiter::for('uploads', function (Request $request) {
  2. return $request->user()->vipCustomer()
  3. ? Limit::none()
  4. : Limit::perMinute(100);
  5. });

レート制限のセグメンテーション

時には、任意の値によってレート制限をセグメント化したい場合があります。たとえば、ユーザーが特定のルートに対してIPアドレスごとに1分間に100回アクセスできるようにしたい場合があります。これを実現するには、レート制限を構築する際にbyメソッドを使用できます:

  1. RateLimiter::for('uploads', function (Request $request) {
  2. return $request->user()->vipCustomer()
  3. ? Limit::none()
  4. : Limit::perMinute(100)->by($request->ip());
  5. });

この機能を別の例で示すと、認証されたユーザーIDごとに1分間に100回、またはゲストの場合はIPアドレスごとに1分間に10回のアクセスを制限できます:

  1. RateLimiter::for('uploads', function (Request $request) {
  2. return $request->user()
  3. ? Limit::perMinute(100)->by($request->user()->id)
  4. : Limit::perMinute(10)->by($request->ip());
  5. });

複数のレート制限

必要に応じて、特定のレートリミッター設定に対してレート制限の配列を返すことができます。各レート制限は、配列内に配置された順序に基づいてルートに対して評価されます:

  1. RateLimiter::for('login', function (Request $request) {
  2. return [
  3. Limit::perMinute(500),
  4. Limit::perMinute(3)->by($request->input('email')),
  5. ];
  6. });

ルートへのレートリミッターの添付

レートリミッターは、throttle ミドルウェアを使用してルートまたはルートグループに添付できます。スロットルミドルウェアは、ルートに割り当てたいレートリミッターの名前を受け取ります:

  1. Route::middleware(['throttle:uploads'])->group(function () {
  2. Route::post('/audio', function () {
  3. // ...
  4. });
  5. Route::post('/video', function () {
  6. // ...
  7. });
  8. });

Redisによるスロットリング

デフォルトでは、throttleミドルウェアはIlluminate\Routing\Middleware\ThrottleRequestsクラスにマッピングされています。ただし、アプリケーションのキャッシュドライバーとしてRedisを使用している場合、LaravelにRedisを使用してレート制限を管理するように指示したい場合があります。これを実現するには、アプリケーションのbootstrap/app.phpファイル内でthrottleWithRedisメソッドを使用する必要があります。このメソッドは、throttleミドルウェアをIlluminate\Routing\Middleware\ThrottleRequestsWithRedisミドルウェアクラスにマッピングします:

  1. ->withMiddleware(function (Middleware $middleware) {
  2. $middleware->throttleWithRedis();
  3. // ...
  4. })

フォームメソッドの偽装

HTMLフォームは、PUTPATCH、またはDELETEアクションをサポートしていません。したがって、HTMLフォームから呼び出されるPUTPATCH、またはDELETEルートを定義する場合、フォームに隠し_methodフィールドを追加する必要があります。_methodフィールドで送信される値は、HTTPリクエストメソッドとして使用されます:

  1. <form action="/example" method="POST">
  2. <input type="hidden" name="_method" value="PUT">
  3. <input type="hidden" name="_token" value="{{ csrf_token() }}">
  4. </form>

便利なことに、@method Bladeディレクティブを使用して_method入力フィールドを生成できます:

  1. <form action="/example" method="POST">
  2. @method('PUT')
  3. @csrf
  4. </form>

現在のルートへのアクセス

  1. ``````php
  2. use Illuminate\Support\Facades\Route;
  3. $route = Route::current(); // Illuminate\Routing\Route
  4. $name = Route::currentRouteName(); // string
  5. $action = Route::currentRouteAction(); // string
  6. `

ルーターおよびルートクラスで利用可能なすべてのメソッドを確認するには、Routeファサードの基礎クラスおよびRouteインスタンスのAPIドキュメントを参照してください。

クロスオリジンリソース共有 (CORS)

Laravelは、設定した値でCORS OPTIONS HTTPリクエストに自動的に応答できます。OPTIONSリクエストは、アプリケーションのグローバルミドルウェアスタックに自動的に含まれるHandleCors ミドルウェアによって自動的に処理されます。

時には、アプリケーションのCORS設定値をカスタマイズする必要があるかもしれません。その場合は、config:publish Artisanコマンドを使用してcors設定ファイルを公開できます:

  1. php artisan config:publish cors

このコマンドは、アプリケーションのconfigディレクトリ内にcors.php設定ファイルを配置します。

CORSおよびCORSヘッダーに関する詳細は、MDNウェブドキュメントのCORSを参照してください。

ルートキャッシング

アプリケーションを本番環境にデプロイする際は、Laravelのルートキャッシュを活用する必要があります。ルートキャッシュを使用すると、アプリケーションのすべてのルートを登録するのにかかる時間が大幅に短縮されます。ルートキャッシュを生成するには、route:cache Artisanコマンドを実行します:

  1. php artisan route:cache

このコマンドを実行した後、キャッシュされたルートファイルはすべてのリクエストで読み込まれます。新しいルートを追加した場合は、新しいルートキャッシュを生成する必要があります。このため、プロジェクトのデプロイ中にのみroute:cacheコマンドを実行する必要があります。

  1. ``````shell
  2. php artisan route:clear
  3. `