応答の作成
文字列と配列
すべてのルートとコントローラーは、ユーザーのブラウザに返される応答を返す必要があります。Laravelは、応答を返すためのいくつかの異なる方法を提供しています。最も基本的な応答は、ルートまたはコントローラーから文字列を返すことです。フレームワークは、文字列を自動的に完全なHTTP応答に変換します:
Route::get('/', function () {
return 'Hello World';
});
ルートやコントローラーから文字列を返すことに加えて、配列を返すこともできます。フレームワークは、配列を自動的にJSON応答に変換します:
Route::get('/', function () {
return [1, 2, 3];
});
ルートやコントローラーから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',
]);
キャッシュ制御ミドルウェア
Laravelにはcache.headers
ミドルウェアが含まれており、ルートのグループにCache-Control
ヘッダーを迅速に設定するために使用できます。ディレクティブは、対応するキャッシュ制御ディレクティブの「スネークケース」相当を使用して提供され、セミコロンで区切る必要があります。etag
がディレクティブのリストに指定されている場合、応答コンテンツのMD5ハッシュが自動的にETag識別子として設定されます:
Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function () {
Route::get('/privacy', function () {
// ...
});
Route::get('/terms', function () {
// ...
});
});
応答にクッキーを追加する
``````php
return response('Hello World')->cookie(
'name', 'value', $minutes
);
`
``````php
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('name', 'value', $minutes);
return response('Hello World')->cookie($cookie);
クッキーの早期期限切れ
``````php
return response('Hello World')->withoutCookie('name');
`
送信中の応答のインスタンスがまだない場合は、Cookie
ファサードのexpire
メソッドを使用してクッキーを期限切れにすることができます:
Cookie::expire('name');
クッキーと暗号化
デフォルトでは、Illuminate\Cookie\Middleware\EncryptCookies
ミドルウェアのおかげで、Laravelによって生成されたすべてのクッキーは暗号化され、署名されているため、クライアントによって変更されたり読み取られたりすることはできません。アプリケーションによって生成されたクッキーのサブセットに対して暗号化を無効にしたい場合は、アプリケーションのbootstrap/app.php
ファイルでencryptCookies
メソッドを使用できます:
->withMiddleware(function (Middleware $middleware) {
$middleware->encryptCookies(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 () {
// Validate the request...
return back()->withInput();
});
名前付きルートへのリダイレクト
引数なしでredirect
ヘルパーを呼び出すと、Illuminate\Routing\Redirector
のインスタンスが返され、Redirector
インスタンスの任意のメソッドを呼び出すことができます。たとえば、名前付きルートへのRedirectResponse
を生成するには、route
メソッドを使用できます:
return redirect()->route('login');
ルートにパラメータがある場合は、route
メソッドの2番目の引数としてそれらを渡すことができます:
// For a route with the following URI: /profile/{id}
return redirect()->route('profile', ['id' => 1]);
Eloquentモデルを介したパラメータの埋め込み
Eloquentモデルから埋め込まれている「ID」パラメータを持つルートにリダイレクトしている場合は、モデル自体を渡すことができます。IDは自動的に抽出されます:
// For a route with the following URI: /profile/{id}
return redirect()->route('profile', [$user]);
ルートパラメータに配置される値をカスタマイズしたい場合は、ルートパラメータ定義(/profile/{id:slug}
)でカラムを指定するか、EloquentモデルのgetRouteKey
メソッドをオーバーライドできます:
/**
* Get the value of the model's route key.
*/
public function getRouteKey(): mixed
{
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
メソッドを呼び出すことで、追加のURLエンコーディング、検証、または確認なしにRedirectResponse
を作成できます:
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
入力を使用したリダイレクト
ユーザーを新しい場所にリダイレクトする前に、withInput
メソッドを使用して現在のリクエストの入力データをセッションにフラッシュできます。これは通常、ユーザーがバリデーションエラーに遭遇した場合に行われます。入力がセッションにフラッシュされた後、次のリクエスト中に簡単に取得してフォームを再入力できます:
return back()->withInput();
その他の応答タイプ
response
ヘルパーを使用して、他のタイプの応答インスタンスを生成できます。引数なしでresponse
ヘルパーを呼び出すと、Illuminate\Contracts\Routing\ResponseFactory
契約の実装が返されます。この契約は、応答を生成するためのいくつかの便利なメソッドを提供します。
ビュー応答
応答のステータスとヘッダーを制御する必要があるが、応答のコンテンツとしてビューを返す必要がある場合は、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'));
ファイルダウンロード
``````php
return response()->download($pathToFile);
return response()->download($pathToFile, $name, $headers);
`
ファイルダウンロードを管理するSymfony HttpFoundationは、ダウンロードされるファイルがASCIIファイル名を持つことを要求します。
ファイル応答
``````php
return response()->file($pathToFile);
return response()->file($pathToFile, $headers);
`
ストリーミング応答
生成されるデータをクライアントにストリーミングすることで、メモリ使用量を大幅に削減し、特に非常に大きな応答の場合にパフォーマンスを向上させることができます。ストリーミング応答により、サーバーがデータの送信を完了する前に、クライアントがデータの処理を開始できます:
function streamedContent(): Generator {
yield 'Hello, ';
yield 'World!';
}
Route::get('/stream', function () {
return response()->stream(function (): void {
foreach (streamedContent() as $chunk) {
echo $chunk;
ob_flush();
flush();
sleep(2); // Simulate delay between chunks...
}
}, 200, ['X-Accel-Buffering' => 'no']);
});
内部的に、LaravelはPHPの出力バッファリング機能を利用しています。上記の例のように、ob_flush
およびflush
関数を使用して、バッファされたコンテンツをクライアントにプッシュする必要があります。
ストリーミングJSON応答
JSONデータを段階的にストリーミングする必要がある場合は、streamJson
メソッドを利用できます。このメソッドは、JavaScriptによって簡単に解析できる形式でブラウザに段階的に送信する必要がある大規模データセットに特に便利です:
use App\Models\User;
Route::get('/users.json', function () {
return response()->streamJson([
'users' => User::cursor(),
]);
});
ストリーミングダウンロード
時には、特定の操作の文字列応答をダウンロード可能な応答に変換したい場合があります。この場合、streamDownload
メソッドを使用できます。このメソッドは、コールバック、ファイル名、およびオプションのヘッダーの配列を引数として受け入れます:
use App\Services\GitHub;
return response()->streamDownload(function () {
echo GitHub::api('repo')
->contents()
->readme('laravel', 'laravel')['contents'];
}, 'laravel-readme.md');
応答マクロ
さまざまなルートやコントローラーで再利用できるカスタム応答を定義したい場合は、macro
メソッドをResponse
ファサードで使用できます。通常、このメソッドは、アプリケーションのサービスプロバイダーの1つのboot
メソッドから呼び出す必要があります。たとえば、App\Providers\AppServiceProvider
サービスプロバイダー:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Response::macro('caps', function (string $value) {
return Response::make(strtoupper($value));
});
}
}
``````php
return response()->caps('foo');
`