Los objetos de solicitud y respuesta proporcionan una abstracción en torno a las solicitudes y respuestas HTTP. El objeto
de solicitud en CakePHP le permite realizar una introspección de una solicitud entrante, mientras que el objeto de
respuesta le permite crear respuestas HTTP sin esfuerzo desde sus controladores.
Solicitud (Request)
-
class Cake\Http\ServerRequest
ServerRequest
es el objeto de solicitud predeterminado utilizado en CakePHP. Centraliza una serie de funciones para
interrogar e interactuar con los datos de la solicitud. En cada solicitud, se crea un Request y luego se pasa por
referencia a las distintas capas de una aplicación que utiliza datos de solicitud. De forma predeterminada, la solicitud
se asigna a $this->request
y está disponible en Controladores, Celdas, Vistas y Ayudantes. También puede acceder a él
en Componentes usando la referencia del controlador.
Algunas de las tareas que realiza ServerRequest
incluyen:
Procesar los arreglos GET, POST y FILES en las estructuras de datos con las que está familiarizado.
Proporcionar una introspección del entorno correspondiente a la solicitud. Información como los encabezados enviados,
la dirección IP del cliente y los nombres de subdominio/dominio en el servidor en el que se ejecuta su aplicación.
Proporcionar acceso a los parámetros de solicitud tanto como índices de matriz como propiedades de objetos.
El objeto de la solicitud de CakePHP implementa PSR-7 ServerRequestInterface, lo que
facilita el uso de bibliotecas desde fuera de CakePHP.
Parámetros de la solicitud
La solicitud expone los parámetros de enrutamiento a través del método getParam()
:
$controllerName = $this->request->getParam('controller');
Para obtener todos los parámetros de enrutamiento como una matriz, use getAttribute()
:
$parameters = $this->request->getAttribute('params');
Se accede a todos los Elementos de ruta a través de esta interfaz.
Además de Elementos de ruta, a menudo también necesita acceso a Argumentos Pasados. Ambos también están
disponibles en el objeto de solicitud:
// Argumentos pasados
$passedArgs = $this->request->getParam(“pass”);
Todos le proporcionarán acceso a los argumentos pasados. Hay varios parámetros importantes/útiles que CakePHP usa
internamente, y todos ellos también se encuentran en los parámetros de enrutamiento:
plugin
El complemento que maneja la solicitud. Será nulo cuando no haya ningún complemento.
controller
El controlador que maneja la solicitud actual.
action
La acción que maneja la solicitud actual.
prefix
El prefijo de la acción actual. Consulte Enrutamiento de Prefijo para obtener más información.
Parámetros de cadena de consulta
-
Cake\Http\ServerRequest::getQuery($name, $default = null)
Los parámetros de la cadena de consulta se pueden leer usando el método getQuery()
:
// URL es /posts/index?page=1&sort=title
$page = $this->request->getQuery('page');
Puede acceder directamente a la propiedad de consulta o puede utilizar el método getQuery()
para leer la matriz de
consulta de URL sin errores. Cualquier clave que no exista devolverá null
:
$foo = $this->request->getQuery('value_that_does_not_exist');
// $foo === null
// También puede proporcionar valores predeterminados
$foo = $this->request->getQuery('does_not_exist', 'default val');
Si desea acceder a todos los parámetros de consulta, puede utilizar getQueryParams()
:
$query = $this->request->getQueryParams();
Datos del cuerpo de la solicitud
-
Cake\Http\ServerRequest::getData($name, $default = null)
Se puede acceder a todos los datos POST normalmente disponibles a través de la variable global $_POST
de PHP usando
Cake\Http\ServerRequest::getData()
. Por ejemplo:
// Se puede acceder a una entrada con un atributo de nombre 'título'
$title = $this->request->getData('title');
Puede utilizar nombres separados por puntos para acceder a datos anidados. Por ejemplo:
$value = $this->request->getData('address.street_name');
Para nombres inexistentes se devolverá el valor $default
:
$foo = $this->request->getData('value.that.does.not.exist');
// $foo == null
También puede utilizar Middleware BodyParser para analizar el cuerpo de la solicitud de diferentes tipos de
contenido en una matriz, de modo que sea accesible a través de ServerRequest::getData()
.
Si desea acceder a todos los parámetros de datos, puede utilizar
getParsedBody()
:
$data = $this->request->getParsedBody();
Cargas de archivos
Se puede acceder a los archivos cargados a través de los datos del cuerpo de la solicitud, utilizando el método
Cake\Http\ServerRequest::getData()
descrito anteriormente. Por ejemplo, se puede acceder a un archivo desde
un elemento de entrada con un atributo de nombre attachment
de esta manera:
$attachment = $this->request->getData('attachment');
De forma predeterminada, las cargas de archivos se representan en los datos de la solicitud como objetos que implementan
\Psr\Http\Message\UploadedFileInterface. En la
implementación actual, la variable $attachment
en el ejemplo anterior contendría de forma predeterminada una
instancia de \Laminas\Diactoros\UploadedFile
.
Acceder a los detalles del archivo cargado es bastante simple, así es como puede obtener los mismos datos que proporciona
la matriz de carga de archivos de estilo antiguo:
$name = $attachment->getClientFilename();
$type = $attachment->getClientMediaType();
$size = $attachment->getSize();
$tmpName = $attachment->getStream()->getMetadata(“uri”);
$error = $attachment->getError();
Mover el archivo cargado desde su ubicación temporal a la ubicación de destino deseada no requiere acceder manualmente al
archivo temporal, sino que se puede hacer fácilmente usando el método moveTo()
del objeto:
$attachment->moveTo($targetPath);
En un entorno HTTP, el método moveTo()
validará automáticamente si el archivo es un archivo cargado real y generará
una excepción en caso de que sea necesario. En un entorno CLI, donde no existe el concepto de cargar archivos, permitirá
mover el archivo al que ha hecho referencia independientemente de sus orígenes, lo que hace posible probar la carga de
archivos.
-
Cake\Http\ServerRequest::getUploadedFile($path)
Devuelve el archivo cargado en una ruta específica. La ruta utiliza la misma sintaxis de puntos que el método
Cake\Http\ServerRequest::getData()
:
$attachment = $this->request->getUploadedFile('attachment');
A diferencia de Cake\Http\ServerRequest::getData()
, Cake\Http\ServerRequest::getUploadedFile()
solo devolvería datos cuando exista una carga de archivo real para la ruta dada, si hay datos regulares del cuerpo de la
solicitud que no son archivos presentes en la ruta dada, entonces este método devolverá «nulo», tal como lo haría para
cualquier ruta inexistente.
-
Cake\Http\ServerRequest::getUploadedFiles()
Devuelve todos los archivos cargados en una estructura de matriz normalizada. Para el ejemplo anterior con el nombre de
entrada del archivo attachment
, la estructura se vería así:
[
'attachment' => object(Laminas\Diactoros\UploadedFile) {
// ...
}
]
-
Cake\Http\ServerRequest::withUploadedFiles(array $files)
Este método establece los archivos cargados del objeto de solicitud, acepta una matriz de objetos que implementan
\Psr\Http\Message\UploadedFileInterface. Reemplazará
todos los archivos cargados posiblemente existentes:
$files = [
'MyModel' => [
'attachment' => new \Laminas\Diactoros\UploadedFile(
$streamOrFile,
$size,
$errorStatus,
$clientFilename,
$clientMediaType
),
'anotherAttachment' => new \Laminas\Diactoros\UploadedFile(
'/tmp/hfz6dbn.tmp',
123,
\UPLOAD_ERR_OK,
'attachment.txt',
'text/plain'
),
],
];
$this->request = $this->request->withUploadedFiles($files);
Nota
Los archivos cargados que se agregaron a la solicitud a través de este método no estarán disponibles en los datos
del cuerpo de la solicitud, es decir, no puede recuperarlos a través de
Cake\Http\ServerRequest::getData()
! Si los necesita en los datos de la solicitud (también), entonces
debe configurarlos mediante Cake\Http\ServerRequest::withData()
o
Cake\HttpServerRequest::withParsedBody()
.
PUT, PATCH o DELETE Datos
-
Cake\Http\ServerRequest::input($callback[, $options])
Al crear servicios REST, a menudo se aceptan datos de solicitud en solicitudes PUT
y DELETE
. Cualquier dato del
cuerpo de solicitud application/x-www-form-urlencoded
se analizará automáticamente y se establecerá en
$this->data
para las solicitudes PUT
y DELETE
. Si acepta datos JSON o XML, consulte a continuación cómo puede
acceder a esos cuerpos de solicitud.
Al acceder a los datos de entrada, puede decodificarlos con una función opcional. Esto resulta útil al interactuar con el
contenido del cuerpo de la solicitud XML o JSON. Se pueden pasar parámetros adicionales para la función de decodificación
como argumentos a input()
:
$jsonData = $this->request->input('json_decode');
Variables de entorno (de $_SERVER y $_ENV)
-
Cake\Http\ServerRequest::putenv($key, $value = null)
ServerRequest::getEnv()
es un contenedor para la función global getenv()
y actúa como un captador/establecedor de
variables de entorno sin tener que modificar los globales $_SERVER
y $_ENV
:
// Obtener el host
$host = $this->request->getEnv('HTTP_HOST');
// Establecer un valor, generalmente útil en las pruebas.
$this->request->withEnv('REQUEST_METHOD', 'POST');
Para acceder a todas las variables de entorno en una solicitud, utilice getServerParams()
:
$env = $this->request->getServerParams();
Datos XML o JSON
Las aplicaciones que emplean REST a menudo intercambian datos en cuerpos de publicaciones sin
codificación URL. Puede leer datos de entrada en cualquier formato usando input()
.
Al proporcionar una función de decodificación, puede recibir el contenido en un formato deserializado:
// Obtenga datos codificados en JSON enviados a una acción PUT/POST
$jsonData = $this->request->input('json_decode');
Algunos métodos de deserialización requieren parámetros adicionales cuando se llaman, como el parámetro “as array” en
json_decode
. Si desea convertir XML en un objeto DOMDocument, input()
también
admite el paso de parámetros adicionales:
// Obtener datos codificados en XML enviados a una acción PUT/POST
$data = $this->request->input('Cake\Utility\Xml::build', ['return' => 'domdocument']);
Comprobación de las condiciones de la solicitud
-
Cake\Http\ServerRequest::is($type, $args...)
El objeto de solicitud proporciona una forma de inspeccionar ciertas condiciones en una solicitud determinada. Al
utilizar el método is()
, puede comprobar una serie de condiciones comunes, así como inspeccionar otros criterios de
solicitud específicos de la aplicación:
$isPost = $this->request->is(“post”);
También puede ampliar los detectores de solicitudes que están disponibles, utilizando
Cake\Http\ServerRequest::addDetector()
para crear nuevos tipos de detectores. Hay diferentes tipos de
detectores que puedes crear:
Comparación de valores del entorno: compara un valor obtenido de env()
para determinar su igualdad con el
valor proporcionado.
Comparación del valor del encabezado: si el encabezado especificado existe con el valor especificado o si el invocable
devuelve verdadero.
Comparación de valores de patrón: la comparación de valores de patrón le permite comparar un valor obtenido de
env()
con una expresión regular.
Comparación basada en opciones: las comparaciones basadas en opciones utilizan una lista de opciones para crear una
expresión regular. Las llamadas posteriores para agregar un detector de opciones ya definido fusionarán las opciones.
Detectores de devolución de llamada: los detectores de devolución de llamada le permiten proporcionar un tipo de
«callback» para manejar la verificación. La devolución de llamada recibirá el objeto de solicitud como único parámetro.
-
Cake\Http\ServerRequest::addDetector($name, $options)
Algunos ejemplos serían:
// Agregue un detector de entorno.
$this->request->addDetector(
'post',
['env' => 'REQUEST_METHOD', 'value' => 'POST']
);
// Agregue un detector de valor de patrón.
$this->request->addDetector(
'iphone',
['env' => 'HTTP_USER_AGENT', 'pattern' => '/iPhone/i']
);
// Agregar un detector de opciones
$this->request->addDetector('internalIp', [
'env' => 'CLIENT_IP',
'options' => ['192.168.0.101', '192.168.0.100']
]);
// Agregue un detector de encabezado con comparación de valores
$this->request->addDetector('fancy', [
'env' => 'CLIENT_IP',
'header' => ['X-Fancy' => 1]
]);
// Agregue un detector de encabezado con comparación invocable
$this->request->addDetector('fancy', [
'env' => 'CLIENT_IP',
'header' => ['X-Fancy' => function ($value, $header) {
return in_array($value, ['1', '0', 'yes', 'no'], true);
}]
]);
// Agregue un detector de devolución de llamada. Debe ser un invocable válido.
$this->request->addDetector(
'awesome',
function ($request) {
return $request->getParam('awesome');
}
);
// Agregue un detector que use argumentos adicionales.
$this->request->addDetector(
'csv',
[
'accept' => ['text/csv'],
'param' => '_ext',
'value' => 'csv',
]
);
Hay varios detectores integrados que puedes utilizar:
is('get')
Verifique si la solicitud actual es un GET.
is('put')
Verifique si la solicitud actual es un PUT.
is('patch')
Verifique si la solicitud actual es un PATCH.
is('post')
Verifique si la solicitud actual es una POST.
is('delete')
Verifique si la solicitud actual es DELETE.
is('head')
Verifique si la solicitud actual es HEAD.
is('options')
Verifique si la solicitud actual es OPTIONS.
is('ajax')
Verifique si la solicitud actual vino con X-Requested-With = XMLHttpRequest.
is('ssl')
Compruebe si la solicitud se realiza a través de SSL.
is('flash')
Verifique si la solicitud tiene un User-Agent de Flash.
is('json')
Verifique si la solicitud tiene la extensión “json” y acepte el tipo mime “application/json”.
is('xml')
Verifique si la solicitud tiene la extensión “xml” y acepte el tipo mime “application/xml” o “text/xml”.
ServerRequest
También incluye métodos como Cake\Http\ServerRequest::domain()
,
Cake\Http\ServerRequest::subdomains()
y Cake\Http\ServerRequest::host()
para simplificar las
aplicaciones que utilizan subdominios.
Datos de sesión
Para acceder a la sesión para una solicitud determinada utilice el método getSession()
o utilice el atributo
session
:
$session = $this->request->getSession();
$session = $this->request->getAttribute('session');
$data = $session->read('sessionKey');
Para obtener más información, consulte la documentación Sesiones sobre cómo utilizar el objeto de
sesión.
Host y nombre de dominio
-
Cake\Http\ServerRequest::domain($tldLength = 1)
Devuelve el nombre de dominio en el que se ejecuta su aplicación:
// Muestra 'example.org'
echo $request->domain();
-
Cake\Http\ServerRequest::subdomains($tldLength = 1)
Devuelve los subdominios en los que se ejecuta su aplicación como una matriz:
// Regresa ['my', 'dev'] de 'my.dev.example.org'
$subdomains = $request->subdomains();
-
Cake\Http\ServerRequest::host()
Devuelve el host en el que se encuentra su aplicación:
// Muestra 'my.dev.example.org'
echo $request->host();
Leyendo el método HTTP
-
Cake\Http\ServerRequest::getMethod()
Devuelve el método HTTP con el que se realizó la solicitud:
// Salida POST
echo $request->getMethod();
Restringir qué método HTTP acepta una acción
-
Cake\Http\ServerRequest::allowMethod($methods)
Establecer métodos HTTP permitidos. Si no coincide, arrojará MethodNotAllowedException
. La respuesta 405 incluirá el
encabezado Allow
requerido con los métodos pasados:
public function delete()
{
// Solo acepte solicitudes POST y DELETE
$this->request->allowMethod(['post', 'delete']);
...
}
Lectura de encabezados HTTP
Le permite acceder a cualquiera de los encabezados HTTP_*
que se utilizaron para la solicitud. Por ejemplo:
// Obtener el encabezado como una cadena
$userAgent = $this->request->getHeaderLine('User-Agent');
// Obtenga una matriz de todos los valores.
$acceptHeader = $this->request->getHeader('Accept');
// Comprobar si existe un encabezado
$hasAcceptHeader = $this->request->hasHeader('Accept');
Si bien algunas instalaciones de Apache no hacen que el encabezado Authorization
sea accesible, CakePHP lo hará
disponible a través de métodos específicos de Apache según sea necesario.
-
Cake\Http\ServerRequest::referer($local = true)
Devuelve la dirección de referencia de la solicitud.
-
Cake\Http\ServerRequest::clientIp()
Devuelve la dirección IP del visitante actual.
Confiar en los encabezados de proxy
Si su aplicación está detrás de un balanceador de carga o se ejecuta en un servicio en la nube, a menudo obtendrá el
host, el puerto y el esquema del balanceador de carga en sus solicitudes. A menudo, los balanceadores de carga también
enviarán encabezados HTTP-X-Forwarded-*
con los valores originales. CakePHP no utilizará los encabezados reenviados
de fábrica. Para que el objeto de solicitud utilice estos encabezados, establezca la propiedad trustProxy
en true
:
$this->request->trustProxy = true;
// Estos métodos ahora utilizarán los encabezados proxy.
$port = $this->request->port();
$host = $this->request->host();
$scheme = $this->request->scheme();
$clientIp = $this->request->clientIp();
Una vez que se confía en los servidores proxy, el método clientIp()
utilizará la última dirección IP en el
encabezado X-Forwarded-For
. Si su aplicación está detrás de varios servidores proxy, puede usar
setTrustedProxies()
para definir las direcciones IP de los servidores proxy bajo su control:
$request->setTrustedProxies(['127.1.1.1', '127.8.1.3']);
Después de que los servidores proxy sean confiables, clientIp()
usará la primera dirección IP en el encabezado
X-Forwarded-For
siempre que sea el único valor que no provenga de un proxy confiable.
Comprobando encabezados aceptados
-
Cake\Http\ServerRequest::accepts($type = null)
Descubra qué tipos de contenido acepta el cliente o compruebe si acepta un tipo de contenido en particular.
Consigue todos los tipos:
$accepts = $this->request->accepts();
Consulta por un solo tipo:
$acceptsJson = $this->request->accepts('application/json');
-
Cake\Http\ServerRequest::acceptLanguage($language = null)
Obtenga todos los idiomas aceptados por el cliente o verifique si se acepta un idioma específico.
Obtenga la lista de idiomas aceptados:
$acceptsLanguages = $this->request->acceptLanguage();
Compruebe si se acepta un idioma específico:
$acceptsSpanish = $this->request->acceptLanguage('es-es');
Leyendo Cookies
Las cookies de solicitud se pueden leer a través de varios métodos:
// Obtenga el valor de la cookie, o nulo si falta la cookie.
$rememberMe = $this->request->getCookie(“remember_me”);
// Lea el valor u obtenga el valor predeterminado de 0
$rememberMe = $this->request->getCookie(“remember_me”, 0);
// Obtener todas las cookies como hash
$cookies = $this->request->getCookieParams();
// Obtener una instancia de CookieCollection
$cookies = $this->request->getCookieCollection()
Consulte la documentación Cake\Http\Cookie\CookieCollection
para saber cómo trabajar con la recopilación
de cookies.
Archivos cargados
Las solicitudes exponen los datos del archivo cargado en getData()
o getUploadedFiles()
como objetos
UploadedFileInterface
:
// Obtener una lista de objetos UploadedFile
$files = $request->getUploadedFiles();
// Lea los datos del archivo.
$files[0]->getStream();
$files[0]->getSize();
$files[0]->getClientFileName();
// Mover el archivo
$files[0]->moveTo($targetPath);
Manipulación de URI
Las solicitudes contienen un objeto URI, que contiene métodos para interactuar con el URI solicitado:
// Obtener la URI
$uri = $request->getUri();
// Leer datos de la URI.
$path = $uri->getPath();
$query = $uri->getQuery();
$host = $uri->getHost();
Respueta (Response)
-
class Cake\Http\Response
Cake\Http\Response
es la clase de respuesta predeterminada en CakePHP. Encapsula una serie de
características y funcionalidades para generar respuestas HTTP en su aplicación. También ayuda en las pruebas, ya que se
puede simular o eliminar, lo que le permite inspeccionar los encabezados que se enviarán.
Response
proporciona una interfaz para envolver las tareas comunes relacionadas con la respuesta, como por ejemplo:
Envío de encabezados para redireccionamientos.
Envío de encabezados de tipo de contenido.
Envío de cualquier encabezado.
Envío del cuerpo de la respuesta.
Tratar con tipos de contenido
-
Cake\Http\Response::withType($contentType = null)
Puede controlar el tipo de contenido de las respuestas de su aplicación con Cake\Http\Response::withType()
.
Si su aplicación necesita manejar tipos de contenido que no están integrados en Response, también puede asignarlos con
setTypeMap()
:
// Agregar un tipo de vCard
$this->response->setTypeMap('vcf', ['text/v-card']);
// Establezca el tipo de contenido de respuesta en vcard
$this->response = $this->response->withType('vcf');
Por lo general, querrás asignar tipos de contenido adicionales en la devolución de llamada de tu controlador
beforeFilter()
, para poder aprovechar las funciones de cambio automático de vista de
RequestHandlerComponent
si lo están usando.
Enviando arhivos
-
Cake\Http\Response::withFile(string $path, array $options = [])
Hay ocasiones en las que desea enviar archivos como respuesta a sus solicitudes. Puedes lograrlo usando
Cake\Http\Response::withFile()
:
public function sendFile($id)
{
$file = $this->Attachments->getFile($id);
$response = $this->response->withFile($file['path']);
// Devuelve la respuesta para evitar que el controlador intente representar una vista.
return $response;
}
Como se muestra en el ejemplo anterior, debe pasar la ruta del archivo al método. CakePHP enviará un encabezado de tipo
de contenido adecuado si es un tipo de archivo conocido que figura en Cake\Http\Response::$_mimeTypes. Puede agregar
nuevos tipos antes de llamar a Cake\Http\Response::withFile()
usando el método
Cake\Http\Response::withType()
.
Si lo desea, también puede forzar la descarga de un archivo en lugar de mostrarlo en el navegador especificando las
opciones:
$response = $this->response->withFile(
$file['path'],
['download' => true, 'name' => 'foo']
);
Las opciones admitidas son:
- name
El nombre le permite especificar un nombre de archivo alternativo para enviarlo al usuario.
- download
Un valor booleano que indica si los encabezados deben configurarse para forzar la descarga.
Enviar una cadena como archivo
Puedes responder con un archivo que no existe en el disco, como un pdf o un ics generado sobre la marcha a partir de una
cadena:
public function sendIcs()
{
$icsString = $this->Calendars->generateIcs();
$response = $this->response;
// Inyectar contenido de cadena en el cuerpo de la respuesta
$response = $response->withStringBody($icsString);
$response = $response->withType('ics');
// Opcionalmente forzar la descarga de archivos
$response = $response->withDownload('filename_for_download.ics');
// Devuelve un objeto de respuesta para evitar que el controlador intente representar una vista.
return $response;
}
Configuración de encabezados
La configuración de los encabezados se realiza con el método Cake\Http\Response::withHeader()
. Como todos
los métodos de la interfaz PSR-7, este método devuelve una instancia nueva con el nuevo encabezado:
// Agregar/reemplazar un encabezado
$response = $response->withHeader('X-Extra', 'My header');
// Establecer múltiples encabezados
$response = $response->withHeader('X-Extra', 'My header')
->withHeader('Location', 'http://example.com');
// Agregar un valor a un encabezado existente
$response = $response->withAddedHeader('Set-Cookie', 'remember_me=1');
Los encabezados no se envían cuando se configuran. En cambio, se retienen hasta que Cake\Http\Server
emite la
respuesta.
Ahora puede utilizar el método conveniente Cake\Http\Response::withLocation()
para configurar u obtener
directamente el encabezado de ubicación de redireccionamiento.
Configurando el cuerpo
-
Cake\Http\Response::withStringBody($string)
Para establecer una cadena como cuerpo de respuesta, haga lo siguiente:
// Coloca una cadena en el cuerpo.
$response = $response->withStringBody(“My Body”);
// Si quieres una respuesta json
$response = $response->withType(“application/json”)->withStringBody(json_encode([“Foo” => “bar”]));
-
Cake\Http\Response::withBody($body)
Para configurar el cuerpo de la respuesta, use el método withBody()
, que es proporcionado por
Laminas\Diactoros\MessageTrait
:
$response = $response->withBody($stream);
Asegúrese de que $stream
sea un objeto Psr\Http\Message\StreamInterface
. Vea a continuación cómo
crear un nuevo stream.
También puedes transmitir respuestas desde archivos usando Laminas\Diactoros\Stream
streams:
// Para transmitir desde un archivo
use Laminas\Diactoros\Stream;
$stream = new Stream('/path/to/file', 'rb');
$response = $response->withBody($stream);
También puedes transmitir respuestas desde una devolución de llamada usando CallbackStream
. Esto es útil cuando tiene
recursos como imágenes, archivos CSV o PDF que necesita transmitir al cliente:
// Transmisión desde una devolución de llamada
use Cake\Http\CallbackStream;
// Crea una imagen.
$img = imagecreate(100, 100);
// ...
$stream = new CallbackStream(function () use ($img) {
imagepng($img);
});
$response = $response->withBody($stream);
Configuración del juego de caracteres
-
Cake\Http\Response::withCharset($charset)
Establece el juego de caracteres que se utilizará en la respuesta:
$this->response = $this->response->withCharset('UTF-8');
Interactuar con el almacenamiento en caché del navegador
-
Cake\Http\Response::withDisabledCache()
A veces es necesario obligar a los navegadores a no almacenar en caché los resultados de una acción del controlador.
Cake\Http\Response::withDisabledCache()
está destinado precisamente a eso:
public function index()
{
// Deshabilitar el almacenamiento en caché
$this->response = $this->response->withDisabledCache();
}
Advertencia
Deshabilitar el almacenamiento en caché de dominios SSL al intentar enviar archivos a Internet Explorer puede
generar errores.
-
Cake\Http\Response::withCache($since, $time = '+1 day')
También puede decirles a los clientes que desea que almacenen en caché las respuestas. Usando
Cake\Http\Response::withCache()
:
public function index()
{
// Habilitar el almacenamiento en caché
$this->response = $this->response->withCache('-1 minute', '+5 days');
}
Lo anterior les indicaría a los clientes que guarden en caché la respuesta resultante durante 5 días, con la esperanza
de acelerar la experiencia de sus visitantes. El método withCache()
establece el valor Última modificación
en el
primer argumento. El encabezado Expires
y la directiva max-age
se establecen en función del segundo parámetro.
La directiva «pública» de Cache-Control también está configurada.
Ajuste fino de la caché HTTP
Una de las mejores y más sencillas formas de acelerar su aplicación es utilizar la caché HTTP. Según este modelo de
almacenamiento en caché, solo debe ayudar a los clientes a decidir si deben usar una copia en caché de la respuesta
configurando algunos encabezados, como la hora de modificación y la etiqueta de entidad de respuesta.
En lugar de obligarlo a codificar la lógica para el almacenamiento en caché y para invalidarla (actualizarla) una vez que
los datos han cambiado, HTTP utiliza dos modelos, caducidad y validación, que generalmente son mucho más simples de usar.
Además de usar Cake\Http\Response::withCache()
, también puedes usar muchos otros métodos para ajustar los
encabezados de caché HTTP para aprovechar el almacenamiento en caché del navegador o del proxy inverso.
El encabezado de control de caché
-
Cake\Http\Response::withSharable($public, $time = null)
Utilizado bajo el modelo de vencimiento, este encabezado contiene múltiples indicadores que pueden cambiar la forma en
que los navegadores o servidores proxy usan el contenido almacenado en caché. Un encabezado Cache-Control
puede
verse así:
Cache-Control: private, max-age=3600, must-revalidate
La clase Response
le ayuda a configurar este encabezado con algunos métodos de utilidad que producirán un encabezado
Cache-Control
final válido. El primero es el método withSharable()
, que indica si una respuesta debe considerarse
compartible entre diferentes usuarios o clientes. Este método en realidad controla la parte «pública» o «privada» de este
encabezado. Establecer una respuesta como privada indica que toda o parte de ella está destinada a un solo usuario. Para
aprovechar las cachés compartidas, la directiva de control debe configurarse como pública.
El segundo parámetro de este método se utiliza para especificar una max-age
para el caché, que es el número de
segundos después de los cuales la respuesta ya no se considera nueva:
public function view()
{
// ...
// Configure Cache-Control como público durante 3600 segundos
$this->response = $this->response->withSharable(true, 3600);
}
public function my_data()
{
// ...
// Configure Cache-Control como privado durante 3600 segundos
$this->response = $this->response->withSharable(false, 3600);
}
Response
expone métodos separados para configurar cada una de las directivas en el encabezado Cache-Control
.
El encabezado de vencimiento
-
Cake\Http\Response::withExpires($time)
Puede configurar el encabezado Expires
en una fecha y hora después de la cual la respuesta ya no se considera nueva.
Este encabezado se puede configurar usando el método withExpires()
:
public function view()
{
$this->response = $this->response->withExpires('+5 days');
}
Este método también acepta una instancia DateTime
o cualquier cadena que pueda ser analizada por la clase
DateTime
.
El encabezado de la etiqueta electrónica
-
Cake\Http\Response::withEtag($tag, $weak = false)
La validación de caché en HTTP se usa a menudo cuando el contenido cambia constantemente y le pide a la aplicación que
solo genere el contenido de la respuesta si el caché ya no está actualizado. Bajo este modelo, el cliente continúa
almacenando páginas en el caché, pero pregunta a la aplicación cada vez si el recurso ha cambiado, en lugar de usarlo
directamente. Esto se usa comúnmente con recursos estáticos como imágenes y otros activos.
El método withEtag()
(llamado etiqueta de entidad) es una cadena que identifica de forma única el recurso solicitado,
como lo hace una suma de comprobación para un archivo, para determinar si coincide con un recurso almacenado en caché.
Para aprovechar este encabezado, debe llamar al método isNotModified()
manualmente o incluir
Checking HTTP Cache en su controlador:
public function index()
{
$articles = $this->Articles->find('all')->all();
// Suma de comprobación simple del contenido del artículo.
// Debería utilizar una implementación más eficiente en una aplicación del mundo real.
$checksum = md5(json_encode($articles));
$response = $this->response->withEtag($checksum);
if ($response->isNotModified($this->request)) {
return $response;
}
$this->response = $response;
// ...
}
Nota
La mayoría de los usuarios de proxy probablemente deberían considerar usar el encabezado de última modificación en
lugar de Etags por razones de rendimiento y compatibilidad.
El último encabezado modificado
-
Cake\Http\Response::withModified($time)
Además, bajo el modelo de validación de caché HTTP, puede configurar el encabezado Last-Modified
para indicar la
fecha y hora en la que se modificó el recurso por última vez. Configurar este encabezado ayuda a CakePHP a decirle a los
clientes de almacenamiento en caché si la respuesta se modificó o no según su caché.
Para aprovechar este encabezado, debe llamar al método isNotModified()
manualmente o incluir
Checking HTTP Cache en su controlador:
public function view()
{
$article = $this->Articles->find()->first();
$response = $this->response->withModified($article->modified);
if ($response->isNotModified($this->request)) {
return $response;
}
$this->response;
// ...
}
El encabezado variable
-
Cake\Http\Response::withVary($header)
En algunos casos, es posible que desee publicar contenido diferente utilizando la misma URL. Este suele ser el caso si
tiene una página multilingüe o responde con HTML diferente según el navegador. En tales circunstancias, puede utilizar
el encabezado Vary
:
$response = $this->response->withVary('User-Agent');
$response = $this->response->withVary('Accept-Encoding', 'User-Agent');
$response = $this->response->withVary('Accept-Language');
Envío de respuestas no modificadas
-
Cake\Http\Response::isNotModified(Request $request)
Compara los encabezados de la caché del objeto de solicitud con el encabezado de la caché de la respuesta y determina
sitodavía se puede considerar nuevo. Si es así, elimina el contenido de la respuesta y envía el encabezado
304 Not Modified:
// En una acción del controlador.
if ($this->response->isNotModified($this->request)) {
return $this->response;
}
Configuración de cookies
Las cookies se pueden agregar a la respuesta usando una matriz o un objeto Cake\Http\Cookie\Cookie
:
use Cake\Http\Cookie\Cookie;
use DateTime;
// Agregar una cookie
$this->response = $this->response->withCookie(Cookie::create(
'remember_me',
'yes',
// Todas las claves son opcionales.
[
'expires' => new DateTime('+1 year'),
'path' => '',
'domain' => '',
'secure' => false,
'httponly' => false,
'samesite' => null // O una de las constantes CookieInterface::SAMESITE_*
]
));
Consulte la sección Creando cookies para saber cómo utilizar el objeto cookie. Puede utilizar
withExpiredCookie()
para enviar una cookie caducada en la respuesta. Esto hará que el navegador elimine su cookie
local:
$this->response = $this->response->withExpiredCookie(new Cookie('remember_me'));