基本のレスポンス
当然ながら全てのルートやコントローラーは、ユーザのブラウザーに対し、何らかのレスポンスを返す必要があります。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');
もしくは、withHeaders
メソッドで、レスポンスへ追加したいヘッダの配列を指定します。
return response($content)
->withHeaders([
'Content-Type' => $type,
'X-Header-One' => 'Header Value',
'X-Header-Two' => 'Header Value',
]);
クッキーの付加
cookie
ヘルパメソッドをレスポンスインスタンスに使えば、簡単にクッキーを付加できます。たとえば、cookie
メソッドを使いクッキーを作成し、レスポンスインスタンスに付加できます。
return response($content)
->header('Content-Type', $type)
->cookie('name', 'value');
cookie
メソッドはクッキーのプロパティーをカスタマイズするためのオプション引数を受け付けます。
->cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly)
もしくは、Cookie
ファサードのqueue
メソッドを使い、レスポンスが送られる時点で自動的に付加されるクッキーを作成することもできます。
<?php
namespace App\Http\Controllers;
use Cookie;
use App\Http\Controllers\Controller;
class DashboardController extends Controller
{
/**
* アプリケーションダッシュボードの表示
*
* @return Response
*/
public function index()
{
Cookie::queue('saw_dashboard', true, 15);
return view('dashboard');
}
}
この例の場合、saw_dashboard
クッキーは、意図的にレスポンスインスタンスに添付するようにコードしなくても、レスポンスが返される時点で自動的にそのレスポンスへ追加されます。
クッキーと暗号化
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のダウンロードファイル名を指定するよう要求しています。
Fileレスポンス
file
メソッドは、ダウンロードの代わりに、ブラウザへ画像やPDFのようなファイルを表示するために使用します。このメソッドは第1引数にファイルパス、第2引数にヘッダの配列を指定します。
return response()->file($pathToFile);
return response()->file($pathToFile, $headers);
リダイレクト
リダイレクトのレスポンスはIlluminate\Http\RedirectResponse
クラスのインスタンスであり、ユーザを他のURLへリダイレクトさせるために必要なしっかりとしたヘッダを含んでいます。RedirectResponse
インスタンスを生成するには様々な方法があります。一番簡単な方法は、グローバルなredirect
ヘルパメソッドを使う方法です。
Route::get('dashboard', function () {
return redirect('home/dashboard');
});
例えば送信されたフォーム内容にエラーがある場合など、直前のページヘユーザーをリダイレクトさせたい場合もあります。グローバルなback
ヘルパ関数を使ってください。ただし、back
関数を使用するルートはweb
ミドルウェアグループに属しているか、セッションミドルウェアが適用されることを確認してください。
Route::post('user/profile', function () {
// レスポンスのバリデーション処理…
return back()->withInput();
});
名前付きルートへのリダイレクト
redirect
ヘルパを引数無しで呼ぶと、Illuminate\Routing\Redirector
インスタンスが返され、Redirector
インスタンスのメソッドが呼び出せるようになります。たとえば、名前付きルートに対するRedirectResponse
を生成したい場合は、route
メソッドが使えます。
return redirect()->route('login');
ルートにパラメーターがある場合は、route
メソッドの第2引数として渡してください。
// profile/{id}のURIへのリダイレクト
return redirect()->route('profile', ['id' => 1]);
Eloquentモデルの"ID"をルートパラメーターとしてリダイレクトする場合は、モデルをそのまま渡してください。IDは自動的にとり出されます。
return redirect()->route('profile', [$user]);
コントローラーアクションへのリダイレクト
コントローラーアクションに対するリダイレクトを生成することもできます。そのためには、コントローラーとアクションの名前をaction
メソッドに渡してください。LaravelのRouteServiceProvider
により、デフォルトのコントローラー名前空間が自動的に設定されるため、コントローラーの完全名前空間名を指定する必要がないことを覚えておいてください。
return redirect()->action('HomeController@index');
もちろん、コントローラールートにパラメーターが必要ならば、action
メソッドの第2引数として渡してください。
return redirect()->action('UserController@profile', ['id' => 1]);
フラッシュデータを保存するリダイレクト
新しいURLへリダイレクトし、セッションへフラッシュデータを保存するのは、一度にまとめて行われる典型的な作業です。そのため便利なように、RedirectResponse
を生成し、同時に一つのメッソッドをチェーンするだけでセッションへフラッシュデータを保存できます。これは特にアクションの後の状況を説明するメッセージを保存する場合に便利です。
Route::post('user/profile', function () {
// ユーザプロフィールの更新処理…
return redirect('dashboard')->with('status', 'Profile updated!');
});
もちろん、ユーザを新しいページヘリダイレクトした後、セッションへ保存したフラッシュデータのメッセージを取り出し、表示する必要があります。たとえばBlade記法を使ってみましょう。
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
レスポンスマクロ
いろいろなルートやコントローラーで、再利用するためのカスタムレスポンスを定義したい場合はResponse
ファサード、もしくはIlluminate\Contracts\Routing\ResponseFactory
の実装に対し、macro
メソッドが使用できます。
たとえば、サービスプロバイダのboot
メソッドで定義します。
<?php
namespace App\Providers;
use Response;
use Illuminate\Support\ServiceProvider;
class ResponseMacroServiceProvider extends ServiceProvider
{
/**
* アプリケーションのレスポンスマクロ登録
*
* @return void
*/
public function boot()
{
Response::macro('caps', function ($value) {
return Response::make(strtoupper($value));
});
}
}
macro
メソッドは登録名を第1引数、クロージャを第2引数に取ります。マクロのクロージャはResponseFactory
の実装か、response
ヘルパに対し、登録名で呼び出すことで、実行されます。
return response()->caps('foo');