Ответы
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]);
});
// Это сожмет все ответы для любого маршрута
Flight::response()->addResponseBodyCallback(function($body) {
return gzencode($body, 9);
});
Вы можете добавить несколько обратных вызовов, и они будут выполняться в порядке их добавления. Поскольку это может принимать любой callable, он может принимать массив классов [ $class, 'method' ]
, замыкание $strReplace = function($body) { str_replace('hi', 'there', $body); };
, или имя функции 'minify'
, если у вас есть функция, чтобы минимизировать ваш html код, например.
Примечание: Обратные вызовы маршрутов не будут работать, если вы используете параметр конфигурации flight.v2.output_buffering
.
Специфический обратный вызов маршрута
Если вы хотите, чтобы это применялось только к конкретному маршруту, вы можете добавить обратный вызов в сам маршрут:
Flight::route('/users', function() {
$db = Flight::db();
$users = $db->fetchAll("SELECT * FROM users");
Flight::render('users_table', ['users' => $users]);
// Это сожмет только ответ для этого маршрута
Flight::response()->addResponseBodyCallback(function($body) {
return gzencode($body, 9);
});
});
Опция Middleware
Вы также можете использовать промежуточное ПО, чтобы применить обратный вызов ко всем маршрутам через промежуточное ПО:
// 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_THROW_ON_ERROR
иJSON_UNESCAPED_SLASHES
при кодировании JSON.
JSON с кодом состояния
Вы также можете передать код состояния в качестве второго аргумента:
Flight::json(['id' => 123], 201);
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');
Таким образом, при выполнении GET-запроса с использованием ?q=my_func
, вы должны получить вывод:
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();
Очистка данных ответа
Вы можете очистить тело ответа и заголовки, используя метод 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 'Этот контент будет кеширован.';
});
// Или вы можете использовать строку, которую вы передали бы
// методу strtotime()
Flight::route('/news', function () {
Flight::response()->cache('+5 minutes');
echo 'Этот контент будет кеширован.';
});
Время последнего изменения
Вы можете использовать метод lastModified
и передать метку времени UNIX, чтобы установить дату
и время, когда страница была в последний раз изменена. Клиент будет продолжать использовать
свой кеш, пока значение времени последнего изменения не изменится.
Flight::route('/news', function () {
Flight::lastModified(1234567890);
echo 'Этот контент будет кеширован.';
});
ETag
Кеширование ETag
аналогично Last-Modified
, за исключением того, что вы можете
указать любое уникальное значение для ресурса:
Flight::route('/news', function () {
Flight::etag('my-unique-id');
echo 'Этот контент будет кеширован.';
});
Имейте в виду, что вызов как lastModified
, так и etag
установит и проверит
значение кеша. Если значение кеша одинаково между запросами, Flight сразу
отправит ответ HTTP 304
и остановит обработку.
Загрузка файла (v3.12.0)
Существует вспомогательный метод для загрузки файла. Вы можете использовать метод download
и передать путь.
Flight::route('/download', function () {
Flight::download('/path/to/file.txt');
});