[ Laravel 5.8 文件 ] 基礎元件 —— URL 生成
簡介
Laravel 提供了多個輔助函式來幫助我們在應用中生成 URL。這些函式主要用於在檢視模板和 API 響應中構建連結,或者生成重定向響應。
快速入門
生成 URL
url
輔助函式可用於為應用生成任意 URL,並且生成的 URL 會自動使用當前請求的scheme
(HTTP or HTTPS) 和host
屬性:
$post = App\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 () { // })->name('post.show');
要生成指向該路由的 URL,可以這樣使用route
輔助函式:
echo route('post.show', ['post' => 1]); // 輸出 http://example.com/post/1
通常我們會使用Eloquent 模型的主鍵來生成 URL,因此,可以傳遞 Eloquent 模型作為引數值,route
輔助函式會自動解析模型主鍵值,所以,上述方法還可以這麼呼叫:
echo route('post.show', ['post' => $post]);
route
輔助函式還可以用於為包含多個引數的路由生成對應的 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 允許你輕鬆建立與命名路由對映的「簽名」URL,這些 URL 會將「簽名」雜湊追加到查詢字串後面,以便 Laravel 驗證 URL 在建立之後沒有被篡改。簽名 URL 對於那些可以公開訪問的路由非常有用,因為這相當於對這些 URL 的修改提供了一個保護層。
例如,你可以使用簽名 URL 來實現一個公開的「退訂」郵件連結,要建立這個簽名 URL 對應的命名路由,可以使用URL
門面提供的signedRoute
方法:
use Illuminate\Support\Facades\URL; return URL::signedRoute('unsubscribe', ['user' => 1]);
如果你想要生成一個包含過期時間的臨時簽名 URL,可以使用temporarySignedRoute
方法:
use Illuminate\Support\Facades\URL; return URL::temporarySignedRoute( 'unsubscribe', now()->addMinutes(30), ['user' => 1] );
驗證簽名路由請求
要驗證輸入請求包含有效的簽名,需要呼叫Request
物件上的hasValidSignature
方法:
use Illuminate\Http\Request; Route::get('/unsubscribe/{user}', function (Request $request) { if (! $request->hasValidSignature()) { abort(401); } // ... })->name('unsubscribe');
此外,你還可以分配Illuminate\Routing\Middleware\ValidateSignature
中介軟體到該路由。你可以先將這個中介軟體註冊到$routeMiddleware
:
/** * The application's route middleware. * * These middleware may be assigned to groups or used individually. * * @var array */ protected $routeMiddleware = [ 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, ];
然後將其分配到路由,如果輸入請求未包含有效的簽名,中介軟體會自動返回403
錯誤響應:
Route::post('/unsubscribe/{user}', function (Request $request) { // ... })->name('unsubscribe')->middleware('signed');
控制器動作 URL
action
輔助函式用於為控制器動作生成 URL,和路由中的定義一樣,你不需要傳遞完整的控制器名稱空間,卻而代之地,傳遞相對於App\Http\Controllers
名稱空間的控制器類名即可:
$url = action('HomeController@index');
你還可以通過「可呼叫」陣列語法引用控制器動作:
use App\Http\Controllers\HomeController; $url = action([HomeController::class, 'index']);
如果控制器方法接收路由引數,你可以將其作為第二個引數傳遞給該方法:
$url = action('UserController@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 { public function handle($request, Closure $next) { URL::defaults(['locale' => $request->user()->locale]); return $next($request); } }
一旦設定好locale
引數的預設值之後,就不必在通過route
輔助函式生成 URL 時每次指定傳遞的值了。