El objeto response es la contraparte lógica del objeto request. Su
propósito es recopilar contenido y/o cabeceras para que puedan
devolverse en conjunto. Además, el controlador frontal pasará
cualquier excepción capturada al objeto response, permitiendo al
desarrollador manejar las excepciones de forma controlada. Esta
funcionalidad se puede sobrescribir
estableciendo
Zend_Controller_Front::throwExceptions(true):
$front->throwExceptions(true);
Para enviar la salida de la respuesta, incluyendo las cabeceras, utilice
sendResponse().
$response->sendResponse();
![]() |
Nota |
|---|---|
|
Por defecto, el controlador frontal llama a $front->returnResponse(true); $response = $front->dispatch(); // do some more processing, such as logging... // and then send the output: $response->sendResponse(); |
Los desarrolladores deberían hacer uso del objeto response en sus controladores de acción. En lugar de renderizar la salida directamente y enviar las cabeceras, envíelas al objeto response:
// Within an action controller action:
// Set a header
$this->getResponse()
->setHeader('Content-Type', 'text/html')
->appendBody($content);
Haciendo esto, todas las cabeceras se envían a la vez, justo antes de mostrar el contenido.
![]() |
Nota |
|---|---|
Si se utiliza la integración
con la vista del controlador de acción, no es necesario
establecer el contenido del script de vista renderizado en el
objeto response, ya que
|
Si se produce una excepción en una aplicación, compruebe el indicador
isException() del objeto response y recupere la
excepción utilizando getException(). Además,
se pueden crear objetos response personalizados que redirijan a
páginas de error, registren mensajes de excepción, formateen
de forma elegante los mensajes de excepción (para entornos de
desarrollo), etc.
Puede recuperar el objeto response tras el
dispatch() del controlador frontal, o solicitar
al controlador frontal que devuelva el objeto response en lugar de
renderizar la salida.
// retrieve post-dispatch:
$front->dispatch();
$response = $front->getResponse();
if ($response->isException()) {
// log, mail, etc...
}
// Or, have the front controller dispatch() process return it
$front->returnResponse(true);
$response = $front->dispatch();
// do some processing...
// finally, echo the response
$response->sendResponse();
Por defecto, los mensajes de excepción no se muestran. Este
comportamiento se puede sobrescribir llamando a
renderExceptions(), o habilitando que el
controlador frontal throwExceptions(), como se muestra arriba:
$response->renderExceptions(true); $front->dispatch($request, $response); // or: $front->returnResponse(true); $response = $front->dispatch(); $response->renderExceptions(); $response->sendResponse(); // or: $front->throwExceptions(true); $front->dispatch();
Como se indicó anteriormente, uno de los cometidos del objeto response es recopilar y emitir cabeceras de respuesta HTTP. Existe una variedad de métodos para ello:
canSendHeaders()se utiliza para determinar si las cabeceras ya han sido enviadas. Acepta un indicador opcional que señala si se debe lanzar una excepción en caso de que las cabeceras ya se hayan enviado. Esto se puede sobrescribir estableciendo la propiedad headersSentThrowsException aFALSE.-
setHeader($name, $value, $replace = false)se utiliza para establecer una cabecera individual. Por defecto, no reemplaza las cabeceras existentes con el mismo nombre en el objeto; sin embargo, estableciendo$replaceaTRUEforzará que así lo haga.Antes de establecer la cabecera, comprueba con
canSendHeaders()si esta operación está permitida en este punto, y solicita que se lance una excepción. -
setRedirect($url, $code = 302)establece una cabecera Location de HTTP para una redirección. Si se ha proporcionado un código de estado HTTP, se utilizará ese código de estado.Internamente, llama a
setHeader()con el indicador$replaceactivado para garantizar que solo se envíe una cabecera de este tipo. getHeaders()devuelve un array con todas las cabeceras. Cada elemento del array es un array con las claves 'name' y 'value'.clearHeaders()elimina todas las cabeceras registradas.setRawHeader()se puede utilizar para establecer cabeceras que no son pares de clave y valor, como una cabecera de estado HTTP.getRawHeaders()devuelve las cabeceras en bruto registradas.clearRawHeaders()elimina las cabeceras en bruto registradas.clearAllHeaders()elimina tanto las cabeceras normales de clave y valor como las cabeceras en bruto.
Además de los métodos anteriores, existen métodos de acceso para establecer
y recuperar el código de respuesta HTTP de la petición actual,
setHttpResponseCode() y
getHttpResponseCode().
Puede inyectar cabeceras Set-Cookie de HTTP en el objeto response
de un controlador de acción utilizando la clase de cabecera proporcionada
Zend_Http_Header_SetCookie
La siguiente tabla enumera todos los argumentos del constructor de
Zend_Http_Header_SetCookie
en el orden en que se aceptan. Todos los argumentos son opcionales,
pero name y value deben proporcionarse mediante sus setters si no
se pasan a través del constructor, o la cabecera Set-Cookie resultante
será inválida.
$name: El nombre de la cookie$value: El valor de la cookie$expires: El momento en que la cookie expira$path: La ruta en el servidor en la cual la cookie estará disponible$domain: El dominio al que restringir la cookie$secure: booleano que indica si la cookie debe enviarse por una conexión sin cifrar (false) o únicamente vía HTTPS (true)$httpOnly: booleano que indica si la cookie debe transmitirse únicamente mediante el protocolo HTTP$maxAge: La edad máxima de la cookie en segundos$version: La versión de la especificación de la cookie
Ejemplo 24.16. Rellenar Zend_Http_Header_SetCookie mediante el constructor y añadirlo a la respuesta
$this->getResponse()->setRawHeader(new Zend_Http_Header_SetCookie(
'foo', 'bar', NULL, '/', 'example.com', false, true
));
Ejemplo 24.17. Rellenar Zend_Http_Header_SetCookie mediante setters y añadirlo a la respuesta
$cookie = new Zend_Http_Header_SetCookie();
$cookie->setName('foo')
->setValue('bar')
->setDomain('example.com')
->setPath('/')
->setHttponly(true);
$this->getResponse()->setRawHeader($cookie);
El objeto response tiene soporte para "segmentos con nombre". Esto le permite segregar el contenido del cuerpo en diferentes segmentos y ordenar esos segmentos para que la salida se devuelva en un orden específico. Internamente, el contenido del cuerpo se guarda como un array, y los distintos métodos de acceso se pueden utilizar para indicar la ubicación y los nombres dentro de ese array.
Como ejemplo, podría utilizar un gancho preDispatch() para
añadir una cabecera al objeto response, luego hacer que el controlador de acción
añada contenido al cuerpo, y un gancho postDispatch() añada
un pie de página:
// Assume that this plugin class is registered with the front controller
class MyPlugin extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$response = $this->getResponse();
$view = new Zend_View();
$view->setBasePath('../views/scripts');
$response->prepend('header', $view->render('header.phtml'));
}
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
$response = $this->getResponse();
$view = new Zend_View();
$view->setBasePath('../views/scripts');
$response->append('footer', $view->render('footer.phtml'));
}
}
// a sample action controller
class MyController extends Zend_Controller_Action
{
public function fooAction()
{
$this->render();
}
}
En el ejemplo anterior, una llamada a /my/foo hará que el
contenido final del cuerpo del objeto response tenga la siguiente
estructura:
array(
'header' => ..., // header content
'default' => ..., // body content from MyController::fooAction()
'footer' => ... // footer content
);
Cuando esto se renderiza, se hará en el orden en que los elementos están dispuestos en el array.
Se puede utilizar una variedad de métodos para manipular los segmentos con nombre:
setBody()le permite pasar un segundo valor,$name, que indica un segmento con nombre. Si proporciona un nombre de segmento, sobrescribirá ese segmento con nombre específico o lo creará si no existe (añadiéndolo al array del cuerpo por defecto). Si no se pasa ningún segmento con nombre asetBody(), reinicia todo el array de contenido del cuerpo.appendBody()también le permite pasar un segundo valor,$name, que indica un segmento con nombre. Si proporciona un nombre de segmento, añadirá el contenido proporcionado al contenido existente en el segmento con nombre, o creará el segmento si no existe (añadiéndolo al array del cuerpo por defecto). Si no se pasa ningún segmento con nombre aappendBody(), añadirá el contenido proporcionado al segmento con nombre 'default', creándolo si no existe ya.prepend($name, $content)creará un segmento llamado$namey lo colocará al principio de el array. Si el segmento ya existe, se eliminará antes de la operación (es decir, se sobrescribe y reemplaza).append($name, $content)creará un segmento llamado$namey lo colocará al final de el array. Si el segmento ya existe, se eliminará antes de la operación (es decir, se sobrescribe y reemplaza).insert($name, $content, $parent = null, $before = false)creará un segmento llamado$name. Si se proporciona un segmento$parent, el nuevo segmento se colocará antes o después de ese segmento (según el valor de$before) en el array. Si el segmento ya existe, se eliminará antes de la operación (es decir, se sobrescribe y reemplaza).clearBody($name = null)eliminará un único segmento con nombre si se proporciona un$name(y todo el array en caso contrario).getBody($spec = false)se puede utilizar para recuperar un único segmento del array si$speces el nombre de un segmento con nombre. Si$specesFALSE, devuelve una cadena formada concatenando todos los segmentos con nombre en orden. Si$specesTRUE, devuelve el array de contenido del cuerpo.
Como se mencionó anteriormente, por defecto, las excepciones capturadas durante el dispatch se registran en el objeto response. Las excepciones se registran en una pila, lo que le permite conservar todas las excepciones lanzadas -- excepciones de la aplicación, excepciones de dispatch, excepciones de plugins, etc. Si desea comprobar excepciones concretas o registrar excepciones, deberá utilizar la API de excepciones del objeto response:
setException(Exception $e)le permite registrar una excepción.isException()le indicará si se ha registrado una excepción.getException()devuelve toda la pila de excepciones.hasExceptionOfType($type)le permite determinar si hay una excepción de una clase concreta en la pila.hasExceptionOfMessage($message)le permite determinar si hay una excepción con un mensaje específico en la pila.hasExceptionOfCode($code)le permite determinar si hay una excepción con un código específico en la pila.getExceptionByType($type)le permite recuperar todas las excepciones de una clase concreta de la pila. DevolveráFALSEsi no se encuentra ninguna, y un array de excepciones en caso contrario.getExceptionByMessage($message)le permite recuperar todas las excepciones con un mensaje específico de la pila. DevolveráFALSEsi no se encuentra ninguna, y un array de excepciones en caso contrario.getExceptionByCode($code)le permite recuperar todas las excepciones con un código específico de la pila. DevolveráFALSEsi no se encuentra ninguna, y un array de excepciones en caso contrario.renderExceptions($flag)le permite establecer un indicador que señala si las excepciones deben emitirse o no cuando se envía la respuesta.
El propósito del objeto response es recopilar cabeceras y contenido de las distintas acciones y plugins y devolverlos al cliente; en segundo lugar, también recopila cualquier error (excepción) que ocurra con el fin de procesarlo, devolverlo, u ocultarlo al usuario final.
La clase response base es
Zend_Controller_Response_Abstract, y cualquier subclase que
cree debe extender esa clase o alguna de sus derivadas. Los
distintos métodos disponibles se han enumerado en las secciones anteriores.
Entre las razones para crear una subclase del objeto response se incluyen modificar la forma en que se devuelve la salida en función del entorno de la petición (por ejemplo, no enviar cabeceras para peticiones de CLI o PHP-GTK), añadir funcionalidad para devolver una vista final basada en el contenido almacenado en segmentos con nombre, etc.
![[Note]](images/note.png)