1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 17593 -->
4 <sect1 id="zend.controller.exceptions">
5 <title>Excepciones MVC</title>
7 <sect2 id="zend.controller.exceptions.introduction">
8 <title>Introducción</title>
12 <acronym>MVC</acronym>
13 en Zend Framework utilizan
14 un Front Controller, lo que significa que todas las
16 un determinado sitio pasarán por un solo punto de entrada. Como
18 todas las excepciones burbujearán eventualmente hacia
19 arriba hasta el Front Controller,
20 permitiendo al desarrollador
21 manejarlos en un solo lugar.
25 Sin embargo, los mensajes de excepción y la información de
26 backtrace contienen a menudo
27 información sensible del sistema, como
29 <acronym>SQL</acronym>
30 , ubicaciones de archivos y
31 otras cosas más. Para ayudar a proteger su sitio, por defecto
32 <classname>Zend_Controller_Front</classname>
34 excepciones y las registra con el objeto respuesta; a su vez, y por
35 defecto, el objeto respuesta no muestra mensajes de excepción.
39 <sect2 id="zend.controller.exceptions.handling">
40 <title>Manejando las Excepciones</title>
43 Ya hay varios mecanismos construidos en los componentes de
44 <acronym>MVC</acronym>
45 , que le permiten manejar excepciones.
52 <link linkend="zend.controller.plugins.standard.errorhandler">error handler
54 está registrado y activo.
55 Este plugin fue diseñado para manejar:
60 <para>Errores debido a controladores o acciones
65 <para>Errores ocurriendo dentro de controladores de
71 Operan como un plugin de
72 <methodname>postDispatch()</methodname>
74 para ver si un despachador, controlador de acción, o de otra
75 excepción ha ocurrido. Si así fuera, lo remite a un
76 controlador de manejo de
80 <para>Este manejador abarcará la mayoría de las situaciones
81 excepcionales, y maneja
82 airosamente controladores y acciones
88 <methodname>Zend_Controller_Front::throwExceptions()</methodname>
92 Pasando a este método un valor booleano
93 <constant>TRUE</constant>
94 , puede decirle al front
95 controller que, en lugar de sumar excepciones en el
97 respuesta o utilizando el plugin de manejo de errores,
99 usted mismo. Como ejemplo:
102 <programlisting language="php"><![CDATA[
103 $front->throwExceptions(true);
106 } catch (Exception $e) {
107 // usted mismo maneja las excepciones
111 <para>Este método es probablemente la forma más fácil de añadir
113 excepciones personalizado que abarque toda la
114 gama de posibles excepciones a su
121 <methodname>Zend_Controller_Response_Abstract::renderExceptions()</methodname>
125 Al pasar a este método un valor booleano
126 <constant>TRUE</constant>
127 , le esta diciendo al objeto
128 respuesta que debe emitir un mensaje de excepción y
129 backtrace cuando se renderiza a sí mismo. En este escenario,
131 cualquier excepción planteada por su aplicación.
132 Esto no es recomendable para
133 entornos de producción, pero sí
140 <methodname>Zend_Controller_Front::returnResponse()</methodname>
142 <methodname>Zend_Controller_Response_Abstract::isException()</methodname>
147 Pasando un valor booleano
148 <constant>TRUE</constant>
150 <methodname>Zend_Controller_Front::returnResponse()</methodname>
152 <methodname>Zend_Controller_Front::dispatch()</methodname>
153 no renderizará la respuesta, sino que la devolverá. Una vez
155 respuesta, entonces puede probar ver si todas
156 las excepciones fueron atrapadas
158 <methodname>isException()</methodname>
160 las excepciones a través del método
161 <methodname>getException()</methodname>
165 <programlisting language="php"><![CDATA[
166 $front->returnResponse(true);
167 $response = $front->dispatch();
168 if ($response->isException()) {
169 $exceptions = $response->getException();
170 // maneje las excepciones ...
172 $response->sendHeaders();
173 $response->outputBody();
178 La principal ventaja que este método ofrece por sobre
179 <methodname>Zend_Controller_Front::throwExceptions()</methodname>
180 es que le permite renderizar condicionalmente la respuesta
181 después de manejar la
182 excepción. Esta capturará cualquier
183 excepción en la cadena de controladores, a
185 plugin de manejo de errores.
191 <sect2 id="zend.controller.exceptions.internal">
192 <title>Excepciones MVC que Usted Pueda Encontrar</title>
195 Los diversos componentes de
196 <acronym>MVC</acronym>
198 router, despachador, controlador de acción, y los objetos respuesta
200 pueden arrojar excepciones en ocasiones. Algunas excepciones
201 puede ser condicionalmente
202 anuladas, y otras se usan para indicar al
203 desarrollador que puede necesitar re-considerar
208 <para>Como algunos ejemplos:</para>
213 <methodname>Zend_Controller_Dispatcher::dispatch()</methodname>
214 hará, por defecto, arrojar una excepción si se hace un
216 controlador no válido. Hay dos maneras
217 recomendadas para lidiar con esto.
223 Establecer el parámetro
224 <emphasis>useDefaultControllerAlways</emphasis>
228 <para>En su front controller, o en su despachador,
232 <programlisting language="php"><![CDATA[
233 $front->setParam('useDefaultControllerAlways', true);
237 $dispatcher->setParam('useDefaultControllerAlways', true);
240 <para>Cuando este flag está establecido, el despachador
242 controlador y la acción por defecto en
243 lugar de lanzar una excepción. La
245 método es que cualquier error ortográfico que un
246 usuario haga cuando acceda a su sitio lo resolverá y
248 de inicio, y que puede causar
249 estragos con la optimización para los
256 La excepción arrojada por
257 <methodname>dispatch()</methodname>
259 <classname>Zend_Controller_Dispatcher_Exception</classname>
260 conteniendo el texto 'Invalid controller specified'.
262 métodos descriptos de
263 <link linkend="zend.controller.exceptions.handling">la
264 sección anterior</link>
266 excepción, y luego redireccionar a una página
268 error o a la página de inicio.
276 <methodname>Zend_Controller_Action::__call()</methodname>
278 <classname>Zend_Controller_Action_Exception</classname>
279 si no puede despachar una acción inexistente a un método. Es
281 utilizar alguna acción por defecto en el
282 controlador en casos como este. Formas
291 <classname>Zend_Controller_Action</classname>
294 <methodname>__call()</methodname>
299 <programlisting language="php"><![CDATA[
300 class My_Controller_Action extends Zend_Controller_Action
302 public function __call($method, $args)
304 if ('Action' == substr($method, -6)) {
305 $controller = $this->getRequest()->getControllerName();
306 $url = '/' . $controller . '/index';
307 return $this->_redirect($url);
310 throw new Exception('Invalid method');
314 <para>El ejemplo anterior intercepta cualquier llamada
315 a un método de acción
316 indefinido y redirecciona a la
317 acción predeterminada en el controlador.</para>
323 <classname>Zend_Controller_Dispatcher</classname>
325 <methodname>getAction()</methodname>
327 verificar si la acción existe. Como ejemplo:
330 <programlisting language="php"><![CDATA[
331 class My_Controller_Dispatcher extends Zend_Controller_Dispatcher
333 public function getAction($request)
335 $action = $request->getActionName();
336 if (empty($action)) {
337 $action = $this->getDefaultAction();
338 $request->setActionName($action);
339 $action = $this->formatActionName($action);
341 $controller = $this->getController();
342 $action = $this->formatActionName($action);
343 if (!method_exists($controller, $action)) {
344 $action = $this->getDefaultAction();
345 $request->setActionName($action);
346 $action = $this->formatActionName($action);
355 <para>El código anterior comprueba para ver que las
357 existan en la clase del
358 controlador; si no, se restablece la acción a la
359 acción por defecto.</para>
362 Este método es agradable porque puede alterar
363 transparentemente la acción
365 despacho. Sin embargo, también significa que errores
367 <acronym>URL</acronym>
369 pueden despacharse correctamente, lo que no es muy
371 optimización en un motor de búsqueda.
378 <methodname>Zend_Controller_Action::preDispatch()</methodname>
380 <methodname>Zend_Controller_Plugin_Abstract::preDispatch()</methodname>
381 para identificar acciones inválidas.
386 <classname>Zend_Controller_Action</classname>
389 <methodname>preDispatch()</methodname>
391 puede modificar todos sus controladores que
392 transmitan a otra acción o
393 redireccionar antes de
394 despachar la acción. El código para hacer esto se
395 verá parecido al código de sustitución de arriba
396 <methodname>__call()</methodname>
400 <para>Alternativamente, puede verificar esta
401 información en un plugin global.
403 ventaja de ser independiente del controlador de
405 su aplicación consiste en una variedad de
406 controladores de acción, y no
407 todos ellos heredan de
408 la misma clase, este método puede añadir
410 a su manejo de clases diferentes.</para>
412 <para>Como ejemplo:</para>
414 <programlisting language="php"><![CDATA[
415 class My_Controller_PreDispatchPlugin extends Zend_Controller_Plugin_Abstract
417 public function preDispatch(Zend_Controller_Request_Abstract $request)
419 $front = Zend_Controller_Front::getInstance();
420 $dispatcher = $front->getDispatcher();
421 $class = $dispatcher->getControllerClass($request);
423 $class = $dispatcher->getDefaultControllerClass($request);
426 $r = new ReflectionClass($class);
427 $action = $dispatcher->getActionMethod($request);
429 if (!$r->hasMethod($action)) {
430 $defaultAction = $dispatcher->getDefaultAction();
431 $controllerName = $request->getControllerName();
432 $response = $front->getResponse();
433 $response->setRedirect('/' . $controllerName
434 . '/' . $defaultAction);
435 $response->sendHeaders();
442 <para>En este ejemplo, vamos a consultar para ver si la
444 está disponible en el controlador.
445 Si no, redireccionamos a la acción
447 el controlador, y salimos inmediatamente de la
448 ejecución del script.</para>