Laravel 9.x URL生成

イントロダクション

Laravelは、アプリケーションのURLを生成するのに役立つヘルパをいくつか提供しています。これらのヘルパは、主にテンプレートとAPIレスポンスでリンクを構築するとき、またはアプリケーションの別の部分へのリダイレクトレスポンスを生成するときに役立ちます。

基礎

URLの生成

urlヘルパは、アプリケーションの任意のURLを生成するために使用します。生成したURLは、アプリケーションが処理している現在のリクエストのスキーム(HTTPまたはHTTPS)とホストを自動的に使用します。

$post = App\Models\Post::find(1);

echo url("/posts/{$post->id}");

// http://example.com/posts/1

現在のURLへのアクセス

urlヘルパにパスを指定しないと、Illuminate\Routing\UrlGeneratorインスタンスが返され、現在のURLに関する情報へアクセスできます。

// クエリ文字列を除いた現在のURL
echo url()->current();

// クエリ文字列を含んだ現在のURL
echo url()->full();

// 直前のリクエストの完全なURL
echo url()->previous();

こうしたメソッドには、URLファサードを使用してもアクセスできます。

use Illuminate\Support\Facades\URL;

echo URL::current();

名前付きルートのURL

routeヘルパは、名前付きルートへのURLを生成するためにも使用できます。名前付きルートを使用すると、ルートで定義する実際のURLと結合せずにURLを生成できます。したがって、ルートのURLが変更された場合でも、route関数の呼び出しを変更する必要はありません。たとえば、アプリケーションに次のように定義されたルートが含まれているとします。

Route::get('/post/{post}', function (Post $post) {
    //
})->name('post.show');

このルートへのURLを生成するには、次のようにrouteヘルパを使用します。

echo route('post.show', ['post' => 1]);

// http://example.com/post/1

もちろん、routeヘルパを使用して、複数のパラメーターを持つルートのURLを生成することもできます。

Route::get('/post/{post}/comment/{comment}', function (Post $post, Comment $comment) {
    //
})->name('comment.show');

echo route('comment.show', ['post' => 1, 'comment' => 3]);

// http://example.com/post/1/comment/3

ルートの定義パラメータに対応しない過剰な配列要素は、URLのクエリ文字列として追加されます。

echo route('post.show', ['post' => 1, 'search' => 'rocket']);

// http://example.com/post/1?search=rocket

Eloquentモデル

Eloquentモデルのルートキー(通常は主キー)を使ってURLを生成することが多いでしょう。そのため、パラメータ値としてEloquentモデルを渡せます。routeヘルパは、モデルのルートキーを自動的に抽出します。

echo route('post.show', ['post' => $post]);

署名付きURL

Laravelでは名前付きルートに対し、簡単に「署名付きURL」を作成できます。このURLは「署名」ハッシュをクエリ文字列として付加し、作成されてからそのURLが変更されていないかをLaravelで確認できるようにします。署名付きURLは公にアクセスさせるルートではあるが、URL操作に対する保護レイヤが必要な場合とくに便利です。

たとえば、公の「購読終了」リンクを顧客へのメールへ用意するために、署名付きURLが使用できます。名前付きルートに対し署名URLを作成するには、URLファサードのsignedRouteメソッドを使用します。

use Illuminate\Support\Facades\URL;

return URL::signedRoute('unsubscribe', ['user' => 1]);

指定する時間が経過すると期限切れになる一時的な署名付きルートURLを生成する場合は、temporarySignedRouteメソッドを使用します。Laravelが一時的な署名付きルートURLを検証するとき、署名付きURLにエンコードされている有効期限のタイムスタンプが経過していないことを確認します。

use Illuminate\Support\Facades\URL;

return URL::temporarySignedRoute(
    'unsubscribe', now()->addMinutes(30), ['user' => 1]
);

署名付きルートリクエストの検査

受信したリクエストに有効な署名があるかどうかを確認するには、受信したIlluminate\Http\RequestインスタンスでhasValidSignatureメソッドを呼び出します。

use Illuminate\Http\Request;

Route::get('/unsubscribe/{user}', function (Request $request) {
    if (! $request->hasValidSignature()) {
        abort(401);
    }

    // ...
})->name('unsubscribe');

