El almacenamiento de datos en caché trata del almacenamiento de alguna variable PHP en caché y recuperarla más tarde del
mismo. También es la base de algunas de las características avanzadas de almacenamiento en caché, tales como
[el almacenamiento en caché de consultas a la base de datos](#query-caching) y
[el almacenamiento en caché de contenido](caching-content.md).
El almacenamiento de datos en caché trata del almacenamiento de alguna variable PHP en caché y recuperarla más tarde del mismo. También es la base de algunas de las características avanzadas de almacenamiento en caché, tales como [el almacenamiento en caché de consultas a la base de datos](#query-caching) y [el almacenamiento en caché de contenido](caching-content.md).
El siguiente código muestra el típico patrón de uso para el almacenamiento en caché, donde la variable `$cache` se
refiere al [componente caché](#cache-components):
El siguiente código muestra el típico patrón de uso para el almacenamiento en caché, donde la variable `$cache` se refiere al [componente caché](#cache-components):
```php
// probar de recuerar $data del caché
// probar de recuperar $data del caché
$data=$cache->get($key);
if($data===false){
// $data no ha sido encontrada en caché, calcularla desde cero
// guardar $data en caché para así recuperarla la próxima vez
$cache->set($key,$data);
}
...
...
@@ -24,13 +19,12 @@ if ($data === false) {
// $data está disponible aquí
```
## Componentes de Caché <a name="cache-components"></a>
El almacenamiento de datos en caché depende de los llamados *cache components* (componentes de caché) los cuales
representan diferentes tipos de almacenamiento en caché, como por ejemplo en memoria, en archivos o en base de datos.
Los Componentes de Caché estan normalmente registrados como componentes de la aplicación para que de esta forma puedan
Los Componentes de Caché están normalmente registrados como componentes de la aplicación para que de esta forma puedan
ser configurados y accesibles globalmente. El siguiente código muestra cómo configurar el componente de aplicación
`cache` para usar [memcached](http://memcached.org/) con dos servidores caché:
...
...
@@ -60,7 +54,6 @@ Debido a que todos los componentes de caché soportan el mismo conjunto de APIs,
subyacente por otro diferente mediante su reconfiguración en la configuración de la aplicación sin tener que modificar
el código que utiliza el caché. Por ejemplo, podrías modificar la configuración anterior para usar [[yii\caching\ApcCache|APC cache]]:
```php
'components'=>[
'cache'=>[
...
...
@@ -69,71 +62,42 @@ el código que utiliza el caché. Por ejemplo, podrías modificar la configuraci
],
```
> Nota: Puedes registrar multiples componentes de aplicación de caché. El componente llamado `cache` es usado por defecto
por muchas caché-dependiente clases (e.g. [[yii\web\UrlManager]]).
> Nota: Puedes registrar múltiples componentes de aplicación de caché. El componente llamado `cache` es usado por defecto por muchas caché-dependiente clases (e.g. [[yii\web\UrlManager]]).
### Almacenamientos de Caché Soportados <a name="supported-cache-storage"></a>
Yii proporciona varios componentes de caché que pueden almacenar datos en diferentes medios. A continuación
se muestra un listado con los componentes de caché disponibles:
*[[yii\caching\ApcCache]]: utiliza la extensión de PHP [APC](http://php.net/manual/en/book.apc.php). Esta opción puede
ser considerada como la más rápida de entre todas las disponibles para una aplicación centralizada. (p. ej. un servidor,
no dedicado balance de carga, etc).
*[[yii\caching\DbCache]]: utiliza una tabla de base de datos para almacenar los datos. Por defecto, se creará y usará
como base de datos [SQLite3](http://sqlite.org/) en el directorio runtime. Se puede especificar explicitamente que base
de datos va a ser utilizada configurando la propiedad `db`.
*[[yii\caching\DummyCache]]: dummy cache (caché tonta) que no almacena en caché nada. El propósito de este componente
es simplificar el código necesario para chequear la disponibilidad de caché. Por ejemplo, durante el desarrollo o
si el servidor no tiene soporte de caché actualmente, puede utilizarse este componente de caché. Cuando este disponible
un soporte en caché, puede cambiarse el componente correspondiente. En ambos casos, puede utilizarse el mismo código
`Yii::$app->cache->get($key)` para recuperar un dato sin la preocupación de que `Yii::$app->cache` pueda ser `null`.
*[[yii\caching\FileCache]]: utiliza un fichero estándar para almacenar los datos. Esto es adecuado para almacenar
grandes bloques de datos (como páginas).
*[[yii\caching\MemCache]]: utiliza las extensiones de PHP [memcache](http://php.net/manual/en/book.memcache.php)
y [memcached](http://php.net/manual/en/book.memcached.php). Esta opción puede ser considerada como la más rápida
cuando la caché es manejada en una aplicación distribuida (p. ej. con varios servidores, con balance de carga, etc..)
*[[yii\redis\Cache]]: implementa un componente de caché basado en [Redis](http://redis.io/) que almacenan pares
clave-valor (requiere la versión 2.6.12 de redis).
*[[yii\caching\WinCache]]: utiliza la extensión de PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension)
*[[yii\caching\ApcCache]]: utiliza la extensión de PHP [APC](http://php.net/manual/en/book.apc.php). Esta opción puede ser considerada como la más rápida de entre todas las disponibles para una aplicación centralizada. (p. ej. un servidor,no dedicado balance de carga, etc).
*[[yii\caching\DbCache]]: utiliza una tabla de base de datos para almacenar los datos. Por defecto, se creará y usará como base de datos [SQLite3](http://sqlite.org/) en el directorio runtime. Se puede especificar explícitamente que base de datos va a ser utilizada configurando la propiedad `db`.
*[[yii\caching\DummyCache]]: dummy cache (caché tonta) que no almacena en caché nada. El propósito de este componente es simplificar el código necesario para chequear la disponibilidad de caché. Por ejemplo, durante el desarrollo o si el servidor no tiene soporte de caché actualmente, puede utilizarse este componente de caché. Cuando este disponible un soporte en caché, puede cambiarse el componente correspondiente. En ambos casos, puede utilizarse el mismo código `Yii::$app->cache->get($key)` para recuperar un dato sin la preocupación de que `Yii::$app->cache` pueda ser `null`.
*[[yii\caching\FileCache]]: utiliza un fichero estándar para almacenar los datos. Esto es adecuado para almacenar grandes bloques de datos (como páginas).
*[[yii\caching\MemCache]]: utiliza las extensiones de PHP [memcache](http://php.net/manual/en/book.memcache.php) y [memcached](http://php.net/manual/en/book.memcached.php). Esta opción puede ser considerada como la más rápida cuando la caché es manejada en una aplicación distribuida (p. ej. con varios servidores, con balance de carga, etc..)
*[[yii\redis\Cache]]: implementa un componente de caché basado en [Redis](http://redis.io/) que almacenan pares clave-valor (requiere la versión 2.6.12 de redis).
*[[yii\caching\WinCache]]: utiliza la extensión de PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension)([ver también](http://php.net/manual/en/book.wincache.php)).
*[[yii\caching\XCache]]: utiliza la extensión de PHP [XCache](http://xcache.lighttpd.net/).
*[[yii\caching\ZendDataCache]]: utiliza
[Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm)
como el medio fundamental de caché.
*[[yii\caching\ZendDataCache]]: utiliza [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm) como el medio fundamental de caché.
> Nota: Puedes utililizar diferentes tipos de almacenamiento de caché en la misma aplicación. Una estrategia común es la
de usar almacenamiento de caché en memoria par almacenar datos que son pequeños pero que son utilizados constantemente
(por ejemplo, datos estadísticos), y utilizar el almacenamiento de caché en archivos o en base de datos para guardar
datos que son grandes y utilizados con menor frecuencia (por ejemplo, contenido de página).
> Nota: Puedes utilizar diferentes tipos de almacenamiento de caché en la misma aplicación. Una estrategia común es la de usar almacenamiento de caché en memoria par almacenar datos que son pequeños pero que son utilizados constantemente (por ejemplo, datos estadísticos), y utilizar el almacenamiento de caché en archivos o en base de datos para guardar datos que son grandes y utilizados con menor frecuencia (por ejemplo, contenido de página).
## API de Caché <a name="cache-apis"></a>
Todos los componentes de almacenamiento de caché provienen de la misma clase "padre" [[yii\caching\Cache]] y por lo tanto
soportan la siguiente API:
Todos los componentes de almacenamiento de caché provienen de la misma clase "padre" [[yii\caching\Cache]] y por lo tanto soportan la siguiente API:
*[[yii\caching\Cache::get()|get()]]: recupera un elemento de datos de la memoria caché con una clave especificada.
Un valor nulo será devuelto si el elemento de datos no ha sido encontrado en la memoria caché o si ha expirado o ha sido
invalidado.
Un valor nulo será devuelto si el elemento de datos no ha sido encontrado en la memoria caché o si ha expirado o ha sido invalidado.
*[[yii\caching\Cache::set()|set()]]: almacena un elemento de datos identificado por una clave en la memoria caché.
*[[yii\caching\Cache::add()|add()]]: almacena un elemento de datos identificado por una clave en la memoria caché si la
clave no se encuentra en la memoria caché.
*[[yii\caching\Cache::add()|add()]]: almacena un elemento de datos identificado por una clave en la memoria caché si la clave no se encuentra en la memoria caché.
*[[yii\caching\Cache::mget()|mget()]]: recupera varios elementos de datos de la memoria caché con las claves especificadas.
*[[yii\caching\Cache::mset()|mset()]]: almacena múltiples elementos de datos en la memoria caché. Cada elemento se
identifica por una clave.
*[[yii\caching\Cache::madd()|madd()]]: stores multiple data items in cache. Each item is identified by a key.
If a key already exists in the cache, the data item will be skipped.
*[[yii\caching\Cache::exists()|exists()]]: devuelve un valor que indica si la clave especificada se encuentra en la
memoria caché.
*[[yii\caching\Cache::mset()|mset()]]: almacena múltiples elementos de datos en la memoria caché. Cada elemento se identifica por una clave.
*[[yii\caching\Cache::madd()|madd()]]: almacena múltiples elementos de datos en la memoria cache. Cada elemento se identifica don una clave. Si una clave ya existe en la cache, el elemento será omitido.
*[[yii\caching\Cache::exists()|exists()]]: devuelve un valor que indica si la clave especificada se encuentra en la memoria caché.
*[[yii\caching\Cache::delete()|delete()]]: elimina un elemento de datos identificado por una clave de la caché.
*[[yii\caching\Cache::flush()|flush()]]: elimina todos los elementos de datos de la cache.
Algunos sistemas de almacenamiento de caché, como por ejemplo MemCache, APC, pueden recuperar multiples valores
almacenados en modo de lote (batch), lo que puede reducir considerablemente la sobrecarga que implica la recuperación
de datos almacenados en el caché. Las API [[yii\caching\Cache::mget()|mget()]] y [[yii\caching\Cache::madd()|madd()]]
se proporcionan para utilizar esta característia. En el caso de que el sistema de memoria caché no lo soportara, ésta
sería simulada.
Algunos sistemas de almacenamiento de caché, como por ejemplo MemCache, APC, pueden recuperar múltiples valores almacenados en modo de lote (batch), lo que puede reducir considerablemente la sobrecarga que implica la recuperación de datos almacenados en el caché. Las API [[yii\caching\Cache::mget()|mget()]] y [[yii\caching\Cache::madd()|madd()]]
se proporcionan para utilizar esta característica. En el caso de que el sistema de memoria caché no lo soportara, ésta sería simulada.
Puesto que [[yii\caching\Cache]] implementa `ArrayAccess`, un componente de caché puede ser usado como una matriz (array).
Cada elemento de datos almacenado en caché se identifica por una clave. Cuando se almacena un elemento de datos en la
memoria caché, se debe especificar una clave. Más tarde, cuando se recupera el elemento de datos de la memoria caché,
se debe proporcionar la tecla correspondiente.
Cada elemento de datos almacenado en caché se identifica por una clave. Cuando se almacena un elemento de datos en la memoria caché, se debe especificar una clave. Más tarde, cuando se recupera el elemento de datos de la memoria caché, se debe proporcionar la tecla correspondiente.
Puedes utilizar una cadena o un valor arbitrario como una clave de caché. Cuando una clave no es una cadena de texto,
ésta será automáticamente serializada en una cadena.
Puedes utilizar una cadena o un valor arbitrario como una clave de caché. Cuando una clave no es una cadena de texto, ésta será automáticamente serializada en una cadena.
Una estrategia común para definir una clave de caché es incluir en ella todos los factores determinantes en términos de
una matriz. Por ejemplo, [[yii\db\Schema]] utiliza la siguiente clave para almacenar en caché la información del esquema
de una tabla de base de datos:
Una estrategia común para definir una clave de caché es incluir en ella todos los factores determinantes en términos de una matriz. Por ejemplo, [[yii\db\Schema]] utiliza la siguiente clave para almacenar en caché la información del esquema de una tabla de base de datos:
```php
[
...
...
@@ -166,35 +124,24 @@ de una tabla de base de datos:
];
```
Como puedes ver, la clave incluye toda la información necesaria para especificar de una forma exclusiva una tabla de
base de datos.
Como puedes ver, la clave incluye toda la información necesaria para especificar de una forma exclusiva una tabla de base de datos.
Cuando el un mismo almacenamiento en caché es utilizado por diferentes aplicaciones, se debería especificar un prefijo
único para las claves de de caché por cada una de las aplicaciones para así evitar conflictos. Esto puede hacerse
mediante la configuración de la propiedad [[yii\caching\Cache::keyPrefix]]. Por ejemplo, en la configuración de la
aplicación podrías escribir el siguiente código:
Cuando el un mismo almacenamiento en caché es utilizado por diferentes aplicaciones, se debería especificar un prefijo único para las claves de de caché por cada una de las aplicaciones para así evitar conflictos. Esto puede hacerse mediante la configuración de la propiedad [[yii\caching\Cache::keyPrefix]]. Por ejemplo, en la configuración de la aplicación podrías escribir el siguiente código:
```php
'components'=>[
'cache'=>[
'class'=>'yii\caching\ApcCache',
'keyPrefix'=>'myapp',// un prefixo de clave de caché único
'keyPrefix'=>'myapp',// un prefijo de clave de caché único
],
],
```
Para garantizar la interoperabilidad, deberían utilizarse sólo caracteres alfanuméricos.
### Caducidad de Caché <a name="cache-expiration"></a>
Un elemento de datos almacenado en la memoria caché permanecerá en ella para siempre, a menos que sea removida de alguna
manera debido a alguna directiva de caché (por ejemplo, el espacio de almacenamiento en caché está lleno y los datos
más antiguos se eliminan). Para cambiar este comportamiento, podrías proporcionar un parámetro de caducidad al llamar
[[yii\caching\Cache::set()|set()]] para guardar el elemento de datos. El parámetro nos indica por cuántos segundos el
elemento se mantendrá válido en memoria caché. Cuando llames [[yii\caching\Cache::get()|get()]] para recuperar el
elemento, si el tiempo de caducidad ha pasado, el método devolverá `false`, indicando que el elemento de datos no ha
sido encontrado en la memoria caché. Por ejemplo,
Un elemento de datos almacenado en la memoria caché permanecerá en ella para siempre, a menos que sea removida de alguna manera debido a alguna directiva de caché (por ejemplo, el espacio de almacenamiento en caché está lleno y los datos más antiguos se eliminan). Para cambiar este comportamiento, podrías proporcionar un parámetro de caducidad al llamar [[yii\caching\Cache::set()|set()]] para guardar el elemento de datos. El parámetro nos indica por cuántos segundos el elemento se mantendrá válido en memoria caché. Cuando llames [[yii\caching\Cache::get()|get()]] para recuperar el elemento, si el tiempo de caducidad ha pasado, el método devolverá `false`, indicando que el elemento de datos no ha sido encontrado en la memoria caché. Por ejemplo,
```php
// guardar los datos en memoria caché al menos 45 segundos
...
...
@@ -208,19 +155,11 @@ if ($data === false) {
}
```
### Dependencias de Caché <a name="cache-dependencies"></a>
### Dependecias de Caché <a name="cache-dependencies"></a>
Además de configurar el tiempo de expiración, los datos almacenados en caché pueden también ser invalidados conforme
a algunos cambios en las dependencias (cache dependencies). Por ejemplo, [[yii\caching\FileDependency]] representa
la dependencia del tiempo de modificación del archivo. Cuando esta dependencia cambia, significa que el archivo
correspondiente ha cambiado. Como resultado, cualquier contenido anticuado que sea encontrado en el caché debería
ser invalidado y la llamada a [[yii\caching\Cache::get()|get()]] debería devolver `null`.
Una dependencia es representada como una instancia de [[yii\caching\Dependency]] o su clase hija. Cuando llamas
[[yii\caching\Cache::set()|set()]] para almacenar un elemento de datos en el caché, puedes pasar el objeto de dependencia
asociado. Por ejemplo,
Además de configurar el tiempo de expiración, los datos almacenados en caché pueden también ser invalidados conforme a algunos cambios en la caché de dependencias. Por ejemplo, [[yii\caching\FileDependency]] representa la dependencia del tiempo de modificación del archivo. Cuando esta dependencia cambia, significa que el archivo correspondiente ha cambiado. Como resultado, cualquier contenido anticuado que sea encontrado en el caché debería ser invalidado y la llamada a [[yii\caching\Cache::get()|get()]] debería devolver `null`.
Una dependencia es representada como una instancia de [[yii\caching\Dependency]] o su clase hija. Cuando llamas [[yii\caching\Cache::set()|set()]] para almacenar un elemento de datos en el caché, puedes pasar el objeto de dependencia asociado. Por ejemplo,
```php
// Crear una dependencia sobre el tiempo de modificación del archivo example.txt.
// También chequeará si la dependencia ha cambiado.
// Devolerá false si se encuentran algunas de esas condiciones.
// Devolverá false si se encuentran algunas de esas condiciones.
$data=$cache->get($key);
```
...
...
@@ -251,8 +190,7 @@ Aquí abajo se muestra un sumario de las dependencias disponibles:
Las consultas en caché es una característica especial de caché construido sobre el almacenamiento de caché de datos. Se
proporciona para almacenar en caché el resultado de consultas a la base de datos.
Las consultas en caché requieren una [[yii\db\Connection|conexión a BD]] y un componente de aplicación
caché válido. El uso básico de las consultas en memoria caché es el siguiente, asumiendo `db` es una instancia [[yii\db\Connection]]:
Las consultas en caché requieren una [[yii\db\Connection|conexión a BD]] y un componente de aplicación caché válido. El uso básico de las consultas en memoria caché es el siguiente, asumiendo `db` es una instancia [[yii\db\Connection]]:
```php
$duration=60;// guardar en caché el resultado de la consulta por 60 segundos.
...
...
@@ -266,33 +204,23 @@ $db->endCache();
```
Como puedes ver, cualquier consulta SQL entre las llamadas `beginCache()` y `endCache()` serán guardadas en la memoria caché.
Si el resultado de la misma consulta se encuentra vigente en la memoria caché, la consulta se omitirá y el resultado
se servirá de la memoria caché en su lugar.
Si el resultado de la misma consulta se encuentra vigente en la memoria caché, la consulta se omitirá y el resultado se servirá de la memoria caché en su lugar.
El almacenamiento en caché de consultas se puede usar para [DAO](db-dao.md), así como para [ActiveRecord](db-active-record.md).
> Nota: Algunos DBMS (por ejemplo, [MySQL](http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)) también soporta
el almacenamiento en caché desde el mismo servidor de la BD. Puedes optar por utilizar cualquiera de los mecanismos
de memoria caché. El almacenamiento en caché de consultas previamente descrito tiene la ventaja que de que se puede
especificar dependencias de caché de una forma flexible y son potencialmente mucho más eficientes.
> Nota: Algunos DBMS (por ejemplo, [MySQL](http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)) también soporta el almacenamiento en caché desde el mismo servidor de la BD. Puedes optar por utilizar cualquiera de los mecanismos de memoria caché. El almacenamiento en caché de consultas previamente descrito tiene la ventaja que de que se puede especificar dependencias de caché de una forma flexible y son potencialmente mucho más eficientes.
Las consultas en caché tienen dos opciones configurables a traves de [[yii\db\Connection]]:
Las consultas en caché tienen dos opciones configurables a través de [[yii\db\Connection]]:
*[[yii\db\Connection::queryCacheDuration|queryCacheDuration]]: esto representa el número de segundos que un resultado
de la consulta permanecerá válido en la memoria caché. La duración será sobrescrita si se llama a
[[yii\db\Connection::beginCache()]] con un parámetro explícito de duración.
*[[yii\db\Connection::queryCacheDuration|queryCacheDuration]]: esto representa el número de segundos que un resultado de la consulta permanecerá válido en la memoria caché. La duración será sobrescrita si se llama a [yii\db\Connection::beginCache()]] con un parámetro explícito de duración.
*[[yii\db\Connection::queryCache|queryCache]]: representa el ID del componente de aplicación de caché.
Por defecto es `'cache'`. El almacenamiento en caché de consultas se habilita sólo cuando hay un componente de la
aplicación de caché válido.
Por defecto es `cache`. El almacenamiento en caché de consultas se habilita sólo cuando hay un componente de la aplicación de caché válido.
El almacenamiento en caché de consultas no funciona con los resultados de consulta que contienen controladores de recursos.
Por ejemplo, cuando se utiliza el tipo de columna `BLOB` en algunos DBMS, el resultado de la consulta devolverá un recurso
para manejar los datos de la columna.
Por ejemplo, cuando se utiliza el tipo de columna `BLOB` en algunos DBMS, el resultado de la consulta devolverá un recurso para manejar los datos de la columna.
Algunos sistemas de almacenamiento caché tienen limitación de tamaño. Por ejemplo, memcache limita el tamaño máximo
de cada entrada a 1MB. Por lo tanto, si el tamaño de un resultado de la consulta excede ese límite, el almacenamiento
en caché fallará.
Algunos sistemas de almacenamiento caché tienen limitación de tamaño. Por ejemplo, memcache limita el tamaño máximo de cada entrada a 1MB. Por lo tanto, si el tamaño de un resultado de la consulta excede ese límite, el almacenamiento en caché fallará.
Las peticiones(requests) hechas a una aplicación son representadas como objetos [[yii\web\Request]] que proporcionan información como parámetros de la petición, cabeceras HTTP, cookies, etc. Dada una petición, se puede acceder al objeto request correspondiente a través del [componente de aplicación](structure-application-components.md)'request' que, por defecto, es una instancia de [[yii\web\Request]]. En esta sección se describirá como hacer uso de este componente en las aplicaciones.
==========
Las peticiones(requests) hechas a una aplicación son representadas como objetos [[yii\web\Request]] que proporcionan información como parámetros de la petición, cabeceras HTTP, cookies, etc. Dada una petición, se puede acceder al objeto request correspondiente a través del [componente de aplicación](structure-application-components.md)`request` que, por defecto, es una instancia de [[yii\web\Request]]. En esta sección se describirá como hacer uso de este componente en las aplicaciones.
## Parámetros de Request <a name="request-parameters"></a>
Para obtener los parámetros de la petición, se puede llamar a los métodos [[yii\web\Request::get()|get()]] y [[yii\web\Request::post()|post()]] del componente 'request'. Estos devuelven los valores de '$_GET' y '$_POST', respectivamente. Por ejemplo:
Para obtener los parámetros de la petición, se puede llamar a los métodos [[yii\web\Request::get()|get()]] y [[yii\web\Request::post()|post()]] del componente `request`. Estos devuelven los valores de `$_GET` y `$_POST`, respectivamente. Por ejemplo:
>Info: En lugar de acceder directamente a '$_GET' y '$_POST' para obtener los parámetros de la petición, es recomendable que se obtengan mediante el componente 'request' como en el ejemplo anterior. Esto facilitará la creación de tests ya que se puede simular una componente de request con datos de peticiones personalizados.
>Info: En lugar de acceder directamente a `$_GET` y `$_POST` para obtener los parámetros de la petición, es recomendable que se obtengan mediante el componente `request` como en el ejemplo anterior. Esto facilitará la creación de tests ya que se puede simular una componente de request con datos de peticiones personalizados.
Cuando se implementan [APIs RESTful](rest-quick-start.md), a menudo se necesita obtener parámetros enviados desde el formulario a través de PUT, PATCH u otros [métodos de request](runtime-requests.md#request-methods). Se pueden obtener estos parámetros llamando a los métodos [[yii\web\Request::getBodyParam()]]. Por ejemplo:
>Info: A diferencia de los parámetros 'GET', los parámetros enviados desde el formulario a través de 'POST', 'PUT', 'PATCH', etc. se envían en el cuerpo de la petición. El componente 'request' convierte los parámetros cuando se acceda a él a través de los métodos descritos anteriormente. Se puede personalizar la manera en como los parámetros se convierten configurando la propiedad [[yii\web\Request::parsers]].
>Info: A diferencia de los parámetros `GET`, los parámetros enviados desde el formulario a través de `POST`, `PUT`, `PATCH`, etc. se envían en el cuerpo de la petición. El componente `request` convierte los parámetros cuando se acceda a él a través de los métodos descritos anteriormente. Se puede personalizar la manera en como los parámetros se convierten configurando la propiedad [[yii\web\Request::parsers]].
## Métodos de Request <a name="request-methods"></a>
Se puede obtener el método HTTP usado por la petición actual a través de la expresión 'Yii::$app->request->method'. Se proporcionan un conjunto de propiedades booleanas para comprobar si el método actual es de un cierto tipo. Por ejemplo:
Se puede obtener el método HTTP usado por la petición actual a través de la expresión `Yii::$app->request->method`. Se proporcionan un conjunto de propiedades booleanas para comprobar si el método actual es de un cierto tipo. Por ejemplo:
```php
$request=Yii::$app->request;
if($request->isAjax){// la request una request AJAX }
if($request->isAjax){// la request es una request AJAX }
if($request->isGet){// el método de la request es GET }
if($request->isPost){// el método de la request es POST }
if($request->isPut){// el método de la request es PUT }
...
...
@@ -59,9 +59,9 @@ if ($request->isPut) { // el método de la request es PUT }
## URLs de Request <a name="request-urls"></a>
El componente 'request' proporciona muchas maneras de inspeccionar la URL solicitada actualmente.
El componente `request` proporciona muchas maneras de inspeccionar la URL solicitada actualmente.
Asumiendo que la URL que se está solicitando es 'http://example.com/admin/index.php/product?id=100', se pueden obtener varias partes de la URL explicadas en los siguientes puntos:
Asumiendo que la URL que se está solicitando es `http://example.com/admin/index.php/product?id=100`, se pueden obtener varias partes de la URL explicadas en los siguientes puntos:
*[[yii\web\Request::url|url]]: devuelve `/admin/index.php/product?id=100`, que es la URL sin la parte de información del host.
*[[yii\web\Request::absoluteUrl|absoluteUrl]]: devuelve `http://example.com/admin/index.php/product?id=100`, que es la URL entera, incluyendo la parte de información del host.
if($headers->has('User-Agent')){// la cabecera contiene un User-Agent }
```
El componente 'request' también proporciona soporte para acceder rápidamente a las cabeceras usadas más comúnmente, incluyendo:
El componente `request` también proporciona soporte para acceder rápidamente a las cabeceras usadas más comúnmente, incluyendo:
*[[yii\web\Request::userAgent|userAgent]]: devuelve el valor de la cabecera 'User-Agen'.
*[[yii\web\Request::userAgent|userAgent]]: devuelve el valor de la cabecera `User-Agen`.
*[[yii\web\Request::contentType|contentType]]: devuelve el valor de la cabecera `Content-Type` que indica el tipo MIME de los datos del cuerpo de la petición.
*[[yii\web\Request::acceptableContentTypes|acceptableContentTypes]]: devuelve los tipos de contenido MIME aceptado por los usuarios, ordenados por puntuación de calidad. Los que tienen mejor puntuación, se devolverán primero.
*[[yii\web\Request::acceptableLanguages|acceptableLanguages]]: devuelve los idiomas aceptados por el usuario. Los idiomas devueltos son ordenados según su orden de preferencia. El primer elemento representa el idioma preferido.
Cuando una aplicación finaliza la gestión de una [petición(request)](runtime-requests.md), genera un objeto [[yii\web\Response|response]] y lo envía al usuario final. El objeto response contiene información como el código de estado(status code) HTTP y cabeceras(headers) HTTP y body. El objetivo final del desarrollo de una aplicación Web es esencialmente construir objetos de response para varias peticiones.
En la mayoría de casos principalmente se debe tratar con [componentes de aplicación](structure-application-components.md) de tipo `response` que, por defecto, son una instancia de [[yii\web\Response]]. Sin embargo, Yii permite crear sus propios objetos `response` y enviarlos al usuario final tal y como se explica a continuación.
En esta sección, se describirá como generar y enviar respuestas a usuarios finales.
## Códigos de Estado <a name="status-code"></a>
Una de las primeras cosas que debería hacerse cuando se genera una respuesta es indicar si la petición se ha gestionado correctamente. Esto se indica asignando la propiedad [[yii\web\Response::statusCode]] a la que se le puede asignar cualquier valor valido dentro de los [códigos de estado HTTP](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html). Por ejemplo, para indicar que la petición se ha gestionado correctamente, se puede asignar el código de estado a 200, como en el siguiente ejemplo:
```php
Yii::$app->response->statusCode=200;
```
Sin embargo, en la mayoría de casos nos es necesario asignar explícitamente el codigo de estado. Esto se debe a que el valor por defecto de [[yii\web\Response::statusCode]] es 200. Y si se quiere indicar que la petición ha fallado, se puede lanzar una excepción HTTP apropiada como en el siguiente ejemplo:
```php
thrownew\yii\web\NotFoundHttpException;
```
Cuando el [error handler](runtime-handling-errors.md) captura una excepción, obtendrá el código de estado de la excepción y lo asignará a la respuesta. En el caso anterior, la excepción [[yii\web\NotFoundHttpException]] esta asociada al estado HTTP 404. En Yii existen las siguientes excepciones predefinidas.
*[[yii\web\BadRequestHttpException]]: código de estado 400.
*[[yii\web\ConflictHttpException]]: código de estado 409.
*[[yii\web\ForbiddenHttpException]]: código de estado 403.
*[[yii\web\GoneHttpException]]: código de estado 410.
*[[yii\web\MethodNotAllowedHttpException]]: código de estado 405.
*[[yii\web\NotAcceptableHttpException]]: código de estado 406.
*[[yii\web\NotFoundHttpException]]: código de estado 404.
*[[yii\web\ServerErrorHttpException]]: código de estado 500.
*[[yii\web\TooManyRequestsHttpException]]: código de estado 429.
*[[yii\web\UnauthorizedHttpException]]: código de estado 401.
*[[yii\web\UnsupportedMediaTypeHttpException]]: código de estado 415.
Si la excepción que se quiere lanzar no se encuentra en la lista anterior, se puede crear una extendiendo [[yii\web\HttpException]], o directamente lanzando un código de estado, por ejemplo:
```php
thrownew\yii\web\HttpException(402);
```
## Cabeceras HTTP <a name="http-headers"></a>
Se puede enviar cabeceras HTTP modificando el [[yii\web\Response::headers|header collection]] en el componente `response`. Por ejemplo:
```php
$headers=Yii::$app->response->headers;
// añade una cabecera Pragma. Las cabeceras Pragma existentes NO se sobrescribirán.
$headers->add('Pragma','no-cache');
// asigna una cabecera Pragma. Cualquer cabecera Pragma existente sera descartada.
$headers->add('Pragma','no-cache');
// Elimina las cabeceras Pragma y devuelve los valores de las eliminadas en un array
$values=$headers->remove('Pragma');
```
>Info: Los nombres de las cabeceras case insensitive, es decir, no discriminan entre mayúsculas y minúsculas. Además, las nuevas cabeceras registradas no se enviaran al usuario hasta que se llame al método [[yii\web\Response::send()]].
## Body de la Respuesta<a name="response-body"></a>
La mayoría de las respuestas deben tener un body que contenga el contenido que se quiere mostrar a los usuarios finales.
Si ya se tiene un texto de body con formato, se puede asignar a la propiedad [[yii\web\Response::content]] de la respuesta. Por ejemplo:
```php
Yii::$app->response->content='hello world!';
```
Si se tiene que dar formato a los datos antes de enviarlo al usuario final, se deben asignar las propiedades [[yii\web\Response::format|format]] y [[yii\web\Response::data|data]]. La propiedad [[yii\web\Response::format|format]] especifica que formato debe tener [[yii\web\Response::data|data]]. Por ejemplo:
```php
$response=Yii::$app->response;
$response->format=\yii\web\Response::FORMAT_JSON;
$response->data=['message'=>'hello world'];
```
Yii soporta a los siguientes formatos de forma predeterminada, cada uno de ellos implementado por una classe [[yii\web\ResponseFormatterInterface|formatter]]. Se pueden personalizar los formatters o añadir nuevos sobrescribiendo la propiedad [[yii\web\Response::formatters]].
*[[yii\web\Response::FORMAT_HTML|HTML]]: implementado por [[yii\web\HtmlResponseFormatter]].
*[[yii\web\Response::FORMAT_XML|XML]]: implementado por [[yii\web\XmlResponseFormatter]].
*[[yii\web\Response::FORMAT_JSON|JSON]]: implementado por [[yii\web\JsonResponseFormatter]].
*[[yii\web\Response::FORMAT_JSONP|JSONP]]: implementado por [[yii\web\JsonResponseFormatter]].
Mientras el body de la respuesta puede ser mostrado de forma explicita como se muestra a en el anterior ejemplo, en la mayoría de casos se puede asignar implícitamente por el valor retorno de los métodos de [acción](structure-controllers.md). El siguiente, es un ejemplo de uso común:
```php
publicfunctionactionIndex()
{
return$this->render('index');
}
```
La acción `index` anterior, devuelve el resultado renderizado de la vista `index`. el valor devuelto sera recogido por el componente `respuesta`, se le aplicará formato y se enviará al usuario final.
Por defecto, el formato de respuesta es [[yii\web\Response::FORMAT_HTML|HTML]], solo se debe devolver un string en un método de acción. Si se quiere usar un formato de respuesta diferente, se debe asignar antes de devolver los datos. por ejemplo:
Como se ha mencionado, además de usar el componente de aplicación `response` predeterminado, también se pueden crear objetos de respuesta propios y enviarlos a los usuarios finales. Se puede hacer retornando un objeto en el método de acción, como en el siguiente ejemplo:
```php
publicfunctionactionInfo()
{
return\Yii::createObject([
'class'=>'yii\web\Response',
'format'=>\yii\web\Response::FORMAT_JSON,
'data'=>[
'message'=>'hello world',
'code'=>100,
],
]);
}
```
>Nota: Si se crea un objeto de respuesta propio, no se podrán aprovechar las configuraciones asignadas para el componente `response` en la configuración de la aplicación. Sin embargo, se puede usar la [inyección de dependencias](concept-di-container.md) para aplicar la configuración común al nuevo objeto de respuesta.
## Redirección de Navegador <a name="browser-redirection"></a>
La redirección de navegador se basa en el envío de la cabecera HTTP `Location`. Debido a que esta característica se usa comúnmente, Yii proporciona soporte especial para ello.
Se puede redirigir el navegador a una URL llamando al método [[yii\web\Response::redirect()]]. El método asigna la cabecera de `Location` apropiada con la URL proporcionada y devuelve el objeto de respuesta él mismo. En un método de acción, se puede acceder a el mediante el acceso directo [[yii\web\Controller::redirect()]] como en siguiente ejemplo:
En el ejemplo anterior, el método de acción devuelve el resultado del método `redirect()`. Como se ha explicado antes, el objeto de respuesta devuelto por el método de acción se usara como respuesta enviándola al usuario final.
En otros sitios que no sean los métodos de acción, se puede llamar a [[yii\web\Response::redirect()]] directamente seguido por una llamada al método [[yii\web\Response::send()]] para asegurar que no habrá contenido extra en la respuesta.
> Información: De forma predeterminada, el método [[yii\web\Response::redirect()]] asigna el estado de respuesta al código de estado 302 que indica al navegador que recurso solicitado esta *temporalmente* alojado en una URI diferente. Se puede enviar un código de estado 301 para expresar que el recurso se ha movido de forma *permanente*.
Cuando la petición actual es de una petición AJAX, el hecho de enviar una cabecera `Location` no causara una redirección del navegador automática. Para resolver este problema, el método [[yii\web\Response::redirect()]] asigna una cabecera `X-Redirect` con el valor de la URL de redirección. En el lado del cliente se puede escribir código JavaScript para leer la esta cabecera y redireccionar el navegador como corresponda.
> Información: Yii contiene el archivo JavaScript `yii.js` que proporciona un conjunto de utilidades comunes de JavaScript, incluyendo la redirección de navegador basada en la cabecera `X-Redirect`. Por tanto, si se usa este fichero JavaScript (registrandolo *asset bundle* [[yii\web\YiiAsset]]), no se necesitará escribir nada más para tener soporte en redirecciones AJAX.
## Enviar Archivos <a name="sending-files"></a>
Igual que con la redirección, el envío de archivos es otra característica que se basa en cabeceras HTTP especificas. Yii proporciona un conjunto de métodos para dar soporte a varias necesidades del envío de ficheros. Todos ellos incorporan soporte para el rango de cabeceras HTTP.
*[[yii\web\Response::sendFile()]]: envía un fichero existente al cliente.
*[[yii\web\Response::sendContentAsFile()]]: envía un string al cliente como si fuera un archivo .
*[[yii\web\Response::sendStreamAsFile()]]: envía un *file stream* existente al cliente como si fuera un archivo.
Estos métodos tienen la misma firma de método con el objeto de respuesta como valor de retorno. Si el archivo que se envía es muy grande, se debe considerar usar [[yii\web\Response::sendStreamAsFile()]] porque es más efectivo en términos de memoria. El siguiente ejemplo muestra como enviar un archivos en una acción de controlador.
Si se llama al meto de envío de ficheros fuera de un método de acción, también se debe llamar al método [[yii\web\Response::send()]] después para asegurar que no se añada contenido extra a la respuesta.
Algunos servidores Web tienen un soporte especial para enviar ficheros llamado *X-Sendfile*. La idea es redireccionar la petición(request) para un fichero a un servidor Web que servirá el fichero directamente. Como resultado, la aplicación Web puede terminar antes mientras el servidor Web envía el fichero. Para usar esta funcionalidad, se puede llamar a [[yii\web\Response::xSendFile()]]. La siguiente lista resume como habilitar la característica `X-Sendfile` para algunos servidores Web populares.
- Cherokee: [X-Sendfile and X-Accel-Redirect](http://www.cherokee-project.com/doc/other_goodies.html#x-sendfile)
## Enviar la Respuesta <a name="sending-response"></a>
El contenido en una respuesta no se envía al usuario hasta que se llama al método [[yii\web\Response::send()]]. De forma predeterminada, se llama a este método automáticamente al final de [[yii\base\Application::run()]]. Sin embargo, se puede llamar explícitamente a este método forzando el envío de la respuesta inmediatamente.
El método [[yii\web\Response::send()]] sigue los siguientes pasos para enviar una respuesta:
1. Lanza el evento [[yii\web\Response::EVENT_BEFORE_SEND]].
2. Llama a [[yii\web\Response::prepare()]] para convertir el [[yii\web\Response::data|response data]] en [[yii\web\Response::content|response content]].
3. Lanza el evento [[yii\web\Response::EVENT_AFTER_PREPARE]].
4. Llama a [[yii\web\Response::sendHeaders()]] para enviar las cabeceras HTTP registradas.
5. Llama a [[yii\web\Response::sendContent()]] para enviar el contenido del body de la respuesta.
6. Lanza el evento [[yii\web\Response::EVENT_AFTER_SEND]].
Después de llamar a [[yii\web\Response::send()]] por primera vez, cualquier llamada a este método sera ignorada. Esto significa que una vez se envíe una respuesta, no se le podrá añadir más contenido.
Como se puede observar, el método [[yii\web\Response::send()]] lanza varios eventos útiles. Al responder a estos eventos, es posible ajustar o decorar al respuesta.