Laravel 8.x HTTPレスポンス

レスポンスの生成

文字列と配列

当然ながらすべてのルートやコントローラは、ユーザーのブラウザに対し、何らかのレスポンスを返す必要があります。Laravelはレスポンスを返すためにさまざまな手段を用意しています。一番基本的なレスポンスは、ルートかコントローラから文字列を返します。フレームワークが自動的に、文字列を完全なHTTPレスポンスへ変換します。

Route::get('/', function () {
    return 'Hello World';
});

ルートやコントローラから文字列を返す他に、配列も返せます。フレームワークは自動的に、配列をJSONレスポンスへ変換します。

Route::get('/', function () {
    return [1, 2, 3];
});

Tip!! Eloquentコレクションも返せることを知っていますか? 自動的にJSONへ変換されます。試してください!

レスポンスオブジェクト

通常、皆さんは単純な文字列や配列をルートアクションから返すだけじゃありませんよね。代わりに、Illuminate\Http\Responseインスタンスかビューを返したいですよね。

完全なResponseインスタンスを返せば、レスポンスのHTTPステータスコードやヘッダをカスタマイズできます。Responseインスタンスは、Symfony\Component\HttpFoundation\Responseクラスを継承しており、HTTPレスポンスを構築するためにさまざまなメソッドを提供しています。

Route::get('/home', function () {
    return response('Hello World', 200)
                  ->header('Content-Type', 'text/plain');
});

Eloquentモデルとコレクション

Eloquent ORMモデルとコレクションをルートとコントローラから直接返すこともできます。これを行うと、Laravelはモデルの非表示属性を尊重しながら、モデルやコレクションをJSONレスポンスへ自動的に変換します。

use App\Models\User;

Route::get('/user/{user}', function (User $user) {
    return $user;
});

レスポンスへのヘッダ付加

レスポンスインスタンスをスラスラと構築できるように、ほとんどのレスポンスメソッドはチェーンとしてつなげられることを覚えておきましょう。たとえば、ユーザーにレスポンスを送り返す前に、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',
            ]);

キャッシュコントロール・ミドルウェア

ルートグループへCache-Controlヘッダを簡単に指定できるよう、Laravelはcache.headersを用意しています。ディレクティブのリストの中でetagが指定されていると、レスポンスコンテンツのMD5ハッシュが、ETag識別子へ自動的にセットされます。

Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function () {
    Route::get('/privacy', function () {
        // ...
    });

    Route::get('/terms', function () {
        // ...
    });
});

レスポンスへのクッキー付加

cookieメソッドを使用して、発信Illuminate\Http\Responseインスタンスへクッキーを添付できます。Cookieが有効であると見なされる名前、値、および分数をメソッドへ渡す必要があります。

return response('Hello World')->cookie(
    'name', 'value', $minutes
);

cookieメソッドはさらに、使用機会が少ない引数をいくつか受け付けます。これらの引数は、全般的にPHPネイティブのsetcookieメソッドに指定する引数と、同じ目的、同じ意味合いを持っています。

