Controladores de AcciónIntroducciónZend_Controller_Action es una clase abstracta
que puede utilizar para implementar controladores de acción
(Action Controllers) para usar con el Front Controller al crear un
un sitio basado en el patrón Modelo-Vista-Controlador (MVC).
Para usar Zend_Controller_Action, necesitará
hacerla una subclase en sus clases actuales de controladores de
acción (o hacerla una subclase para crear su propia clase base de
acción de controladores).
La operación más elemental es hacerla una subclase, y crear métodos
de acción que corresponden a las diversas acciones que desee que el
contralor maneje para su sitio.
El manejo del ruteo y envío de
Zend_Controller descubrirá por sí mismo
cualquier método que termine en 'Action' en su clase, como posibles
acciones del controlador.
Por ejemplo, digamos que su clase se define como sigue:
La clase de arriba FooController (el controlador
foo) define dos acciones, bar y
baz.
Se pueden lograr muchas cosas más, tales como personalizar
la inicialización de acciones, las acciones a llamar por defecto no
deberían especificar ninguna acción (o una acción inválida),
ganchos de pre y post despacho, y una variedad de métodos ayudantes.
Este capítulo sirve como panorama de la funcionalidad del
controlador de acciones.
Comportamiento por Defecto
Por defecto, el front
controller habilita al ayudante de acción ViewRenderer.
Este ayudante toma a su cargo la inyección del objeto "view"
en el contralor, así como compatibilizar automáticamente las
vistas. Usted podrá desactivarlo dentro de su contralor de
acción por uno de los métodos siguientes:
_helper->viewRenderer->setNoRender(true);
// Globalmente:
$this->_helper->removeHelper('viewRenderer');
// También globalmente, pero tendría que ser en conjunción con la
// versión local con el fin de propagarlo para este controlador:
Zend_Controller_Front::getInstance()
->setParam('noViewRenderer', true);
}
}
]]>initView(), getViewScript(),
render(), y renderScript() cada
proxy al ViewRenderer a menos que el ayudante no
esté como ayudante intermediario o no se haya establecido el
flag de noViewRenderer.
También puede simplemente desactivarse para una prestación
individual ajustando el flag noRender de
ViewRenderer:
_helper->viewRenderer->setNoRender();
}
}
]]>
Las principales razones para desactivar
ViewRenderer son si usted simplemente no necesita
una objeto "view" o si no está mostrándolos via view scripts
(por ejemplo, cuando se utiliza un controlador de acción
para alimentar a los protocolos de un servicio web como SOAP,
XML-RPC, o REST). En muchos casos, nunca necesitará desactivar
a ViewRenderer globalmente, sólo selectivamente
dentro de los distintos controladores o acciones.
Inicialización de Objectos
Si bien siempre puede anular el contolador de acción del
constructor, no lo recomendamos.
Zend_Controller_Action::__construct()
realiza algunas tareas importantes, tales como registrar los
objetos de solicitud y respuesta, así como los argumentos de
cualquier invocación personalizada pasados desde el front
controller. Si debe anular el constructor, asegúrese de llamar a
parent::__construct($request, $response, $invokeArgs).
La manera más apropiada de personalizar la instanciación es
utilizar el método init(), el cual es llamado como la
última tarea de __construct().
Por ejemplo, si se quiere conectar a una base de datos en la
instanciación:
db = Zend_Db::factory('Pdo_Mysql', array(
'host' => 'myhost',
'username' => 'user',
'password' => 'XXXXXXX',
'dbname' => 'website'
));
}
}
]]>Ganchos de Pre- and Post-DespachoZend_Controller_Action especifica dos
métodos que pueden ser llamados para marcar una solicitud de acción,
preDispatch() y postDispatch().
Estas pueden ser útiles de varias maneras: verificar la
autenticación y ACLs antes de ejecutar una acción (llamando a
_forward() en preDispatch(), se saltará
la acción), por ejemplo, o colocando contenido generado en una
plantilla general del sitio (postDispatch()).
Accessors (Accededores)
Con el objeto, se registran una serie de objetos y variables,
y cada uno tiene métodos de acceso.
Objecto Requerimiento: getRequest()
puede ser utilizado para recuperar el objeto solicitud
utilizado para llamar a la acción.
Objecto Respuesta:
getResponse() puede ser utilizado para
recuperar el objeto respuesta agregando la respuesta final.
Algunas llamadas típicas podrían ser:
getResponse()->setHeader('Content-Type', 'text/xml');
$this->getResponse()->appendBody($content);
]]>Argumentos de Invocación: el front
controller puede empujar parámetros al router, al
despachador, y al controlador de acción. Para recuperarlos,
use getInvokeArg($key); por otra parte, se
puede traer toda la lista utilizando
getInvokeArgs().
Parámetros de Requerimientos:
La objeto solicitud agrega parámetros de solicitud,
como cualquiera de los parámetros _GET o _POST,
o parámetros del usuario especificados en la información
del path de la URL. Para recuperarlos, use
_getParam($key) o _getAllParams().
También se pueden establecer parámetros de solicitud usando
_setParam(); lo que es útil cuando se reenvían
a acciones adicionales.
Para probar si un parámetro existe o no (muy útil para
bifurcaciones lógicas), use _hasParam($key).
_getParam() puede tomar opcionalmente un
segundo argumento que contiene un valor por defecto a
utilizar si el parámetro no está establecido o está
vacío. Usándolo elimina la necesidad de llamar
previamente a _hasParam() para
recuperar un valor:
_getParam('id', 1);
// En lugar de:
if ($this->_hasParam('id') {
$id = $this->_getParam('id');
} else {
$id = 1;
}
]]>Integración de VistasIntegración de la Vista por Defecto via ViewRenderer
El contenido de esta sección sólo es válida cuando usted tiene
explícitamente deshabilitado a
ViewRenderer.
De lo contrario, puede saltarse esta sección.
Zend_Controller_Action proporciona un
mecanismo rudimentario y flexible para ver la integración.
Hay dos métodos para lograrlo, initView() y
render(); el anterior método $view
carga la propiedad pública, y este último muestra una vista en
base a la acción requerida actual, utilizando la jerarquía del
directorio para determinar el path del script.
Inicialización de la VistainitView() inicializa el objeto vista.
render() llama a initView()
con el fin de recuperar el objeto vista, pero puede ser
iniciada en cualquier momento; por defecto introduce
información a la propiedad de $view con un objeto
Zend_View, pero se puede usar cualquier
clase que implemente Zend_View_Interface.
Si $view ya ha sido inicializada, simplemente
devuelve esa propiedad.
La implementación por defecto hace la siguiente hipótesis de la
estructura del directorio:
En otras palabras, los scripts de vista se supone están en el
subdirectorio views/scripts/, y en el subdirectorio
views se supone que contiene funcionalidades
hermanas (ayudantes, filtros). Al determinar el nombre y el
path del script, el directorio views/scripts/
será utilizado como el path base, con directorios nombrados
después que los controladores individuales proporcionen una
jerarquía a los scripts de vista.
Suministrando las Vistasrender() tiene la siguiente firma:
render() suministra un script de vista.
Si no se pasan argumentos, se supone que el script requerido es
[controller]/[action].phtml (donde
.phtml es el valor de la propiedad
$viewSuffix).
Pasándole un valor a $action suministrará esa
plantilla en al subdirectorio [controller]. Para
anular el subdirectorio [controller] ponga un
valor verdadero en $noController.
Por último, las plantillas son suministradas en el objeto
respuesta; si desea suministrar a un determinado
named segment en el objeto respuesta, pase un valor a
$name.
Dado que el controlador y los nombres de acción pueden
contener caracteres delimitadores como '_', '.', y '-',
render() los normaliza a '-' para determinar
el nombre del script. Internamente, utiliza los
delimitadores de palabra y de path del despachador para
hacer esta normalización. Así, una solicitud a
/foo.bar/baz-bat suministrará el script
foo-bar/baz-bat.phtml.
Si su método de acción contiene camelCasing, recuerde que
esto se traducirá en palabras separadas por '-'
al determinar el nombre del archivo del script de vista.
Algunos ejemplos:
render();
// Suministra my/bar.phtml
$this->render('bar');
// Suministra baz.phtml
$this->render('baz', null, true);
// Suministra my/login.phtml al segmento 'form' del
// objeto respuesta
$this->render('login', 'form');
// Suministra site.phtml al segmento 'page' del objeto
// respuesta; no usa el subdirectorio 'my/'
$this->render('site', 'page', true);
}
public function bazBatAction()
{
// Suministra my/baz-bat.phtml
$this->render();
}
}
]]>Métodos Utilitarios
Además de los accesadores y de los métodos de integración de vistas,
Zend_Controller_Action tiene varios
métodos utilitarios para realizar tareas comunes dentro de sus
métodos de acción (o de pre-/post-despacho).
_forward($action, $controller = null, $module = null,
array $params = null): realiza otra acción. Si es
llamado en preDispatch(), la acción actualmente
requerida se saltará en favor de la nueva.
De lo contrario, después de procesar la acción actual,
se ejecutará la acción solicitada en _forward().
_redirect($url, array $options =
array()): redireccionar a otro lugar.
Este método toma una URL y un conjunto de opciones.
Por defecto, realiza una redirección HTTP 302.
Las opciones pueden incluir uno o más de los siguientes:
exit: ya sea para salir
inmediatamente o no. Si así lo solicita, limpiamente
cerrará cualquier sesión abierta y realizará
la redirección.
Puede configurar esta opción globalmente en el
controlador utilizando el accesador
setRedirectExit().
prependBase: ya sea
anteponiendo o no la base URL registrada con el
objeto solicitud a la URL provista.
Puede configurar esta opción globalmente en el
controlador utilizando el accesador
setRedirectPrependBase().
code: qué código HTTP
utilizar en la redirección. Por defecto,
se utiliza un HTTP 302; se puede utilizar cualquier
código entre 301 y 306.
Puede configurar esta opción globalmente en el
controlador utilizando el accesador
setRedirectCode().
Controladores de Acción y haciendo Subclases
Por diseño, Zend_Controller_Action
debe ser "subclaseada" a fin de crear un controlador de acción.
Como mínimo, necesitará definir los métodos de acción que podrá
llamar el controlador.
Además de crear una funcionalidad útil para su aplicaciones web,
también puede encontrar que está repitiendo demasiado los mismos
setups o métodos utilitarios en sus diferentes controladores;
si así fuera, creando una clase base común del controlador
que extienda Zend_Controller_Action puede
resolver esta redundacia.
Manejando Acciones No Existentes
Si hay una solicitud a un controlador que incluye un método de
acción no definido, se invocará a
Zend_Controller_Action::__call().
__call() es, por supuesto, el método mágico de PHP
para la sobrecarga del método.
Por defecto, este método lanza un
Zend_Controller_Action_Exception
indicando que el método no se encuentró en el controlador.
Si el método requerido termina en 'Action', la suposición es
que una acción fue solicitada y no existe; tales errores
resultan en una excepción con un código 404.
Todos los demás métodos resultan en una excepción con un
código 500. Esto le permite diferenciar fácilmente entre una
página no encontrada y errores de aplicación con su
manejador de errores.
Usted debe anular esta funcionalidad si desea realizar otras
operaciones. Por ejemplo, si desea mostrar un mensaje de error,
usted podría escribir algo como esto:
render('error');
}
// todos los otros métodos lanzan una excepción
throw new Exception('Se ha llamado al método "'
. $method
. '" que es inválido',
500);
}
}
]]>
Otra posibilidad es que puede querer avanzar a un controlador
de página por defecto:
render();
}
public function __call($method, $args)
{
if ('Action' == substr($method, -6)) {
// Si no se encontró el método de acción, avance a la
// acción index
return $this->_forward('index');
}
// todos los otros métodos lanzan una excepción
throw new Exception('Se ha llamado al método "'
. $method
. '" que es inválido',
500);
}
}
]]>
Además de sobrecargar __call(), cada uno de los
métodos gancho de inicialización, utilidad, accesador, vista,
y despacho mencionados anteriormente en este capítulo pueden ser
anulados a fin de personalizar sus controladores.
Como ejemplo, si está almacenando su objeto vista en un registro,
quizás desee modificar su método initView() con código
parecido al siguiente:
view) {
if (Zend_Registry::isRegistered('view')) {
$this->view = Zend_Registry::get('view');
} else {
$this->view = new Zend_View();
$this->view->setBasePath(dirname(__FILE__) . '/../views');
}
}
return $this->view;
}
}
]]>
Es de esperar, que de la información en este capítulo, usted puede ver
la flexibilidad de este componente en particular y cómo puede darle
forma a su aplicaciones o a las necesidades de su sitio web.