Lang x Lang

URL Generation

Table of Contents

Introduction

Laravel は、 application の URL を生成するのを支援するためのいくつかの helpers を提供しています。これらの helpers は主に、テンプレートや API レスポンスで links を構築したり、 application の別の部分への redirect レスポンスを生成するときに役立ちます。

The Basics

URL の生成

url helper は、あなたの application のための任意の URL を生成するために使用できます。生成された URL は自動的に現在の request が application によって処理されているス key ム(HTTP または HTTPS)とホストを使用します。

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

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

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

query method を使用して、 query string パラメーター付きの URL を生成することができます。

echo url()->query('/posts', ['search' => 'Laravel']);

// https://example.com/posts?search=Laravel

echo url()->query('/posts?sort=latest', ['search' => 'Laravel']);

// http://example.com/posts?sort=latest&search=Laravel

path に既に存在する query string パラメータを提供すると、既存の value が上書きされます:

echo url()->query('/posts?sort=latest', ['sort' => 'oldest']);

// http://example.com/posts?sort=oldest

values の配列も query パラメータとして渡すことができます。これらの values は生成された URL に適切にキー付けされ、エンコードされます:

echo $url = url()->query('/posts', ['columns' => ['title', 'body']]);

// http://example.com/posts?columns%5B0%5D=title&columns%5B1%5D=body

echo urldecode($url);

// http://example.com/posts?columns[0]=title&columns[1]=body

現在の URL へのアクセス

urlヘルパーに対して path が提供されない場合、 Illuminate\Routing\UrlGenerator インスタンスが返され、現在の URL に関する情報にアクセスできます。

// Get the current URL without the query string...
echo url()->current();

// Get the current URL including the query string...
echo url()->full();

// Get the full URL for the previous request...
echo url()->previous();

これらのメソッドはそれぞれ、URL facadeを通じてアクセスすることも可能です:

use Illuminate\Support\Facades\URL;

echo URL::current();

URLs for Named Routes

route helper は、名前付き routesの URL を生成するために使用できます。名前付き routes を使用すると、実際の URL が route 上で定義されているのに連動せずに URL を生成できます。したがって、route の URL が変更されても、route関数への呼び出しに変更を加える必要はありません。例えば、あなたの application には以下のように定義された route が含まれていると想像してみてください:

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

この route への URL を生成するために、以下のように route helper を使用することができます:

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

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

もちろん、routeヘルパーは、 routes の複数のパラメーターに対する 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

ルートの定義パラメータに対応しない追加の array elements は、URL の query string に追加されます。

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

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

Eloquent Models

あなたはしばしば、Eloquent modelsの route キー(通常は primary キー)を使用して URL を生成することがあります。そのため、 Eloquent models をパラメータ values として渡すことができます。routeヘルパーは自動的にモデルの route キーを抽出します。

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

サイン付き URL

Laravel は、署名付きの routes への URL を簡単に作成することができます。これらの URL には hash 形式の署名が query string に追加されており、Laravel がそれが作成されてから URL が変更されていないことを確認することを可能にします。署名付きの URL は、公にアクセス可能でありながら URL の操作に対する保護層が必要な routes に特に有用です。

たとえば、署名付き URL を使用して、お客様に mail で送信される public の unsubscribelink を実装する場合があります。名前付き route への署名付き URL を作成するには、URL facade の signedRoute method を使用してください:

use Illuminate\Support\Facades\URL;

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

signedRoute method にabsolute引数を提供することにより、署名付き URL hash から domain を除外することができます。

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

特定の時間が経過した後に有効期限が切れる一時的な署名付きの route URL を生成したい場合、temporarySignedRoute method を使用することができます。 Laravel が一時的に署名された route URL を確認する際、署名付き URL にエンコードされた有効期限 timestamp がまだ経過していないことを確認します。

use Illuminate\Support\Facades\URL;

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

Validating 署名済み Route リクエストの検証

着信の request が有効な signature を持っていることを確認するには、着信のIlluminate\Http\Request インスタンスにhasValidSignature method を呼び出すべきです:

use Illuminate\Http\Request;

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

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

時々、クライアント側の pagination を実行するときなど、アプリケーションのフロントエンドが署名された URL に append data を追加できるようにする必要があるかもしれません。したがって、署名された URL の validating を行う際に無視するべき request query パラメータを hasValidSignatureWhileIgnoring method を使用して指定することができます。覚えておいてください、パラメータを無視すると、誰でもそのパラメータを request 上で変更することができます:

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

受信した request インスタンスを使って validating 署名付き URL を検証する代わりに、signed (Illuminate\Routing\Middleware\ValidateSignature) middleware を route に割り当てることができます。受信した request に有効な signature がない場合、 middleware は自動的に403 HTTP response を返します。

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

もし署名付き URL が URL hash 内に domain を含んでいない場合、relative引数を middleware に提供するべきです:

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

Invalid と署名された Routes への対応

誰かが有効期限が切れた署名付きの URL を訪れると、彼らは一般的な error ページを403の HTTP status コード で受け取ります。しかし、application のbootstrap/app.phpファイルでInvalidSignatureException例外のための custom レンダークロージャを定義することで、この振る舞いをカスタマイズすることができます。

use Illuminate\Routing\Exceptions\InvalidSignatureException;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (InvalidSignatureException $e) {
        return response()->view('error.link-expired', [], 403);
    });
})

URLs for Controller Actions

action関数は、指定された controller action のための URL を生成します:

use App\Http\Controllers\HomeController;

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

もし controller method が route パラメータを受け入れるのであれば、関数の第二引数として route パラメータの連想 array を渡すことができます:

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

Default Values

一部の application では、特定の URL パラメータに対して request 全体の default values を指定したい場合があります。例えば、多くの routes で{locale}パラメータを定義していると想像してみてください:

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

route helper を呼び出すたびに毎回 locale を渡すのは面倒です。したがって、 URL::defaults method を使用して、このパラメーターの default value を定義し、現在の request の間は常に適用できるようにすることができます。現在の request にアクセスできるように、この method をroute middlewareから呼び出すことを検討してみて下さい。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
use Symfony\Component\HttpFoundation\Response;

class SetDefaultLocaleForUrls
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        URL::defaults(['locale' => $request->user()->locale]);

        return $next($request);
    }
}

localeパラメータの defaultvalue が設定されると、routehelper を使用して URL を生成する際に、その value を渡す必要は必須ではなくなります。

URL Defaults と Middleware の優先度

URL default values を設定すると、Laravel の暗黙的な model バインディングの処理に干渉する可能性があります。そのため、SubstituteBindings middleware よりも先に URL defaults を設定するmiddleware を優先させるべきです。これは、アプリケーションのbootstrap/app.phpファイルの中のpriority middleware method を使用して実現できます。

->withMiddleware(function (Middleware $middleware) {
    $middleware->priority([
        \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
        \Illuminate\Cookie\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
        \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
        \Illuminate\Routing\Middleware\ThrottleRequests::class,
        \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,
        \Illuminate\Session\Middleware\AuthenticateSession::class,
        \App\Http\Middleware\SetDefaultLocaleForUrls::class, // [tl! add]
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \Illuminate\Auth\Middleware\Authorize::class,
    ]);
})

当社サイトでは、Cookie を使用しています。各規約をご確認の上ご利用ください:
Cookie Policy, Privacy Policy および Terms of Use