Respuestas
Flight ayuda a generar parte de los encabezados de respuesta para ti, pero tú tienes la mayor parte del control sobre lo que envías de vuelta al usuario. A veces puedes acceder directamente al objeto Response
, pero la mayoría de las veces usarás la instancia de Flight
para enviar una respuesta.
Enviar una Respuesta Básica
Flight usa ob_start() para almacenar en buffer la salida. Esto significa que puedes usar echo
o print
para enviar una respuesta al usuario y Flight la capturará y la enviará de vuelta con los encabezados apropiados.
// Esto enviará "Hello, World!" al navegador del usuario
Flight::route('/', function() {
echo "Hello, World!";
});
// HTTP/1.1 200 OK
// Content-Type: text/html
//
// Hello, World!
Como alternativa, puedes llamar al método write()
para agregar al cuerpo también.
// Esto enviará "Hello, World!" al navegador del usuario
Flight::route('/', function() {
// verbose, pero a veces se necesita cuando lo requieres
Flight::response()->write("Hello, World!");
// si quieres recuperar el cuerpo que has establecido en este punto
// puedes hacerlo así
$body = Flight::response()->getBody();
});
Códigos de Estado
Puedes establecer el código de estado de la respuesta usando el método status
:
Flight::route('/@id', function($id) {
if($id == 123) {
Flight::response()->status(200);
echo "Hello, World!";
} else {
Flight::response()->status(403);
echo "Forbidden";
}
});
Si quieres obtener el código de estado actual, puedes usar el método status
sin argumentos:
Flight::response()->status(); // 200
Establecer un Cuerpo de Respuesta
Puedes establecer el cuerpo de la respuesta usando el método write
, sin embargo, si echo o print algo,
se capturará y se enviará como el cuerpo de la respuesta a través del almacenamiento en buffer de salida.
Flight::route('/', function() {
Flight::response()->write("Hello, World!");
});
// lo mismo que
Flight::route('/', function() {
echo "Hello, World!";
});
Limpiar un Cuerpo de Respuesta
Si quieres limpiar el cuerpo de la respuesta, puedes usar el método clearBody
:
Flight::route('/', function() {
if($someCondition) {
Flight::response()->write("Hello, World!");
} else {
Flight::response()->clearBody();
}
});
Ejecutar un Callback en el Cuerpo de Respuesta
Puedes ejecutar un callback en el cuerpo de la respuesta usando el método addResponseBodyCallback
:
Flight::route('/users', function() {
$db = Flight::db();
$users = $db->fetchAll("SELECT * FROM users");
Flight::render('users_table', ['users' => $users]);
});
// Esto comprimirá con gzip todas las respuestas para cualquier ruta
Flight::response()->addResponseBodyCallback(function($body) {
return gzencode($body, 9);
});
Puedes agregar múltiples callbacks y se ejecutarán en el orden en que se agregaron. Como esto puede aceptar cualquier callable, puede aceptar un array de clase [ $class, 'method' ]
, un cierre $strReplace = function($body) { str_replace('hi', 'there', $body); };
, o un nombre de función 'minify'
si tienes una función para minimizar tu código HTML, por ejemplo.
Nota: Los callbacks de rutas no funcionarán si estás usando la opción de configuración flight.v2.output_buffering
.
Callback para una Ruta Específica
Si querías que esto se aplicara solo a una ruta específica, podrías agregar el callback en la ruta misma:
Flight::route('/users', function() {
$db = Flight::db();
$users = $db->fetchAll("SELECT * FROM users");
Flight::render('users_table', ['users' => $users]);
// Esto comprimirá con gzip solo la respuesta para esta ruta
Flight::response()->addResponseBodyCallback(function($body) {
return gzencode($body, 9);
});
});
Opción de Middleware
También puedes usar middleware para aplicar el callback a todas las rutas a través de middleware:
// MinifyMiddleware.php
class MinifyMiddleware {
public function before() {
// Aplicar el callback aquí en el objeto response().
Flight::response()->addResponseBodyCallback(function($body) {
return $this->minify($body);
});
}
protected function minify(string $body): string {
// minimiza el cuerpo de alguna manera
return $body;
}
}
// index.php
Flight::group('/users', function() {
Flight::route('', function() { /* ... */ });
Flight::route('/@id', function($id) { /* ... */ });
}, [ new MinifyMiddleware() ]);
Establecer un Encabezado de Respuesta
Puedes establecer un encabezado como el tipo de contenido de la respuesta usando el método header
:
// Esto enviará "Hello, World!" al navegador del usuario en texto plano
Flight::route('/', function() {
Flight::response()->header('Content-Type', 'text/plain');
// o
Flight::response()->setHeader('Content-Type', 'text/plain');
echo "Hello, World!";
});
JSON
Flight proporciona soporte para enviar respuestas JSON y JSONP. Para enviar una respuesta JSON, pasa algunos datos para ser codificados en JSON:
Flight::json(['id' => 123]);
Nota: Por defecto, Flight enviará un encabezado
Content-Type: application/json
con la respuesta. También usará las constantesJSON_THROW_ON_ERROR
yJSON_UNESCAPED_SLASHES
al codificar el JSON.
JSON con Código de Estado
También puedes pasar un código de estado como el segundo argumento:
Flight::json(['id' => 123], 201);
JSON con Impresión Bonita
Puedes pasar un argumento en la última posición para habilitar la impresión bonita:
Flight::json(['id' => 123], 200, true, 'utf-8', JSON_PRETTY_PRINT);
Si estás cambiando opciones pasadas a Flight::json()
y quieres una sintaxis más simple, puedes
remapear el método JSON:
Flight::map('json', function($data, $code = 200, $options = 0) {
Flight::_json($data, $code, true, 'utf-8', $options);
}
// Y ahora puede usarse así
Flight::json(['id' => 123], 200, JSON_PRETTY_PRINT);
JSON y Detener la Ejecución (v3.10.0)
Si quieres enviar una respuesta JSON y detener la ejecución, puedes usar el método jsonHalt()
.
Esto es útil para casos en los que estás verificando algún tipo de autorización y si
el usuario no está autorizado, puedes enviar una respuesta JSON inmediatamente, limpiar el contenido
del cuerpo existente y detener la ejecución.
Flight::route('/users', function() {
$authorized = someAuthorizationCheck();
// Verifica si el usuario está autorizado
if($authorized === false) {
Flight::jsonHalt(['error' => 'Unauthorized'], 401);
}
// Continúa con el resto de la ruta
});
Antes de v3.10.0, tendrías que hacer algo como esto:
Flight::route('/users', function() {
$authorized = someAuthorizationCheck();
// Verifica si el usuario está autorizado
if($authorized === false) {
Flight::halt(401, json_encode(['error' => 'Unauthorized']));
}
// Continúa con el resto de la ruta
});
JSONP
Para solicitudes JSONP, puedes pasar opcionalmente el nombre del parámetro de consulta que estás usando para definir tu función de callback:
Flight::jsonp(['id' => 123], 'q');
Entonces, al hacer una solicitud GET usando ?q=my_func
, deberías recibir la salida:
my_func({"id":123});
Si no pasas un nombre de parámetro de consulta, se establecerá por defecto en jsonp
.
Redirigir a otra URL
Puedes redirigir la solicitud actual usando el método redirect()
y pasando
una nueva URL:
Flight::redirect('/new/location');
Por defecto, Flight envía un código de estado HTTP 303 ("See Other"). Puedes establecer opcionalmente un código personalizado:
Flight::redirect('/new/location', 401);
Detener
Puedes detener el framework en cualquier momento llamando al método halt
:
Flight::halt();
También puedes especificar un código de estado HTTP opcional y un mensaje:
Flight::halt(200, 'Be right back...');
Llamar a halt
descartará cualquier contenido de respuesta hasta ese punto. Si quieres detener
el framework y salir con la respuesta actual, usa el método stop
:
Flight::stop($httpStatusCode = null);
Nota:
Flight::stop()
tiene un comportamiento extraño, como que saldrá la respuesta pero continuará ejecutando tu script. Puedes usarexit
oreturn
después de llamar aFlight::stop()
para prevenir una ejecución adicional, pero generalmente se recomienda usarFlight::halt()
.
Limpiar Datos de Respuesta
Puedes limpiar el cuerpo y los encabezados de la respuesta usando el método clear()
. Esto limpiará
cualquier encabezado asignado a la respuesta, limpiará el cuerpo de la respuesta y establecerá el código de estado en 200
.
Flight::response()->clear();
Limpiar Solo el Cuerpo de Respuesta
Si solo quieres limpiar el cuerpo de la respuesta, puedes usar el método clearBody()
:
// Esto mantendrá cualquier encabezado establecido en el objeto response().
Flight::response()->clearBody();
Almacenamiento en Caché HTTP
Flight proporciona soporte integrado para el almacenamiento en caché a nivel HTTP. Si se cumple la condición de caché,
Flight devolverá una respuesta HTTP 304 Not Modified
. La próxima vez que el cliente solicite el mismo recurso, se le pedirá que use su versión en caché local.
Almacenamiento en Caché a Nivel de Ruta
Si quieres almacenar en caché toda tu respuesta, puedes usar el método cache()
y pasar el tiempo de caché.
// Esto almacenará en caché la respuesta por 5 minutos
Flight::route('/news', function () {
Flight::response()->cache(time() + 300);
echo 'This content will be cached.';
});
// Alternativamente, puedes usar una cadena que pasarías
// al método strtotime()
Flight::route('/news', function () {
Flight::response()->cache('+5 minutes');
echo 'This content will be cached.';
});
Last-Modified
Puedes usar el método lastModified
y pasar una marca de tiempo UNIX para establecer la fecha
y hora en que una página fue modificada por última vez. El cliente continuará usando su caché hasta
que el valor de última modificación cambie.
Flight::route('/news', function () {
Flight::lastModified(1234567890);
echo 'This content will be cached.';
});
ETag
El almacenamiento en caché ETag
es similar a Last-Modified
, excepto que puedes especificar cualquier ID que
quieras para el recurso:
Flight::route('/news', function () {
Flight::etag('my-unique-id');
echo 'This content will be cached.';
});
Ten en cuenta que llamar a lastModified
o etag
establecerá y verificará
el valor de caché. Si el valor de caché es el mismo entre solicitudes, Flight enviará inmediatamente
una respuesta HTTP 304
y detendrá el procesamiento.
Descargar un Archivo (v3.12.0)
Hay un método helper para descargar un archivo. Puedes usar el método download
y pasar la ruta.
Flight::route('/download', function () {
Flight::download('/path/to/file.txt');
});