レスポンス
Flight はレスポンスヘッダーの一部を生成するのを助けてくれますが、ユーザーに返送する内容のほとんどを制御するのはあなたです。時折、直接 Response
オブジェクトにアクセスできますが、ほとんどの場合、Flight
インスタンスを使ってレスポンスを送信します。
基本レスポンスの送信
Flight は ob_start() を使用して出力をバッファリングします。これにより、echo
または print
を使用してユーザーにレスポンスを送信でき、Flight がそれをキャプチャして適切なヘッダーと一緒に返送します。
// これはユーザーのブラウザに "Hello, World!" を送信します
Flight::route('/', function() {
echo "Hello, World!";
});
// HTTP/1.1 200 OK
// Content-Type: text/html
//
// Hello, World!
代わりに、write()
メソッドを呼び出してボディに追加することもできます。
// これはユーザーのブラウザに "Hello, World!" を送信します
Flight::route('/', function() {
// 冗長ですが、必要な場合に役立つ
Flight::response()->write("Hello, World!");
// この時点で設定したボディを取得したい場合
// 以下のようにできます
$body = Flight::response()->getBody();
});
ステータスコード
レスポンスのステータスコードを設定するには、status
メソッドを使用します:
Flight::route('/@id', function($id) {
if($id == 123) {
Flight::response()->status(200);
echo "Hello, World!";
} else {
Flight::response()->status(403);
echo "Forbidden";
}
});
現在のステータスコードを取得するには、引数なしで status
メソッドを使用します:
Flight::response()->status(); // 200
レスポンスボディの設定
レスポンスボディを設定するには、write
メソッドを使用しますが、echo
または print
を使用すると、それはキャプチャされて出力バッファリング経由でレスポンスボディとして送信されます。
Flight::route('/', function() {
Flight::response()->write("Hello, World!");
});
// これは以下と同等です
Flight::route('/', function() {
echo "Hello, World!";
});
レスポンスボディのクリア
レスポンスボディをクリアしたい場合、clearBody
メソッドを使用します:
Flight::route('/', function() {
if($someCondition) {
Flight::response()->write("Hello, World!");
} else {
Flight::response()->clearBody();
}
});
レスポンスボディに対するコールバックの実行
レスポンスボディでコールバックを実行するには、addResponseBodyCallback
メソッドを使用します:
Flight::route('/users', function() {
$db = Flight::db();
$users = $db->fetchAll("SELECT * FROM users");
Flight::render('users_table', ['users' => $users]);
});
// これはすべてのルートのレスポンスをgzipします
Flight::response()->addResponseBodyCallback(function($body) {
return gzencode($body, 9);
});
複数のコールバックを追加でき、それらは追加された順序で実行されます。これは callable を受け入れるため、クラス配列 [ $class, 'method' ]
、クロージャ $strReplace = function($body) { str_replace('hi', 'there', $body); };
、または例えば HTML コードを最小化する関数名 'minify'
を受け入れます。
注: ルートコールバックは、flight.v2.output_buffering
構成オプションを使用している場合に動作しません。
特定のルートに対するコールバック
これを特定のルートにのみ適用したい場合、ルート内でコールバックを追加できます:
Flight::route('/users', function() {
$db = Flight::db();
$users = $db->fetchAll("SELECT * FROM users");
Flight::render('users_table', ['users' => $users]);
// これはこのルートのレスポンスのみgzipします
Flight::response()->addResponseBodyCallback(function($body) {
return gzencode($body, 9);
});
});
ミドルウェアオプション
ミドルウェアを使用して、すべてのルートにコールバックを適用することもできます:
// MinifyMiddleware.php
class MinifyMiddleware {
public function before() {
// ここで response() オブジェクトにコールバックを適用します。
Flight::response()->addResponseBodyCallback(function($body) {
return $this->minify($body);
});
}
protected function minify(string $body): string {
// ボディを何らかの方法で最小化します
return $body;
}
}
// index.php
Flight::group('/users', function() {
Flight::route('', function() { /* ... */ });
Flight::route('/@id', function($id) { /* ... */ });
}, [ new MinifyMiddleware() ]);
レスポンスヘッダーの設定
レスポンスのヘッダー、例えばコンテンツタイプを設定するには、header
メソッドを使用します:
// これはユーザーのブラウザにプレーンテキストで "Hello, World!" を送信します
Flight::route('/', function() {
Flight::response()->header('Content-Type', 'text/plain');
// または
Flight::response()->setHeader('Content-Type', 'text/plain');
echo "Hello, World!";
});
JSON
Flight は JSON および JSONP レスポンスの送信をサポートします。JSON レスポンスを送信するには、JSON エンコードするデータを渡します:
Flight::json(['id' => 123]);
注: デフォルトで、Flight はレスポンスに
Content-Type: application/json
ヘッダーを送信します。また、JSON をエンコードする際にJSON_THROW_ON_ERROR
とJSON_UNESCAPED_SLASHES
定数を使用します。
JSON の整形出力
整形出力を有効にするために、最後の位置に引数を渡すこともできます:
Flight::json(['id' => 123], 200, true, 'utf-8', JSON_PRETTY_PRINT);
Flight::json()
に渡されるオプションを変更し、よりシンプルな構文を望む場合、JSON メソッドを再マップできます:
Flight::map('json', function($data, $code = 200, $options = 0) {
Flight::_json($data, $code, true, 'utf-8', $options);
}
// そして今、これのように使用できます
Flight::json(['id' => 123], 200, JSON_PRETTY_PRINT);
JSON と実行停止 (v3.10.0)
JSON レスポンスを送信して実行を停止したい場合、jsonHalt()
メソッドを使用します。これは、例えば承認チェックを行い、ユーザーが承認されていない場合にすぐに JSON レスポンスを送信し、既存のボディコンテンツをクリアして実行を停止するのに便利です。
Flight::route('/users', function() {
$authorized = someAuthorizationCheck();
// ユーザーが承認されているか確認
if($authorized === false) {
Flight::jsonHalt(['error' => 'Unauthorized'], 401);
}
// ルートの残りを続行
});
v3.10.0 以前では、以下のようにする必要がありました:
Flight::route('/users', function() {
$authorized = someAuthorizationCheck();
// ユーザーが承認されているか確認
if($authorized === false) {
Flight::halt(401, json_encode(['error' => 'Unauthorized']));
}
// ルートの残りを続行
});
JSONP
JSONP リクエストの場合、オプションでコールバック関数を定義するためのクエリパラメーター名を渡せます:
Flight::jsonp(['id' => 123], 'q');
例えば、?q=my_func
を使用して GET リクエストを行うと、出力は以下のようになります:
my_func({"id":123});
クエリパラメーター名を渡さない場合、デフォルトで jsonp
になります。
別の URL へのリダイレクト
現在のリクエストをリダイレクトするには、redirect()
メソッドを使用して新しい URL を渡します:
Flight::redirect('/new/location');
デフォルトで Flight は HTTP 303 ("See Other") ステータスコードを送信します。オプションでカスタムコードを設定できます:
Flight::redirect('/new/location', 401);
停止
フレームワークを任意の時点で停止するには、halt
メソッドを呼びます:
Flight::halt();
オプションで HTTP ステータスコードとメッセージを指定できます:
Flight::halt(200, 'Be right back...');
halt
を呼び出すと、それまでのレスポンスコンテンツは破棄されます。フレームワークを停止して現在のレスポンスを出力したい場合、stop
メソッドを使用します:
Flight::stop($httpStatusCode = null);
注:
Flight::stop()
は、レスポンスを出力するがスクリプトの実行を継続するなどの奇妙な動作をします。実行を防ぐためにexit
またはreturn
をFlight::stop()
の後に使用できますが、一般的にFlight::halt()
を使用することを推奨します。
レスポンスデータのクリア
レスポンスボディとヘッダーをクリアするには、clear()
メソッドを使用します。これにより、レスポンスに割り当てられたヘッダーをクリアし、レスポンスボディをクリアし、ステータスコードを 200
に設定します。
Flight::response()->clear();
レスポンスボディのみのクリア
レスポンスボディのみをクリアしたい場合、clearBody()
メソッドを使用します:
// これは response() オブジェクトに設定されたヘッダーを保持します。
Flight::response()->clearBody();
HTTP キャッシング
Flight は HTTP レベルでのキャッシングを組み込みでサポートします。キャッシング条件が満たされると、Flight は HTTP 304 Not Modified
レスポンスを返します。次にクライアントが同じリソースをリクエストすると、ローカルにキャッシュされたバージョンの使用が促されます。
ルートレベルのキャッシング
レスポンス全体をキャッシングしたい場合、cache()
メソッドを使用してキャッシング時間を渡します。
// これはレスポンスを5分間キャッシングします
Flight::route('/news', function () {
Flight::response()->cache(time() + 300);
echo 'This content will be cached.';
});
// または、strtotime() メソッドに渡す文字列を使用
Flight::route('/news', function () {
Flight::response()->cache('+5 minutes');
echo 'This content will be cached.';
});
Last-Modified
ページが最後に変更された日時を設定するには、lastModified
メソッドに UNIX タイムスタンプを渡します。クライアントは last modified 値が変更されるまでキャッシュを継続して使用します。
Flight::route('/news', function () {
Flight::lastModified(1234567890);
echo 'This content will be cached.';
});
ETag
ETag
キャッシングは Last-Modified
に似ていますが、リソースの任意の ID を指定できます:
Flight::route('/news', function () {
Flight::etag('my-unique-id');
echo 'This content will be cached.';
});
lastModified
または etag
を呼び出すと、キャッシュ値を設定およびチェックします。リクエスト間でキャッシュ値が同じ場合、Flight はすぐに HTTP 304 レスポンスを送信して処理を停止します。
ファイルのダウンロード (v3.12.0)
ファイルをダウンロードするためのヘルパーメソッドがあります。download
メソッドにパスを渡します。
Flight::route('/download', function () {
Flight::download('/path/to/file.txt');
});