| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect3 id="zend.controller.router.routes.regex">
- <title>Zend_Controller_Router_Route_Regex</title>
- <para>Además de los tipos de ruta estáticos y por defecto, también está
- disponible el tipo de
- ruta Expresión Regular. Esta ruta ofrece más
- potencia y flexibilidad que los otros, pero a
- costa de un ligero aumento
- en la complejidad. Al mismo tiempo, debería ser más rápido que la
- standard Route.</para>
- <para>Al igual que la standard Route, esta ruta tiene que ser inicializada
- con una definición de
- ruta y algunos valores predeterminados. Vamos a
- crear un archivo ruta como un ejemplo,
- similar al previamente definido,
- sólo que esta vez usaremos la ruta Regex:</para>
- <programlisting language="php"><![CDATA[
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive/(\d+)',
- array(
- 'controller' => 'archive',
- 'action' => 'show'
- )
- );
- $router->addRoute('archive', $route);
- ]]></programlisting>
- <para>
- Cada sub-patrón regex definido será inyectado al objeto solicitud.
- Con nuestro ejemplo
- anterior, después de un matching exitoso
- <filename>http://domain.com/archive/2006</filename>
- , el valor
- resultante del array puede verse como:
- </para>
- <programlisting language="php"><![CDATA[
- $values = array(
- 1 => '2006',
- 'controller' => 'archive',
- 'action' => 'show'
- );
- ]]></programlisting>
- <note>
- <para>
- Las barras de comienzo y final están recortadas de la
- <acronym>URL</acronym>
- en el Router antes de una concordancia.
- Como resultado, coincidendo con la
- <acronym>URL</acronym>
- <filename>http://domain.com/foo/bar/</filename>
- , involucraría al
- regex de
- <filename>foo/bar</filename>
- , y no a
- <filename>/foo/bar</filename>
- .
- </para>
- </note>
- <note>
- <para>Las anclas de comienzo y fin de línea ('^' y '$',
- respectivamente) son automáticamente
- antepuestas y pospuestas a
- todas las expresiones. Así, no debe usar éstas en sus
- expresiones
- regulares, y debe coincidir con el string completo.</para>
- </note>
- <note>
- <para>
- Esta clase de ruta usa el carácter
- <emphasis>#</emphasis>
- como un delimitador. Esto significa que necesitará caracteres hash
- ('#') para escapar
- pero no barras ('/') en sus definiciones de ruta.
- Dado que el carácter '#' (llamado
- ancla) es raramente pasado al
- webserver, será muy rara la necesidad de utilizar ese
- carácter en su
- regex.
- </para>
- </note>
- <para>Puede obtener el contenido de los sub-patrones definidos por la forma
- habitual:</para>
- <programlisting language="php"><![CDATA[
- public function showAction()
- {
- $request = $this->getRequest();
- $year = $request->getParam(1); // $year = '2006';
- }
- ]]></programlisting>
- <note>
- <para>Tenga en cuenta que la clave es un entero (1) en lugar de un
- string ('1').</para>
- </note>
- <para>Sin embargo, esta ruta no funciona exactamente igual que su
- contraparte standard route dado
- que el valor por defecto para 'year'
- todavía no se ha establecido. Y lo que puede ser no tan
- evidente es que
- tendremos un problema con una barra final incluso si declaramos por
- defecto el
- año y hacemos opcional al sub-patrón. La solución es hacer
- que toda la parte del año sea
- opcional junto con la barra pero capturar
- solo la parte numérica:</para>
- <programlisting language="php"><![CDATA[
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive(?:/(\d+))?',
- array(
- 1 => '2006',
- 'controller' => 'archive',
- 'action' => 'show'
- )
- );
- $router->addRoute('archive', $route);
- ]]></programlisting>
- <para>Ahora, ocupemósnos del problema que probablemente haya notado.
- Utilizar claves basadas en
- enteros para los parámetros no es una
- solución fácilmente manejable y puede ser
- potencialmente problemática a
- largo plazo. Y aquí es donde entra el tercer parámetro. Este
- parámetro
- es un array asociativo que representa un mapa de sub-patrones regex a
- nombres de
- clave de parámetros. Trabajemos en nuestro ejemplo más fácil:</para>
- <programlisting language="php"><![CDATA[
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive/(\d+)',
- array(
- 'controller' => 'archive',
- 'action' => 'show'
- ),
- array(
- 1 => 'year'
- )
- );
- $router->addRoute('archive', $route);
- ]]></programlisting>
- <para>Esto resultaraá en los siguientes valores inyectados a la solicitud:</para>
- <programlisting language="php"><![CDATA[
- $values = array(
- 'year' => '2006',
- 'controller' => 'archive',
- 'action' => 'show'
- );
- ]]></programlisting>
- <para>El mapa puede ser definido en cualquier dirección para hacer que
- funcione en cualquier
- ambiente. Las claves pueden contener nombres de
- variables o índices de sub-patrones:</para>
- <programlisting language="php"><![CDATA[
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive/(\d+)',
- array( ... ),
- array(1 => 'year')
- );
- // O
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive/(\d+)',
- array( ... ),
- array('year' => 1)
- );
- ]]></programlisting>
- <note>
- <para>Las claves de los sub-patrones deben respresentarse por enteros.
- </para>
- </note>
- <para>Observe que el índice numérico en los valores del Request ahora han
- desaparecido y en su
- lugar se muestra una variable nombrada. Por
- supuesto que puede mezclar variables nombradas y
- numéricas si lo desea:</para>
- <programlisting language="php"><![CDATA[
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive/(\d+)/page/(\d+)',
- array( ... ),
- array('year' => 1)
- );
- ]]></programlisting>
- <para>
- Lo que resultará en una mezcla de valores disponibles en la
- solicitud. Como ejemplo, la
- <acronym>URL</acronym>
- <filename>http://domain.com/archive/2006/page/10</filename>
- resultará
- con los siguientes valores:
- </para>
- <programlisting language="php"><![CDATA[
- $values = array(
- 'year' => '2006',
- 2 => 10,
- 'controller' => 'archive',
- 'action' => 'show'
- );
- ]]></programlisting>
- <para>
- Dado que los patrones regex no pueden invertirse fácilmente, tendrá
- que preparar una
- <acronym>URL</acronym>
- inversa si desea usar un
- ayudante de
- <acronym>URL</acronym>
- o incluso un método de ensamble de
- esta clase. Este path inverso está representado por un
- string parseable
- por
- <methodname>sprintf()</methodname>
- y se define como el cuarto parámetro del constructor:
- </para>
- <programlisting language="php"><![CDATA[
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive/(\d+)',
- array( ... ),
- array('year' => 1),
- 'archive/%s'
- );
- ]]></programlisting>
- <para>
- Todo esto es algo que ya fue posible de hacer por medio de un objeto
- de ruta estandard, por
- lo tanto podría preguntarese: ¿cuál es la ventaja
- de utilizar la ruta Regex?. Principalmente,
- le permite describir
- cualquier tipo de
- <acronym>URL</acronym>
- sin restricción alguna.
- Imagínese que tiene un blog y desea crear URLs como:
- <filename>http://domain.com/blog/archive/01-Using_the_Regex_Router.html</filename>
- ,
- y que tiene que descomponer el último elemento del path
- <filename>01-Using_the_Regex_Router.html</filename>
- , en un ID de
- artículo y en el título o descripción del artículo; esto no es posible con
- el
- standard route. Con la ruta Regex, puede hacer algo como la siguiente
- solución:
- </para>
- <programlisting language="php"><![CDATA[
- $route = new Zend_Controller_Router_Route_Regex(
- 'blog/archive/(\d+)-(.+)\.html',
- array(
- 'controller' => 'blog',
- 'action' => 'view'
- ),
- array(
- 1 => 'id',
- 2 => 'description'
- ),
- 'blog/archive/%d-%s.html'
- );
- $router->addRoute('blogArchive', $route);
- ]]></programlisting>
- <para>Como puede ver, esto añade una enorme cantidad de flexibilidad por
- encima del standard
- route.</para>
- </sect3>
|