El Router StandardIntroducciónZend_Controller_Router_Rewrite Es el router
standard del Framework. Routing es el proceso de tomar la parte
final de una URI (la parte de la
URI que viene después de la
URL base) y la descomposición en parámetros
para determinar qué módulo, qué controlador y acción de ese
controlador debe recibir la solicitud. Estos valores del módulo,
controlador, acción y otros parámetros están enpaquetados en un
objeto Zend_Controller_Request_Http el cual
es procesado luego por
Zend_Controller_Dispatcher_Standard . El
routing ocurre sólo una vez: cuando se recibió inicialmente la
solicitud y antes del dispatch del primer controlador. Zend_Controller_Router_Rewrite está diseñado
para permitir que una funcionalidad tipo mod_rewrite se pueda usar
en estructuras PHP puras. Se basa muy vagamente
en el routing de Ruby on Rails (RoR) y no requiere ningún
conocimiento previo de reescritura de la URL del
webserver. Está diseñado para trabajar con solo una regla
mod_rewrite de Apache (one of): o (preferido): El router rewrite también puede utilizarse con el
IIS webserver (versions <= 7.0) si
Isapi_Rewrite
se ha instalado como una extensión Isapi con la siguiente regla de
reescribir: IIS Isapi_Rewrite Cuando se usa IIS ,
$_SERVER['REQUEST_URI'] puede no existir,
o establecerlo como un string vacío. En este caso,
Zend_Controller_Request_Http
intentará usar el valor de
$_SERVER['HTTP_X_REWRITE_URL']
establecido por la extensión Isapi_Rewrite. IIS 7.0 introduce un módulo nativo de reescribir la URL, y puede
ser configurado como sigue: ]>
Si está usando Lighttpd, la siguiente regla de reescritura es válida:
"/index.php?$1",
".*\.(js|ico|gif|jpg|png|css|html)$" => "$0",
"" => "/index.php"
)
]]>Usando un Router Para utilizar adecuadamente el router de reescritura debe
instanciarlo, agregar algunas rutas definidas por el usuario y luego
inyectarlo en el controlador. El siguiente código ilustra el
procedimiento: getRouter(); // returns a rewrite router by default
$router->addRoute(
'user',
new Zend_Controller_Router_Route('user/:username',
array('controller' => 'user',
'action' => 'info'))
);
]]>Operación Básica del Rewrite Router El corazón del RewriteRouter es la definición de la rutas
definidas por el usuario. Las rutas se agregan llamando al método
addRoute de RewriteRouter y pasándole una nueva instancia de una
clase que implementó a
Zend_Controller_Router_Route_Interface .
Eg.: addRoute('user',
new Zend_Controller_Router_Route('user/:username'));
]]> El Rewrite Router viene con seis tipos básicos de rutas (uno de
los cuales es especial):
Zend_Controller_Router_Route
Zend_Controller_Router_Route_Static
Zend_Controller_Router_Route_Regex
Zend_Controller_Router_Route_Hostname
Zend_Controller_Router_Route_Chain
Zend_Controller_Router_Rewrite * Las rutas pueden ser utilizadas numerosas veces para crear una
cadena o un esquema de aplicación de ruteo definido por el usuario.
Puede usar cualquier número de rutas en cualquier configuración, con
la excepción de la ruta del Módulo, la cual debe ser utilizada una
vez y probablemente como la ruta más genérica (es decir, por
defecto). Cada ruta se describe en mayor detalle más adelante. El primer parámetro a addRoute es el nombre de la ruta. Se
utiliza como un manejador para sacar las rutas del router (por
ejemplo, con fines de generación de URL ). El
segundo parámetro es la ruta misma. El uso más común del nombre de ruta es por medio del ayudante
de URL
Zend_View : url(array('username' => 'martel'), 'user') ?>">Martel
]]> Que resultaría en la href: user/martel .
El routing es un simple proceso de iteración a través de todas
las rutas provistas y la equiparación de sus definiciones con la
petición actual de URI . Cuando se encuentra una
concordancia, se devuelven valores de variables desde la instancia
Route y se inyecta en el objeto
Zend_Controller_Request para su posterior
utilización en el dispatcher así también como en los controladores
creados por el usuario. En caso de no encontrar ninguna
concordancia, se comprobará la siguiente ruta en la cadena. Si necesita determinar en qué ruta se encontró una concordancia,
puede usar el método getCurrentRouteName()
, que devolverá el identificador usado cuando registró la ruta con
el router. Si quiere el objeto de la ruta actual, puede usar
getCurrentRoute() . Matching Inverso Las rutas están equiparadas en orden inverso para asegurarse
que las rutas más genéricas se definan primero. Valores Retornados Los valores retornados del routing provienen de parámetros
URL o de rutas definidas por defecto por
el usuario. Estas variables son accesibles posteriormente a
través de los métodos
Zend_Controller_Request::getParam()
o Zend_Controller_Action::_getParam() .
Hay tres variables que pueden utilizarse en las rutas - 'module',
'controller' y 'action'. Estas variables especiales son utilizados
por Zend_Controller_Dispatcher para encontrar
un controlador y una acción para hacer el dispatch. Variables Especiales Los nombres de estas variables especiales pueden ser
diferentes si elige alterar los valores por defecto en
Zend_Controller_Request_Http mediante
los métodos setControllerKey() y
setActionKey() . Routes por DefectoZend_Controller_Router_Rewrite viene
preconfigurado con una ruta por defecto, que se comparará con
URI s en la forma de
controller/action . Además, se puede
especificar un nombre de módulo como primer elemento del path,
permitiendo URI s de la forma
module/controller/action . Por último,
también coincidrá con cualquier parámetro adicional agregado a la
URI por defecto -
controller/action/var1/value1/var2/value2 . Algunos ejemplos de cómo están equiparadas las rutas: setControllerDirectory(
array(
'default' => '/path/to/default/controllers',
'news' => '/path/to/news/controllers',
'blog' => '/path/to/blog/controllers'
)
);
Módulo únicamente:
http://example/news
module == news
Modulo inválido mapea al nombre del controlador:
http://example/foo
controller == foo
Módulo + controlador:
http://example/blog/archive
module == blog
controller == archive
Módulo + controlador + accción:
http://example/blog/archive/list
module == blog
controller == archive
action == list
Módulo + controlador + accción + parámetros:
http://example/blog/archive/list/sort/alpha/date/desc
module == blog
controller == archive
action == list
sort == alpha
date == desc
]]> La ruta por defecto es simplemente un objeto
Zend_Controller_Router_Route_Module
almacenado bajo el nombre de (index) por 'default' en RewriteRouter.
Está generado más o menos así: addRoute('default', $compat);
]]> Si no quiere esta ruta en particular en su esquema por defecto de
routing, podrá anularla creando su propia ruta por 'defecto' (es
decir, almacenar bajo el nombre de 'default') o eliminarla por
completo usando removeDefaultRoutes() : removeDefaultRoutes();
]]>URL Base y Subdirectorios El router rewrite puede ser utilizado en subdirectorios (por
ejemplo
http://domain.com/~user/application-root/ )
en cuyo caso la URL base de la aplicación (
/user/application-root ) debe ser detectada
automáticamente por
Zend_Controller_Request_Http y usada en
consecuencia. Si la URL base se detecta incorrectamente se
la puede anular con su propio path de base usando
Zend_Controller_Request_Http y llamando
al método setBaseUrl() (ver ): setBaseUrl('/~user/application-root/');
]]>Parámetros Globales Puede establecer los parámetros globales en un router que se
proporcionan automáticamente a una ruta cuando se ensamblasn
mediante setGlobalParam() . Si se establece
un parámetro global pero también se lo entrega directamente al
método de ensamblaje, el parámetro del usuario sobreescribe al
parámetro global. Puede establecer un parámetro global esta forma: setGlobalParam('lang', 'en');
]]>Tipos de Route Usando Zend_Config con RewriteRouter A veces es más conveniente para actualizar un archivo de
configuración con nuevas rutas que modificar el código. Esto es
posible a través del método addConfig() .
Básicamente, se crea una configuración compatible con
Zend_Config . Y en su código lo lee y lo
pasa a RewriteRouter. Como ejemplo, considere el siguiente archivo
INI : Entonces el archivo INI puede ser leído por un
objeto Zend_Config como sigue: addConfig($config, 'routes');
]]> En el ejemplo de arriba, le decimos el router que utilice la
sección 'routes' del archivo INI para utilizarlo
en sus rutas. Cada clave de primer nivel en esa sección será
utilizada para definir un nombre de ruta; el ejemplo anterior define
las rutas 'archive' y 'news'. Entonces cada ruta requiere, como
mínimo, una entrada a la 'ruta' y una o más entradas por 'default';
opcionalmente puede proporcionarse una o más 'reqs' (abreviación de
'required'). Dicho todo esto, estos corresponden a los tres
argumentos que se le suministran al objeto
Zend_Controller_Router_Route_Interface .
Puede utilizarse una clave opcional 'type' para especificar el tipo
de clase de ruta a utilizar en esa ruta en particular; por defecto,
usa Zend_Controller_Router_Route . En el
ejemplo de arriba, la ruta 'news' está definida para usar
Zend_Controller_Router_Route_Static .
Subclassing del Router El standard rewrite router debería proporcionarle más
funcionalidad si la necesita; más a menudo, sólo necesitará crear un
nuevo tipo de ruta a fin de ofrecer funcionalidades nuevas o
modificadas sobre las tutas provistas. Dicho esto, en algún momento puede encontrarse a si mismo
deseando usar un paradigma diferente de routing. La intefaz
Zend_Controller_Router_Interface
proporciona la información mínima necesaria para crear un router, y
consiste en un único método. El routing sólo ocurre una vez: cuando la petición es recibida
por primera vez en el sistema. El propósito del router es determinar
el controlador, la acción, y los parámetros opcionales sobre la base
del medio ambiente de la solicitud, y luego ajustarlos en la
solicitud. El objeto solicitud se pasa entonces al dispatcher. Si no
es posible trazar una ruta hacia un dispatch token, el router no
debe hacer nada con el objeto solicitud.