基本のレスポンス
当然ながらルートやコントローラーは全て、ユーザーのブラウザーへ何らかのレスポンスを返す必要があります。Laravelはレスポンスを返すために様々な手段を用意しています。一番基本的なレスポンスは、ルートかコントローラーから単に文字列を返します。
Route::get('/', function () {
return 'Hello World';
});
指定された文字列は、フレームワークによりHTTPレスポンスへ変換されます。
しかし通常、ほとんどのルートとコントローラーアクションからは、Illuminate\Http\Response
インスタンスか、ビューを返します。Response
インスタンスを返せば、レスポンスのHTTPステータスコードやヘッダーがカスタマイズできます。Response
インスタンスは、Symfony\Component\HttpFoundation\Response
を継承しており、HTTPレスポンスを組み立てるために数多くのメソッドが提供されています。
use Illuminate\Http\Response;
Route::get('home', function () {
return (new Response($content, $status))
->header('Content-Type', $value);
});
response
ヘルパも、便利に使用できます。
Route::get('home', function () {
return response($content, $status)
->header('Content-Type', $value);
});
注目: Responseメソッドの完全なリストは、APIドキュメントと、SymfonyのAPIドキュメントをご覧ください。
ヘッダーの付加
レスポンスを速やかに組み立てられるようにほとんどのレスポンスメソッドは、チェーンとしてつなげられることを覚えておいてください。たとえば、ユーザーにレスポンスを送り返す前に、header
メソッドでいくつかのヘッダーを追加できます。
return response($content)
->header('Content-Type', $type)
->header('X-Header-One', 'Header Value')
->header('X-Header-Two', 'Header Value');
クッキーの付加
withCookie
ヘルパメソッドをレスポンスインスタンスに使えば、簡単にクッキーを付加できます。たとえば、withCookie
メソッドを使いクッキーを作成し、レスポンスインスタンスに付加できます。
return response($content)->header('Content-Type', $type)
->withCookie('name', 'value');
withCookie
メソッドはクッキーのプロパティーをカスタマイズするためのオプション引数を受け付けます。
->withCookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly)
Laravelにより生成されるクッキーは、クライアントにより変更されたり読まれたりされないようにデフォルトで暗号化され、署名されます。アプリケーションで生成する特定のクッキーで暗号化を無効にしたい場合は、App\Http\Middleware\EncryptCookies
ミドルウェアの$except
プロパティで指定してください。
/**
* 暗号化すべきでないクッキーの名前
*
* @var array
*/
protected $except = [
'cookie_name',
];
他のレスポンスタイプ
response
ヘルパは、他のタイプのレスポンスインスタンスを生成するために便利です。response
ヘルパが引数なしで呼び出されると、Illuminate\Contracts\Routing\ResponseFactory
契約が返されます。この契約はレスポンスを生成するための、様々なメソッドを提供しています。
Viewレスポンス
レスポンスのステータスやヘッダーをコントロールしながらも、レスポンス内容としてビューを返す必要がある場合は、view
メソッドを使用してください。
return response()->view('hello', $data)->header('Content-Type', $type);
もちろん、カスタムHTTPステータスコードやヘッダーの指定が不必要であれば、シンプルにグローバルview
ヘルパ関数を使用することもできます。
JSONレスポンス
json
メソッドは自動的にContent-Type
ヘッダーをapplication/json
にセットし、同時に指定された配列をjson_encode
PHP関数によりJSONへ変換します。
return response()->json(['name' => 'Abigail', 'state' => 'CA']);
JSONPレスポンスを生成したい場合は、json
メソッドに追加してsetCallback
を使用してください。
return response()->json(['name' => 'Abigail', 'state' => 'CA'])
->setCallback($request->input('callback'));
Fileダウンロード
download
メソッドは指定したパスのファイルをダウンロードようにブラウザに強要するレスポンスを生成するために使用します。download
メソッドはファイル名を第2引数として受け取り、ユーザーがダウンロードするファイル名になります。第3引数にHTTPヘッダーの配列を渡すこともできます。
return response()->download($pathToFile);
return response()->download($pathToFile, $name, $headers);
注意: ファイルダウンロードを管理しているSymfony HttpFoundationクラスは、ASCIIのダウンロードファイル名を指定するよう要求しています。
リダイレクト
リダイレクトのレスポンスはIlluminate\Http\RedirectResponse
クラスのインスタンスであり、ユーザーを他のURLへリダイレクトさせるために必要なしっかりとしたヘッダーを含んでいます。RedirectResponse
インスタンスを生成するには様々な方法があります。一番簡単な方法は、グローバルなredirect
ヘルパメソッドを使う方法です。
Route::get('dashboard', function () {
return redirect('home/dashboard');
});
たとえばバリデーション失敗時のように、直前のページヘユーザーをリダイレクトさせたい場合も時々あるでしょう。グローバルなback
ヘルパ関数を使ってください。
Route::post('user/profile', function () {
// リクエストのバリデーション…
return back()->withInput();
});
名前付きルートへのリダイレクト
redirect
ヘルパを引数無しで呼ぶと、Illuminate\Routing\Redirector
インスタンスが返され、Redirector
インスタンスのメソッドが呼び出せるようになります。たとえば、名前付きルートに対するRedirectResponse
を生成したい場合は、route
メソッドが使えます。
return redirect()->route('login');
ルートにパラメーターがある場合は、route
メソッドの第2引数として渡してください。
// profile/{id}のルート定義に対するリダイレクト
return redirect()->route('profile', [1]);
Eloquentモデルの"ID"をルートパラメーターとしてリダイレクトする場合は、モデルをそのまま渡してください。IDは自動的にとり出されます。
return redirect()->route('profile', [$user]);
コントローラーアクションへのリダイレクト
コントローラーアクションに対するリダイレクトを生成することもできます。そのためには、コントローラーとアクションの名前をaction
メソッドに渡してください。LaravelのRouteServiceProvider
により、デフォルトのコントローラー名前空間が自動的に設定されるため、コントローラーの完全名前空間名を指定する必要がないことを覚えておいてください。
return redirect()->action('HomeController@index');
もちろん、コントローラールートにパラメーターが必要ならば、action
メソッドの第2引数として渡してください。
return redirect()->action('UserController@profile', [1]);
フラッシュデータを保存するリダイレクト
新しいURLへリダイレクトし、セッションへフラッシュデータを保存するのは、一度にまとめて行われる典型的な作業です。そのため便利なように、RedirectResponse
を生成し、同時に一つのメッソッドをチェーンするだけでセッションへフラッシュデータを保存できます。これは特にアクションの後の状況を説明するメッセージを保存する場合に便利です。
Route::post('user/profile', function () {
// ユーザープロフィールの更新…
return redirect('dashboard')->with('status', 'プロファイル更新!');
});
もちろん、ユーザーを新しいページヘリダイレクトした後、セッションへ保存したフラッシュデータのメッセージを取り出し、表示する必要があります。たとえばBlade記法を使ってみましょう。
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
レスポンスマクロ
いろいろなルートやコントローラーで、再利用するためのカスタムレスポンスを定義したい場合は、Illuminate\Contracts\Routing\ResponseFactory
に実装されているmacro
メソッドを使ってください。
たとえば、サービスプロバイダーのboot
メソッドで定義します。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Routing\ResponseFactory;
class ResponseMacroServiceProvider extends ServiceProvider
{
/**
* サービス初期処理登録後に実行
*
* @param ResponseFactory $factory
* @return void
*/
public function boot(ResponseFactory $factory)
{
$factory->macro('caps', function ($value) use ($factory) {
return $factory->make(strtoupper($value));
});
}
}
macro
メソッドは登録名を第1引数、クロージャーを第2引数に取ります。マクロのクロージャーはResponseFactory
の実装か、response
ヘルパに対し、登録名で呼び出すことで、実行されます。
return response()->caps('foo');