return response('Hello World')->cookie(
    'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);

クッキーが送信レスポンスとともに確実に送信したいが、そのレスポンスのインスタンスがまだない場合は、Cookieファサードを使用して、送信時にレスポンスへ添付するためにそのクッキーを「キュー」へ投入できます。queueメソッドは、クッキーインスタンスの作成に必要な引数をとります。こうしたクッキーは、ブラウザへ送信される前に送信レスポンスへ添付します。

use Illuminate\Support\Facades\Cookie;

Cookie::queue('name', 'value', $minutes);

クッキーインスタンスの生成

後ほどレスポンスインスタンスへアタッチできるSymfony\Component\HttpFoundation\Cookieインスタンスを生成したい場合は、グローバルなcookieヘルパを使用します。このCookieは、レスポンスインスタンスへ添付しない限り、クライアントに返送されません。

$cookie = cookie('name', 'value', $minutes);

return response('Hello World')->cookie($cookie);

クッキーの早期期限切れ

送信レスポンスのwithoutCookieメソッドを介してクッキーを期限切れにすることにより、そのクッキーを削除できます。

return response('Hello World')->withoutCookie('name');

送信レスポンスのインスタンスがまだない場合は、Cookieファサードのexpireメソッドを使用してCookieを期限切れにすることができます。

Cookie::expire('name');

クッキーと暗号化

Laravelにより生成されるクッキーは、クライアントにより変更されたり、読まれたりされないようにデフォルトで暗号化され、署名されます。アプリケーションで生成する特定のクッキーで暗号化を無効にしたい場合は、app/Http/Middlewareディレクトリ中に存在する、App\Http\Middleware\EncryptCookiesミドルウェアの$exceptプロパティで指定してください。

/**
 * 暗号化しないクッキー名
 *
 * @var array
 */
protected $except = [
    'cookie_name',
];

リダイレクト

リダイレクトのレスポンスは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モデルによる、パラメータの埋め込み

Eloquentモデルの"ID"をルートパラメーターとしてリダイレクトする場合は、モデルをそのまま渡してください。IDは自動的にとり出されます。

//  /profile/{id}のURIを持つルートの場合

return redirect()->route('profile', [$user]);

ルートパラメータへ配置する値をカスタマイズする場合は、ルートパラメータ定義(/profile/{id:slug})でカラムを指定するか、EloquentモデルのgetRouteKeyメソッドをオーバーライドします。

/**
 * モデルのルートキー値の取得
 *
 * @return mixed
 */
public function getRouteKey()
{
    return $this->slug;
}

コントローラアクションへのリダイレクト

コントローラアクションに対するリダイレクトを生成することもできます。そのためには、コントローラとアクションの名前をactionメソッドに渡してください。

use App\Http\Controllers\UserController;

return redirect()->action([UserController::class, 'index']);

コントローラルートにパラメーターが必要ならば、actionメソッドの第2引数として渡してください。

return redirect()->action(
    [UserController::class, 'profile'], ['id' => 1]
);

外部ドメインへのリダイレクト

アプリケーション外のドメインへリダイレクトする必要がときどき起きます。このためにはawayメソッドを呼び出してください。これはRedirectResponseを生成しますが、URLエンコードを追加せず、バリデーションも検証も行いません。

return redirect()->away('https://www.google.com');

フラッシュデータを保存するリダイレクト

新しい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

入力と共にリダイレクト

ユーザーを新しい場所にリダイレクトする前に、RedirectResponseインスタンスが提供するwithInputメソッドを使用して、現在のリクエストの入力データをセッションへ一時保存できます。これは通常、ユーザーがバリデーションエラーに遭遇した場合に行います。入力をセッションに一時保存したら、次のリクエスト中で簡単に取得してフォームを再入力できます。

return back()->withInput();

他のレスポンスタイプ

responseヘルパは、他のタイプのレスポンスインスタンスを生成するために便利です。responseヘルパが引数なしで呼び出されると、Illuminate\Contracts\Routing\ResponseFactory契約が返されます。この契約はレスポンスを生成するための、さまざまなメソッドを提供しています。

Viewレスポンス

レスポンスのステータスやヘッダをコントロールしながらも、レスポンス内容としてビューを返す必要がある場合は、viewメソッドを使用してください。

return response()
            ->view('hello', $data, 200)
            ->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メソッドとwithCallbackメソッドを組み合わせてください。

return response()
            ->json(['name' => 'Abigail', 'state' => 'CA'])
            ->withCallback($request->input('callback'));

Fileダウンロード

downloadメソッドを使用して、ユーザーのブラウザに対し、指定パスのファイルをダウンロードするように強制するレスポンスを生成できます。downloadメソッドは、メソッドの引数の2番目にファイル名を取ります。これにより、ユーザーがファイルをダウンロードするときに表示するファイル名が決まります。最後に、HTTPヘッダの配列をメソッドの3番目の引数として渡すこともできます。

return response()->download($pathToFile);

return response()->download($pathToFile, $name, $headers);

Note: ファイルダウンロードを管理しているSymfony HttpFoundationクラスは、ASCIIのダウンロードファイル名を指定するよう要求しています。

ストリームダウンロード

特定の操作の文字列レスポンスを、操作の内容をディスクに書き込まずにダウンロード可能なレスポンスへ変換したい場合もあるでしょう。このシナリオでは、streamDownloadメソッドを使用します。このメソッドは、コールバック、ファイル名、およびオプションのヘッダ配列を引数に取ります。

use App\Services\GitHub;

return response()->streamDownload(function () {
    echo GitHub::api('repo')
                ->contents()
                ->readme('laravel', 'laravel')['contents'];
}, 'laravel-readme.md');

Fileレスポンス

fileメソッドは、ダウンロードする代わりに、ブラウザへ画像やPDFのようなファイルを表示するために使用します。このメソッドは第1引数にファイルパス、第2引数にヘッダの配列を指定します。

return response()->file($pathToFile);

return response()->file($pathToFile, $headers);

レスポンスマクロ

さまざまなルートやコントローラで再利用できるカスタムレスポンスを定義する場合は、Responseファサードでmacroメソッドを使用してください。通常、このメソッドは、App\Providers\AppServiceProviderサービスプロバイダなど、アプリケーションのサービスプロバイダの1つのbootメソッドから呼び出す必要があります。

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Response;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 全アプリケーションサービスの初期起動処理
     *
     * @return void
     */
    public function boot()
    {
        Response::macro('caps', function ($value) {
            return Response::make(strtoupper($value));
        });
    }
}

macro関数は、最初の引数に名前を受け入れ、2番目の引数にクロージャを取ります。マクロのクロージャは、ResponseFactory実装またはresponseヘルパからマクロ名を呼び出すときに実行されます。

return response()->caps('foo');

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる