URL
URL
生成 URL
簡(jiǎn)介
Laravel 提供了幾個(gè)輔助函數(shù)來(lái)為應(yīng)用程序生成 URL。主要用于在模板和 API 響應(yīng)中構(gòu)建 URL 或者在應(yīng)用程序的其它部分生成重定向響應(yīng)。
基礎(chǔ)
生成基礎(chǔ) URL
輔助函數(shù) url
可以用于應(yīng)用的任何一個(gè) URL。生成的 URL 將自動(dòng)使用當(dāng)前請(qǐng)求中的方案( HTTP 或 HTTPS )和主機(jī):
$post = App\Post::find(1); echo url("/posts/{$post->id}"); // http://example.com/posts/1
訪(fǎng)問(wèn)當(dāng)前 URL
如果沒(méi)有給輔助函數(shù) url
提供路徑,則會(huì)返回一個(gè) Illuminate\Routing\UrlGenerator
實(shí)例,來(lái)允許你訪(fǎng)問(wèn)有關(guān)當(dāng)前 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();
上面的這些方法都可以通過(guò) URL
facade 訪(fǎng)問(wèn):
use Illuminate\Support\Facades\URL; echo URL::current();
命名路由的 URL
輔助函數(shù) route
可以用于為指定路由生成 URL。命名路由生成的 URL 不與路由上定義的 URL 相耦合。因此,就算路由的 URL 有任何更改,都不需要對(duì) route
函數(shù)調(diào)用進(jìn)行任何更改。例如,假設(shè)你的應(yīng)用程序包含以下路由:
Route::get('/post/{post}', function () { // })->name('post.show');
要生成此路由的 URL,可以像這樣使用輔助函數(shù) route
:
echo route('post.show', ['post' => 1]); // http://example.com/post/1
您通常會(huì)使用 Eloquent 模型 的主鍵生成 URL。因此,您可以將 Eloquent 模型作為參數(shù)值傳遞。 route
輔助函數(shù)將自動(dòng)提取模型的主鍵:
echo route('post.show', ['post' => $post]);
輔助函數(shù) route
也可用于為具有多個(gè)參數(shù)的路由生成 URL:
Route::get('/post/{post}/comment/{comment}', function () { // })->name('comment.show'); echo route('comment.show', ['post' => 1, 'comment' => 3]); // http://example.com/post/1/comment/3
簽名 URL
Laravel 允許你輕松地為命名路徑創(chuàng)建 「簽名」 URL。這些 URL 在查詢(xún)字符串后附加了 「簽名」哈希,允許 Laravel 驗(yàn)證 URL 自創(chuàng)建以來(lái)未被修改過(guò)。簽名 URL 對(duì)于可公開(kāi)訪(fǎng)問(wèn)但需要一層防止 URL 操作的路由特別有用。
例如,你可以使用簽名 URL 來(lái)實(shí)現(xiàn)通過(guò)電子郵件發(fā)送給客戶(hù)的公共 「取消訂閱」鏈接。要?jiǎng)?chuàng)建指向路徑的簽名 URL,請(qǐng)使用 facade 的 signedRoute
方法 URL
:
use Illuminate\Support\Facades\URL;return URL::signedRoute('unsubscribe', ['user' => 1]);
如果要生成過(guò)期的臨時(shí)簽名路由 URL,可以使用以下 temporarySignedRoute
方法:
use Illuminate\Support\Facades\URL;return URL::temporarySignedRoute( 'unsubscribe', now()->addMinutes(30), ['user' => 1] );
驗(yàn)證簽名路由請(qǐng)求
要驗(yàn)證傳入請(qǐng)求是否具有有效簽名,你應(yīng)該調(diào)用 hasValidSignature
傳入的方法 Request
:
use Illuminate\Http\Request; Route::get('/unsubscribe/{user}', function (Request $request) { if (! $request->hasValidSignature()) { abort(401); } // ... })->name('unsubscribe');
或者,你可以將 Illuminate\Routing\Middleware\ValidateSignature
中間件分配給路由。如果它不存在,則應(yīng)該在 HTTP 內(nèi)核的 routeMiddleware
數(shù)組中為此中間件分配一個(gè)鍵:
/** * 應(yīng)用程序的路由中間件 * * 這些中間件可能被分配給組或單獨(dú)使用 * * @var array */ protected $routeMiddleware = [ 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, ];
在內(nèi)核中注冊(cè)中間件后,你可以將其附加到路由中。如果傳入請(qǐng)求沒(méi)有有效簽名,則中間件將自動(dòng)返回 403
錯(cuò)誤響應(yīng):
Route::post('/unsubscribe/{user}', function (Request $request) { // ... })->name('unsubscribe')->middleware('signed');
控制器行為的 URL
action
功能可以為給定的控制器行為生成 URL。這個(gè)功能不需要你傳遞控制器的完整命名空間,但你需要傳遞相對(duì)于命名空間 App\Http\Controllers
的控制器類(lèi)名:
$url = action('HomeController@index');
你還可以使用 “可調(diào)用” 數(shù)組語(yǔ)法引用操作:
use App\Http\Controllers\HomeController; $url = action([HomeController::class, 'index']);
如果控制器方法需要路由參數(shù),那就將它們作為第二個(gè)參數(shù)傳遞給 action
函數(shù):
$url = action('UserController@profile', ['id' => 1]);
默認(rèn)值
對(duì)于某些應(yīng)用程序,你可能希望為某些 URL 參數(shù)的請(qǐng)求范圍指定默認(rèn)值。例如,假設(shè)有些路由定義了 {locale} 參數(shù):
Route::get('/{locale}/posts', function () { //})->name('post.index');
每次都通過(guò) locale
來(lái)調(diào)用輔助函數(shù) route
也是一件很麻煩的事情。因此,使用 URL::defaults
方法定義這個(gè)參數(shù)的默認(rèn)值,可以讓該參數(shù)始終存在當(dāng)前請(qǐng)求中。然后就能從 路由中間件 調(diào)用此方法來(lái)訪(fǎng)問(wèn)當(dāng)前請(qǐng)求:
<?php namespace App\Http\Middleware; use Closure;use Illuminate\Support\Facades\URL; class SetDefaultLocaleForUrls{ public function handle($request, Closure $next) { URL::defaults(['locale' => $request->user()->locale]); return $next($request); } }
一旦設(shè)置了 locale
參數(shù)的默認(rèn)值,您就不再需要通過(guò)輔助函數(shù) route
生成 URL 時(shí)傳遞它的值。