イントロダクションIntroduction
Laravelは、アプリケーションのURLを生成するのに役立つヘルパをいくつか提供しています。これらのヘルパは、主にテンプレートとAPIレスポンスでリンクを構築するとき、またはアプリケーションの別の部分へのリダイレクトレスポンスを生成するときに役立ちます。Laravel provides several helpers to assist you in generating URLs for your application. These helpers are primarily helpful when building links in your templates and API responses, or when generating redirect responses to another part of your application.
基礎The Basics
URLの生成Generating URLs
url
ヘルパは、アプリケーションの任意のURLを生成するために使用します。生成したURLは、アプリケーションが処理している現在のリクエストのスキーム(HTTPまたはHTTPS)とホストを自動的に使用します。The url
helper may
be used to generate arbitrary URLs for your
application. The generated URL will automatically
use the scheme (HTTP or HTTPS) and host from the
current request being handled by the
application:
$post = App\Models\Post::find(1);
echo url("/posts/{$post->id}");
// http://example.com/posts/1
現在のURLへのアクセスAccessing the Current URL
url
ヘルパにパスを指定しないと、Illuminate\Routing\UrlGenerator
インスタンスが返され、現在のURLに関する情報へアクセスできます。If no path is provided to the
url
helper, an
Illuminate\Routing\UrlGenerator
instance is returned, allowing you to access
information about the current URL:
// クエリ文字列を除いた現在のURL
echo url()->current();
// クエリ文字列を含んだ現在のURL
echo url()->full();
// 直前のリクエストの完全なURL
echo url()->previous();
こうしたメソッドには、URL
ファサードを使用してもアクセスできます。Each of these methods may also be
accessed via the URL
facade[/docs/{{version}}/facades]:
use Illuminate\Support\Facades\URL;
echo URL::current();
名前付きルートのURLURLs for Named Routes
route
ヘルパは、名前付きルートへのURLを生成するためにも使用できます。名前付きルートを使用すると、ルートで定義する実際のURLと結合せずにURLを生成できます。したがって、ルートのURLが変更された場合でも、route
関数の呼び出しを変更する必要はありません。たとえば、アプリケーションに次のように定義されたルートが含まれているとします。The route
helper may
be used to generate URLs to named
routes[/docs/{{version}}/routing#named-routes].
Named routes allow you to generate URLs without
being coupled to the actual URL defined on the
route. Therefore, if the route's URL changes, no
changes need to be made to your calls to the
route
function. For example, imagine
your application contains a route defined like the
following:
Route::get('/post/{post}', function (Post $post) {
// ...
})->name('post.show');
このルートへのURLを生成するには、次のようにroute
ヘルパを使用します。To generate a URL to this route,
you may use the route
helper like
so:
echo route('post.show', ['post' => 1]);
// http://example.com/post/1
もちろん、route
ヘルパを使用して、複数のパラメーターを持つルートのURLを生成することもできます。Of course, the route
helper may also be used to generate URLs for routes
with multiple parameters:
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のクエリ文字列として追加されます。Any additional array elements that do not correspond to the route's definition parameters will be added to the URL's query string:
echo route('post.show', ['post' => 1, 'search' => 'rocket']);
// http://example.com/post/1?search=rocket
EloquentモデルEloquent Models
Eloquentモデルのルートキー(通常は主キー)を使ってURLを生成することが多いでしょう。そのため、パラメータ値としてEloquentモデルを渡せます。route
ヘルパは、モデルのルートキーを自動的に抽出します。You will often be generating URLs
using the route key (typically the primary key) of
Eloquent models[/docs/{{version}}/eloquent].
For this reason, you may pass Eloquent models as
parameter values. The route
helper will
automatically extract the model's route
key:
echo route('post.show', ['post' => $post]);
署名付きURLSigned URLs
Laravelでは名前付きルートに対し、簡単に「署名付きURL」を作成できます。このURLは「署名」ハッシュをクエリ文字列として付加し、作成されてからそのURLが変更されていないかをLaravelで確認できるようにします。署名付きURLは公にアクセスさせるルートではあるが、URL操作に対する保護レイヤが必要な場合とくに便利です。Laravel allows you to easily create "signed" URLs to named routes. These URLs have a "signature" hash appended to the query string which allows Laravel to verify that the URL has not been modified since it was created. Signed URLs are especially useful for routes that are publicly accessible yet need a layer of protection against URL manipulation.
たとえば、公の「購読終了」リンクを顧客へのメールへ用意するために、署名付きURLが使用できます。名前付きルートに対し署名URLを作成するには、URL
ファサードのsignedRoute
メソッドを使用します。For example, you might use signed
URLs to implement a public "unsubscribe"
link that is emailed to your customers. To create a
signed URL to a named route, use the
signedRoute
method of the
URL
facade:
use Illuminate\Support\Facades\URL;
return URL::signedRoute('unsubscribe', ['user' => 1]);
signedRoute
メソッドでabsolute
引数を指定すれば、署名付きURLハッシュからドメインを除外できます。You may exclude the domain from
the signed URL hash by providing the
absolute
argument to the
signedRoute
method:
return URL::signedRoute('unsubscribe', ['user' => 1], absolute: false);
指定する時間が経過すると期限切れになる一時的な署名付きルートURLを生成する場合は、temporarySignedRoute
メソッドを使用します。Laravelが一時的な署名付きルートURLを検証するとき、署名付きURLにエンコードされている有効期限のタイムスタンプが経過していないことを確認します。If you would like to generate a
temporary signed route URL that expires after a
specified amount of time, you may use the
temporarySignedRoute
method. When
Laravel validates a temporary signed route URL, it
will ensure that the expiration timestamp that is
encoded into the signed URL has not
elapsed:
use Illuminate\Support\Facades\URL;
return URL::temporarySignedRoute(
'unsubscribe', now()->addMinutes(30), ['user' => 1]
);
署名付きルートリクエストの検査Validating Signed Route Requests
受信リクエストに有効な署名があるかどうかを確認するには、受信したIlluminate\Http\Request
インスタンスでhasValidSignature
メソッドを呼び出します。To verify that an incoming
request has a valid signature, you should call the
hasValidSignature
method on the
incoming Illuminate\Http\Request
instance:
use Illuminate\Http\Request;
Route::get('/unsubscribe/{user}', function (Request $request) {
if (! $request->hasValidSignature()) {
abort(401);
}
// ...
})->name('unsubscribe');
クライアントサイドのペジネーションなど、アプリケーションのフロントエンドが署名付きURLにデータを追加することを許可する必要が起きる場合があります。そのようなときは、hasValidSignatureWhileIgnoring
メソッドを用いて、署名付きURLを検証する際に無視すべきリクエストクエリパラメータを指定します。パラメータの無視を許すと、誰でもリクエストのそのパラメータを変更できる点に注意してください。Sometimes, you may need to allow
your application's frontend to append data to a
signed URL, such as when performing client-side
pagination. Therefore, you can specify request query
parameters that should be ignored when validating a
signed URL using the
hasValidSignatureWhileIgnoring
method.
Remember, ignoring parameters allows anyone to
modify those parameters on the request:
if (! $request->hasValidSignatureWhileIgnoring(['page', 'order'])) {
abort(401);
}
受信リクエストインスタンスを使って署名付きURLを検証する代わりに、signed
(Illuminate\Routing\Middleware\ValidateSignature
)ミドルウェアをルートへ指定できます。受信クエストが有効な署名を持っていない場合、ミドルウェアは自動的に
403
HTTP レスポンスをします。Instead of validating signed URLs
using the incoming request instance, you may assign
the signed
(Illuminate\Routing\Middleware\ValidateSignature
)
middleware[/docs/{{version}}/middleware] to
the route. If the incoming request does not have a
valid signature, the middleware will automatically
return a 403
HTTP response:
Route::post('/unsubscribe/{user}', function (Request $request) {
// ...
})->name('unsubscribe')->middleware('signed');
署名付きURLがURLハッシュにドメインを含んでいない場合、ミドルウェアでrelative
引数を与える必要があります。If your signed URLs do not
include the domain in the URL hash, you should
provide the relative
argument to the
middleware:
Route::post('/unsubscribe/{user}', function (Request $request) {
// ...
})->name('unsubscribe')->middleware('signed:relative');
無効な署名付きルートのレスポンスResponding to Invalid Signed Routes
有効期限が切れた署名付きURLへ誰かがアクセスすると、403
HTTPステータスコードの一般的なエラーページを表示します。しかし、アプリケーションのbootstrap/app.php
ファイルで、InvalidSignatureException
例外用のカスタム「レンダ」クロージャを定義することで、この動作をカスタマイズできます。When someone visits a signed URL
that has expired, they will receive a generic error
page for the 403
HTTP status code.
However, you can customize this behavior by defining
a custom "render" closure for the
InvalidSignatureException
exception in
your application's bootstrap/app.php
file:
use Illuminate\Routing\Exceptions\InvalidSignatureException;
->withExceptions(function (Exceptions $exceptions) {
$exceptions->render(function (InvalidSignatureException $e) {
return response()->view('error.link-expired', [], 403);
});
})
コントローラアクションのURLURLs for Controller Actions
action
関数は、指定するコントローラアクションに対するURLを生成します。The action
function
generates a URL for the given controller
action:
use App\Http\Controllers\HomeController;
$url = action([HomeController::class, 'index']);
コントローラメソッドがルートパラメータを受け入れる場合、関数の2番目の引数としてルートパラメータの連想配列を渡せます。If the controller method accepts route parameters, you may pass an associative array of route parameters as the second argument to the function:
$url = action([UserController::class, 'profile'], ['id' => 1]);
デフォルト値Default Values
アプリケーションにより、特定のURLパラメータのデフォルト値をリクエスト全体で指定したい場合もあります。たとえば、多くのルートで{locale}
パラメータを定義していると想像してください。For some applications, you may
wish to specify request-wide default values for
certain URL parameters. For example, imagine many of
your routes define a {locale}
parameter:
Route::get('/{locale}/posts', function () {
// ...
})->name('post.index');
毎回route
ヘルパを呼び出すごとに、locale
をいつも指定するのは厄介です。そのため、現在のリクエストの間、常に適用されるこのパラメートのデフォルト値は、URL::defaults
メソッドを使用し定義できます。現在のリクエストでアクセスできるように、ルートミドルウェアから、このメソッドを呼び出したいかと思います。It is cumbersome to always pass
the locale
every time you call the
route
helper. So, you may use the
URL::defaults
method to define a
default value for this parameter that will always be
applied during the current request. You may wish to
call this method from a route
middleware[/docs/{{version}}/middleware#assigning-middleware-to-routes]
so that you have access to the current
request:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
use Symfony\Component\HttpFoundation\Response;
class SetDefaultLocaleForUrls
{
/**
* 受信リクエストの処理
*
* @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
パラメータに対するデフォルト値をセットしたら、route
ヘルパを使いURLを生成する時に、値を渡す必要はもうありません。Once the default value for the
locale
parameter has been set, you are
no longer required to pass its value when generating
URLs via the route
helper.
URLのデフォルトとミドルウェアの優先度URL Defaults and Middleware Priority
URLのデフォルト値を設定すると、Laravelの暗黙のモデル結合の処理と干渉することがあります。そのため、URLのデフォルト値を設定するミドルウェアは、Laravel自身のSubstituteBindings
ミドルウェアよりも先に実行されるように、[優先順位を付ける]必要があります。アプリケーションのbootstrap/app.php
ファイルにあるpriority
ミドルウェアメソッドを使用することで指定できます。Setting URL default values can
interfere with Laravel's handling of implicit model
bindings. Therefore, you should prioritize your
middleware[/docs/{{version}}/middleware#sorting-middleware]
that set URL defaults to be executed before
Laravel's own SubstituteBindings
middleware. You can accomplish this using the
priority
middleware method in your
application's bootstrap/app.php
file:
->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,
]);
})