Flight помогает генерировать часть заголовков ответа для вас, но большую часть управления тем, что вы отправляете пользователю, вы удерживаете. Иногда вы можете получить доступ к объекту Responseнепосредственно, но большую часть времени вы будете использовать экземпляр Flight для отправки ответа.
Response
Flight
Flight использует ob_start() для буферизации вывода. Это означает, что вы можете использовать echo или print для отправки ответа пользователю, и Flight захватит его и отправит обратно пользователю с соответствующими заголовками.
echo
print
// Это отправит "Привет, Мир!" в браузер пользователя Flight::route('/', function() { echo "Привет, Мир!"; }); // HTTP/1.1 200 OK // Content-Type: text/html // // Привет, Мир!
В качестве альтернативы вы можете вызвать метод write() для добавления к телу также.
write()
// Это отправит "Привет, Мир!" в браузер пользователя Flight::route('/', function() { // многословно, но удобно, когда вам это нужно Flight::response()->write("Привет, Мир!"); // если вы хотите извлечь тело, которое вы установили на этом этапе // вы можете сделать это так $body = Flight::response()->getBody(); });
Вы можете установить код статуса ответа, используя метод status:
status
Flight::route('/@id', function($id) { if($id == 123) { Flight::response()->status(200); echo "Привет, Мир!"; } else { Flight::response()->status(403); echo "Forbidden"; } });
Если вы хотите получить текущий код статуса, вы можете использовать метод status без аргументов:
Flight::response()->status(); // 200
Вы можете установить тело ответа, используя метод write, однако, если вы используете echo или print что-либо, это будет захвачено и отправлено как тело ответа через буферизацию вывода.
write
Flight::route('/', function() { Flight::response()->write("Привет, Мир!"); }); // то же самое, что и Flight::route('/', function() { echo "Привет, Мир!"; });
Если вы хотите очистить тело ответа, вы можете использовать метод clearBody:
clearBody
Flight::route('/', function() { if($someCondition) { Flight::response()->write("Привет, Мир!"); } else { Flight::response()->clearBody(); } });
Вы можете запустить обратный вызов на теле ответа, используя метод addResponseBodyCallback:
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); });
Вы можете добавлять несколько обратных вызовов, и они будут запускаться в том порядке, в котором они были добавлены. Поскольку это может принимать любой вызываемый объект, он может принимать массив класса [ $class, 'method' ], замыкание $strReplace = function($body) { str_replace('hi', 'there', $body); };, или имя функции 'minify', если у вас есть функция для минификации вашего html-кода, например.
[ $class, 'method' ]
$strReplace = function($body) { str_replace('hi', 'there', $body); };
'minify'
Примечание: Обратные вызовы маршрута не будут работать, если вы используете параметр конфигурации flight.v2.output_buffering.
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); }); });
Вы также можете использовать промежуточное программное обеспечение для применения обратного вызова ко всем маршрутам через промежуточное программное обеспечение:
// 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:
header
// Это отправит "Привет, Мир!" в браузер пользователя в виде простого текста Flight::route('/', function() { Flight::response()->header('Content-Type', 'text/plain'); // или Flight::response()->setHeader('Content-Type', 'text/plain'); echo "Привет, Мир!"; });
Flight предоставляет поддержку для отправки JSON и JSONP ответов. Чтобы отправить JSON-ответ, вы передаете некоторые данные для кодирования JSON:
Flight::json(['id' => 123]);
Вы также можете передать код статуса в качестве второго аргумента:
Flight::json(['id' => 123], 201);
Вы также можете передать аргумент в последнюю позицию для включения красивой печати:
Flight::json(['id' => 123], 200, true, 'utf-8', JSON_PRETTY_PRINT);
Если вы изменяете передаваемые в Flight::json() параметры и хотите более простый синтаксис, вы можете просто переопределить метод JSON:
Flight::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-ответ и остановить выполнение, вы можете использовать метод jsonHalt. Это полезно для случаев, когда вы проверяете, возможно, какой-то тип авторизации и если пользователь не авторизован, вы можете немедленно отправить JSON-ответ, очистить текущее тело содержимого и остановить выполнение.
jsonHalt
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 вы можете необязательно передать имя параметра запроса, которое вы используете для определения вашей функции обратного вызова:
Flight::jsonp(['id' => 123], 'q');
Таким образом, при выполнении GET-запроса с использованием ?q=my_func, вы должны получить вывод:
?q=my_func
my_func({"id":123});
Если вы не передадите имя параметра запроса, он по умолчанию будет jsonp.
jsonp
Вы можете перенаправить текущий запрос, используя метод redirect() и передавая новый URL:
redirect()
Flight::redirect('/new/location');
По умолчанию Flight отправляет код состояния HTTP 303 ("Смотри другой"). Вы можете указать пользовательский код:
Flight::redirect('/new/location', 401);
Вы можете остановить фреймворк в любой момент, вызвав метод halt:
halt
Flight::halt();
Также вы можете указать необязательный HTTP код состояния и сообщение:
HTTP
Flight::halt(200, 'Скоро вернусь...');
Вызов halt будет отбрасывать любое содержимое ответа до этого момента. Если вы хотите остановить фреймворк и вывести текущий ответ, используйте метод stop:
stop
Flight::stop();
Вы можете очистить тело ответа и заголовки, используя метод clear(). Это очистит любые заголовки, присвоенные ответу, очистит тело ответа и установит код статуса на 200.
clear()
200
Flight::response()->clear();
Если вы хотите очистить только тело ответа, вы можете использовать метод clearBody():
clearBody()
// Это все еще сохранит все заголовки установленные на объекте response(). Flight::response()->clearBody();
Flight предоставляет встроенную поддержку кэширования на уровне HTTP. Если условие кэширования соблюдается, Flight вернет HTTP 304 Not Modified ответ. При следующем запросе клиента к тому же ресурсу, их попросят использовать локально кэшированную версию.
304 Not Modified
Если вы хотите кешировать весь ваш ответ, вы можете использовать метод cache() и передать время кэширования.
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 для установки даты и времени последнего изменения страницы. Клиент продолжит использовать свой кэш до тех пор, пока значение последнего изменения не изменится.
lastModified
Flight::route('/news', function () { Flight::lastModified(1234567890); echo 'Этот контент будет закеширован.'; });
Кэширование ETag аналогично кэшированию Last-Modified, за исключением того, что вы можете указать любой идентификатор, который вы хотите для ресурса:
ETag
Last-Modified
Flight::route('/news', function () { Flight::etag('my-unique-id'); echo 'Этот контент будет закеширован.'; });
Имейте в виду, что вызов lastModified или etag установит и проверит значение кеша. Если значение кеша одинаково между запросами, Flight немедленно отправит ответ HTTP 304 и прекратит обработку.
etag
HTTP 304
Есть вспомогательный метод для загрузки файла. Вы можете использовать метод download и передать путь.
download
Flight::route('/download', function () { Flight::download('/path/to/file.txt'); });