Laravel 5.5是如何建立響應的?可能很多人不是很清楚,那麼,接下來我將為大家介紹一下關於Laravel 5.5建立一個http響應的方法以及介紹一下其他的響應類型。
建立響應
字串 & 數組
所有的路由和控制器處理完商務邏輯之後都會返回一個發送到使用者瀏覽器的響應,Laravel 提供了多種不同的方式來返迴響應,最基本的響應就是從路由或控制器返回一個簡單的字串,架構會自動將這個字串轉化為一個完整的 HTTP 響應。
Route::get('/', function () { return 'Hello World';});
除了從路由或控制器返回字串之外,還可以返回數組。架構會自動將數組轉化為一個 JSON 響應。
Route::get('/', function () { return [1, 2, 3];});
註:還可以從路由或控制器返回 Eloquent 集合,這也會被自動轉化為 JSON 響應。
Response 對象
通常,我們並不只是從路由簡單返回字串或數組,大多數情況下,都會返回一個完整的 Illuminate\Http\Response 執行個體或視圖。
返回一個完整的 Response 執行個體允許你自訂響應的 HTTP 狀態代碼和頭資訊。Response 執行個體繼承自 Symfony\Component\HttpFoundation\Response 基類,該類提供了一系列方法用於建立 HTTP 響應。
Route::get('/', function () { return response('Hello World', 200) ->header('Content-Type', 'text/plain');});
添加回應標頭
大部分回應程式法都可以以方法鏈的形式調用,從而可以流式構建響應(流介面模式)。例如,在發送響應給使用者前可以使用 header 方法來添加一系列回應標頭。
return response($content) ->header('Content-Type', $type) ->header('X-Header-One', 'Header Value') ->header('X-Header-Two', 'Header Value');
或者你可以使用 withHeaders 方法來指定頭資訊數組添加到響應。
return response($content) ->withHeaders([ 'Content-Type' => $type, 'X-Header-One' => 'Header Value', 'X-Header-Two' => 'Header Value', ]);
添加 Cookie 到響應
使用響應執行個體上的 cookie 方法可以輕鬆添加 Cookie 到響應。例如,你可以使用 cookie 方法產生 Cookie 並將其添加到響應執行個體。
return response($content) ->header('Content-Type', $type) ->cookie('name', 'value', $minutes);
cookie 方法還可以接收更多使用頻率較低的額外選擇性參數,一般來說,這些參數和 PHP 原生提供的 setcookie 方法目的和意義差不多。
->cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly)
此外,還可以使用 Cookie 門面以”隊列”形式將 Cookie 添加到響應。queue 方法接收 Cookie 執行個體或建立 Cookie 所必要的參數作為參數,這些 Cookie 會在響應被發送到瀏覽器之前添加到響應。
Route::get('cookie/response', function() { Cookie::queue(Cookie::make('site', 'www.baidu.com',1)); Cookie::queue('author', 'admin', 1); return response('Hello Laravel', 200) ->header('Content-Type', 'text/plain');});
在瀏覽器中訪問 http://www.adm.devp/cookie/response ,就可以看到這兩個新增的 cookie 。
Cookie 加密
預設情況下,Laravel 架構產生的 Cookie 都經過了加密和簽名,以免在用戶端被篡改。如果你想要讓特定的 Cookie 子集在產生時取消加密,可以通過 app/Http/Middleware 目錄下的中介軟體 App\Http\Middleware\EncryptCookies 提供的 $except 屬性來排除這些 Cookie。
/** * 不需要被加密的cookies名稱 * * @var array */protected $except = [ 'cookie_name',];
重新導向
重新導向響應是 Illuminate\Http\RedirectResponse 類的執行個體,包含了必要的頭資訊將使用者重新導向到另一個 URL,有很多方式來產生 RedirectResponse 執行個體,最簡單的方法就是使用全域輔助函數 redirect。
Route::get('dashboard', function () { return redirect('home/dashboard');});
有時候你想要將使用者重新導向到上一個請求的位置,比如,表單提交後,驗證不通過,你就可以使用輔助函數 back 返回到前一個 URL(由於該功能使用了 Session,使用該方法之前確保相關路由位於 web 中介軟體組或者應用了 Session 中介軟體)。
Route::post('user/profile', function () { // 驗證請求... return back()->withInput();});
重新導向到命名路由
如果調用不帶參數的 redirect 方法,會返回一個 Illuminate\Routing\Redirector 執行個體,然後就可以使用 Redirector 執行個體上的所有方法。
例如,要產生一個 RedirectResponse 到命名路由,可以使用 route 方法。
return redirect()->route('login');
如果路由中有參數,可以將其作為第二個參數傳遞到 route 方法:
// For a route with the following URI: profile/{id}return redirect()->route('profile', ['id'=>1]);
通過 Eloquent 模型填充路由參數
如果要重新導向到帶 ID 參數的路由( Eloquent 模型繫結 ),可以傳遞模型本身,ID 會被自動解析出來。
return redirect()->route('profile', [$user]);
如果你想要自訂這個路由參數中的預設參數名(預設是 id),需要重寫模型執行個體上的 getRouteKey 方法。
/** * Get the value of the model's route key. * * @return mixed */public function getRouteKey(){ return $this->slug;}
重新導向到控制器方法
你還可以產生重新導向到控制器的方法,只需傳遞控制器和方法名到 action 方法即可。記住,你不需要指定控制器的完整命名空間,因為 Laravel 的 RouteServiceProvider 將會自動化佈建預設的控制器命名空間。
return redirect()->action('HomeController@index');
和 route 方法一樣,如果控制器路由要求參數,你可以將參數作為第二個參數傳遞給 action 方法。
return redirect()->action('UserController@profile', ['id'=>1]);
帶一次性 Session 資料的重新導向
重新導向到一個新的 URL 並將資料存放區到一次性 Session 中通常是同時完成的,為了方便,可以建立一個 RedirectResponse 執行個體然後在同一個方法鏈上將資料存放區到 Session,這種方式在 action 之後儲存狀態資訊時特別方便。
Route::post('user/profile', function () { // 更新使用者屬性... return redirect('dashboard')->with('status', 'Profile updated!');});
使用者重新導向到新頁面之後,你可以從 Session 中取出並顯示這些一次性資訊,使用 Blade 文法實現如下:
@if (session('status')) <p class="alert alert-success"> {{ session('status') }} </p>@endif
註:這個一次性體現在第一次從 Session 取出資料之後,這些資料就會被銷毀,不複存在。
其它響應類型
上面我們講了 Response 和 RedirectResponse 兩種響應類型,我們還可以通過輔助函數 response 很方便地產生其他類型的響應執行個體,當無參數調用 response 時會返回 Illuminate\Contracts\Routing\ResponseFactory 契約的一個實現,該契約提供了一些有用的方法來產生各種響應,如視圖響應、JSON 響應、檔案下載、流響應等等。
視圖響應
如果你需要控制響應狀態和回應標頭,並且還需要返回一個視圖作為響應內容,可以使用 view 方法。
return response() ->view('hello', $data, 200) ->header('Content-Type', $type);
當然,如果你不需要傳遞自訂的 HTTP 狀態代碼和頭資訊,只需要簡單使用全域輔助函數 view 即可。
Route::get('view/response', function() { return view('hello');});
註:視圖響應的視圖檔案必須存在,視圖檔案位於 resources/views 目錄中。
JSON響應
json 方法會自動將 Content-Type 頭設定為 application/json,並使用 PHP 函數 json_encode 方法將給定數組轉化為 JSON 格式的資料。
return response()->json([ 'name' => 'Abigail', 'state' => 'CA']);
如果你想要建立一個 JSONP 響應,可以在 json 方法之後調用 withCallback 方法。
return response() ->json(['name' => 'Abigail', 'state' => 'CA']) ->withCallback($request->input('callback'));
或者直接使用 jsonp 方法。
return response() ->jsonp($request->input('callback'), ['name' => 'Abigail', 'state' => 'CA']);
檔案下載
download 方法用於產生強制使用者瀏覽器下載給定路徑檔案的響應。download 方法接受檔案名稱作為第二個參數,該參數決定使用者下載檔案的顯示名稱,你還可以將 HTTP 頭資訊作為第三個參數傳遞到該方法。
return response()->download($pathToFile);return response()->download($pathToFile, $name, $headers);return response()->download($pathToFile)->deleteFileAfterSend(true);
註:管理檔案下載的 Symfony HttpFoundation 類要求被下載檔案有一個 ASCII 檔案名稱,這意味著被下載檔案名稱不能是中文。
Route::get('download/response', function() { return response()->download(storage_path('app/photo/test.jpg'), '測試圖片.jpg');});
檔案響應
file 方法可用於直接在使用者瀏覽器顯示檔案,例片或 PDF,而不需要下載,該方法接收檔案路徑作為第一個參數,頭資訊數組作為第二個參數。
return response()->file($pathToFile);return response()->file($pathToFile, $headers);
響應宏
如果你想要定義一個自訂的可以在多個路由和控制器中複用的響應,可以使用 Response 門面上的 macro 方法。
例如,在某個服務提供者的 boot 方法中編寫代碼如下:
<?phpnamespace App\Providers;use Illuminate\Support\Facades\Response;use Illuminate\Support\ServiceProvider;class ResponseMacroServiceProvider extends ServiceProvider{ /** * Perform post-registration booting of services. * * @return void */ public function boot() { Response::macro('caps', function ($value) { return Response::make(strtoupper($value)); }); }}
macro 方法接收響應名稱作為第一個參數,閉包函數作為第二個參數,響應宏的閉包在 ResponseFactory 實作類別或輔助函數 response 中調用宏名稱的時候被執行。
Route::get('macro/response', function() { return response()->caps('test');});
在瀏覽器中訪問 http://www.adm.devp/macro/response ,輸出入下:
TEST