クライアントサイドのペジネーションなど、アプリケーションのフロントエンドが署名付きURLにデータを追加することを許可する必要が起きる場合があります。そのようなときは、hasValidSignatureWhileIgnoringメソッドを用いて、署名付きURLを検証する際に無視すべきリクエストクエリパラメータを指定します。パラメータの無視を許すと、誰でもリクエストのそのパラメータを変更できる点に注意してください。

if (! $request->hasValidSignatureWhileIgnoring(['page', 'order'])) {
    abort(401);
}

受信リクエストのインスタンスを使用して署名付きURLをバリデーションする代わりに、Illuminate\Routing\Middleware\ValidateSignatureミドルウェアをルートへ指定できます。存在しない場合は、HTTPカーネルのrouteMiddleware配列のキーとして、このミドルウェアを割り当てる必要があります。

/**
 * アプリケーションルートのミドルウェア
 *
 * これらのミドルウェアはグループ、もしくは個別に指定される。
 *
 * @var array
 */
protected $routeMiddleware = [
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
];

ミドルウェアをカーネルに登録したら、それをルートにアタッチできます。受信リクエストに有効な署名がない場合、ミドルウェアは自動的に403HTTPレスポンスを返します。

Route::post('/unsubscribe/{user}', function (Request $request) {
    // ...
})->name('unsubscribe')->middleware('signed');

無効な署名付きルートのレスポンス

期限切れになった署名付きURLを訪問すると、403 HTTPステータスコードの汎用エラーページが表示されます。ただし、例外ハンドラでInvalidSignatureException例外のカスタム"renderable"クロージャを定義することにより、この動作をカスタマイズできます。このクロージャはHTTPレスポンスを返す必要があります。

use Illuminate\Routing\Exceptions\InvalidSignatureException;

/**
 * アプリケーションの例外処理コールバックの登録
 *
 * @return void
 */
public function register()
{
    $this->renderable(function (InvalidSignatureException $e) {
        return response()->view('error.link-expired', [], 403);
    });
}

コントローラアクションのURL

action関数は、指定するコントローラアクションに対するURLを生成します。

use App\Http\Controllers\HomeController;

$url = action([HomeController::class, 'index']);

コントローラメソッドがルートパラメータを受け入れる場合、関数の2番目の引数としてルートパラメータの連想配列を渡せます。

$url = action([UserController::class, 'profile'], ['id' => 1]);

デフォルト値

アプリケーションにより、特定のURLパラメータのデフォルト値をリクエスト全体で指定したい場合もあります。たとえば、多くのルートで{locale}パラメータを定義していると想像してください。

Route::get('/{locale}/posts', function () {
    //
})->name('post.index');

毎回routeヘルパを呼び出すごとに、localeをいつも指定するのは厄介です。そのため、現在のリクエストの間、常に適用されるこのパラメートのデフォルト値は、URL::defaultsメソッドを使用し定義できます。現在のリクエストでアクセスできるように、ルートミドルウェアから、このメソッドを呼び出したいかと思います。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\URL;

class SetDefaultLocaleForUrls
{
    /**
     * 受信リクエストの処理
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return \Illuminate\Http\Response
     */
    public function handle($request, Closure $next)
    {
        URL::defaults(['locale' => $request->user()->locale]);

        return $next($request);
    }
}

一度localeパラメータに対するデフォルト値をセットしたら、routeヘルパを使いURLを生成する時に、値を渡す必要はもうありません。

URLのデフォルトとミドルウェアの優先度

URLのデフォルト値を設定すると、Laravelの暗黙的なモデルバインディングの処理を妨げる可能性があります。したがって、URLのデフォルトをLaravel自身のSubstituteBindingsミドルウェアの前に実行するよう設定するため、ミドルウェアの優先度を設定する必要があります。それには、アプリケーションのHTTPカーネルの$middlewarePriorityプロパティ内にあるSubstituteBindingsミドルウェアの前にミドルウェアを確実に設置してください。

$middlewarePriorityプロパティはIlluminate\Foundation\Http\Kernelベースクラスで定義されています。変更するにはその定義をこのクラスからコピーし、アプリケーションのHTTPカーネルでオーバーライトしてください。

/**
 * ミドルウェアの優先リスト
 *
 * この指定により、グローバルではないミドルウェアは常にこの順番になります。
 *
 * @var array
 */
protected $middlewarePriority = [
    // ...
     \App\Http\Middleware\SetDefaultLocaleForUrls::class,
     \Illuminate\Routing\Middleware\SubstituteBindings::class,
     // ...
];

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる