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