Zend_Controller-Router-Route-Regex.xml 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 17592 -->
  3. <!-- Reviewed: no -->
  4. <sect3 id="zend.controller.router.routes.regex">
  5. <title>Zend_Controller_Router_Route_Regex</title>
  6. <para> Además de los tipos de ruta estáticos y por defecto, también está
  7. disponible el tipo de ruta Expresión Regular. Esta ruta ofrece más
  8. potencia y flexibilidad que los otros, pero a costa de un ligero aumento
  9. en la complejidad. Al mismo tiempo, debería ser más rápido que la
  10. standard Route. </para>
  11. <para> Al igual que la standard Route, esta ruta tiene que ser inicializada
  12. con una definición de ruta y algunos valores predeterminados. Vamos a
  13. crear un archivo ruta como un ejemplo, similar al previamente definido,
  14. sólo que esta vez usaremos la ruta Regex: </para>
  15. <programlisting language="php"><![CDATA[
  16. $route = new Zend_Controller_Router_Route_Regex(
  17. 'archive/(\d+)',
  18. array(
  19. 'controller' => 'archive',
  20. 'action' => 'show'
  21. )
  22. );
  23. $router->addRoute('archive', $route);
  24. ]]></programlisting>
  25. <para> Cada sub-patrón regex definido será inyectado al objeto solicitud.
  26. Con nuestro ejemplo anterior, después de un matching exitoso
  27. <filename>http://domain.com/archive/2006</filename>, el valor
  28. resultante del array puede verse como: </para>
  29. <programlisting language="php"><![CDATA[
  30. $values = array(
  31. 1 => '2006',
  32. 'controller' => 'archive',
  33. 'action' => 'show'
  34. );
  35. ]]></programlisting>
  36. <note>
  37. <para> Las barras de comienzo y final están recortadas de la
  38. <acronym>URL</acronym> en el Router antes de una concordancia.
  39. Como resultado, coincidendo con la <acronym>URL</acronym>
  40. <filename>http://domain.com/foo/bar/</filename>, involucraría al
  41. regex de <filename>foo/bar</filename>, y no a
  42. <filename>/foo/bar</filename>. </para>
  43. </note>
  44. <note>
  45. <para> Las anclas de comienzo y fin de línea ('^' y '$',
  46. respectivamente) son automáticamente antepuestas y pospuestas a
  47. todas las expresiones. Así, no debe usar éstas en sus expresiones
  48. regulares, y debe coincidir con el string completo. </para>
  49. </note>
  50. <note>
  51. <para> Esta clase de ruta usa el carácter <emphasis>#</emphasis>
  52. como un delimitador. Esto significa que necesitará caracteres hash
  53. ('#') para escapar pero no barras ('/') en sus definiciones de ruta.
  54. Dado que el carácter '#' (llamado ancla) es raramente pasado al
  55. webserver, será muy rara la necesidad de utilizar ese carácter en su
  56. regex. </para>
  57. </note>
  58. <para> Puede obtener el contenido de los sub-patrones definidos por la forma
  59. habitual: </para>
  60. <programlisting language="php"><![CDATA[
  61. public function showAction()
  62. {
  63. $request = $this->getRequest();
  64. $year = $request->getParam(1); // $year = '2006';
  65. }
  66. ]]></programlisting>
  67. <note>
  68. <para> Tenga en cuenta que la clave es un entero (1) en lugar de un
  69. string ('1'). </para>
  70. </note>
  71. <para> Sin embargo, esta ruta no funciona exactamente igual que su
  72. contraparte standard route dado que el valor por defecto para 'year'
  73. todavía no se ha establecido. Y lo que puede ser no tan evidente es que
  74. tendremos un problema con una barra final incluso si declaramos por
  75. defecto el año y hacemos opcional al sub-patrón. La solución es hacer
  76. que toda la parte del año sea opcional junto con la barra pero capturar
  77. solo la parte numérica: </para>
  78. <programlisting language="php"><![CDATA[
  79. $route = new Zend_Controller_Router_Route_Regex(
  80. 'archive(?:/(\d+))?',
  81. array(
  82. 1 => '2006',
  83. 'controller' => 'archive',
  84. 'action' => 'show'
  85. )
  86. );
  87. $router->addRoute('archive', $route);
  88. ]]></programlisting>
  89. <para> Ahora, ocupemósnos del problema que probablemente haya notado.
  90. Utilizar claves basadas en enteros para los parámetros no es una
  91. solución fácilmente manejable y puede ser potencialmente problemática a
  92. largo plazo. Y aquí es donde entra el tercer parámetro. Este parámetro
  93. es un array asociativo que representa un mapa de sub-patrones regex a
  94. nombres de clave de parámetros. Trabajemos en nuestro ejemplo más fácil: </para>
  95. <programlisting language="php"><![CDATA[
  96. $route = new Zend_Controller_Router_Route_Regex(
  97. 'archive/(\d+)',
  98. array(
  99. 'controller' => 'archive',
  100. 'action' => 'show'
  101. ),
  102. array(
  103. 1 => 'year'
  104. )
  105. );
  106. $router->addRoute('archive', $route);
  107. ]]></programlisting>
  108. <para> Esto resultaraá en los siguientes valores inyectados a la solicitud: </para>
  109. <programlisting language="php"><![CDATA[
  110. $values = array(
  111. 'year' => '2006',
  112. 'controller' => 'archive',
  113. 'action' => 'show'
  114. );
  115. ]]></programlisting>
  116. <para> El mapa puede ser definido en cualquier dirección para hacer que
  117. funcione en cualquier ambiente. Las claves pueden contener nombres de
  118. variables o índices de sub-patrones: </para>
  119. <programlisting language="php"><![CDATA[
  120. $route = new Zend_Controller_Router_Route_Regex(
  121. 'archive/(\d+)',
  122. array( ... ),
  123. array(1 => 'year')
  124. );
  125. // O
  126. $route = new Zend_Controller_Router_Route_Regex(
  127. 'archive/(\d+)',
  128. array( ... ),
  129. array('year' => 1)
  130. );
  131. ]]></programlisting>
  132. <note>
  133. <para> Las claves de los sub-patrones deben respresentarse por enteros.
  134. </para>
  135. </note>
  136. <para> Observe que el índice numérico en los valores del Request ahora han
  137. desaparecido y en su lugar se muestra una variable nombrada. Por
  138. supuesto que puede mezclar variables nombradas y numéricas si lo desea: </para>
  139. <programlisting language="php"><![CDATA[
  140. $route = new Zend_Controller_Router_Route_Regex(
  141. 'archive/(\d+)/page/(\d+)',
  142. array( ... ),
  143. array('year' => 1)
  144. );
  145. ]]></programlisting>
  146. <para> Lo que resultará en una mezcla de valores disponibles en la
  147. solicitud. Como ejemplo, la <acronym>URL</acronym>
  148. <filename>http://domain.com/archive/2006/page/10</filename> resultará
  149. con los siguientes valores: </para>
  150. <programlisting language="php"><![CDATA[
  151. $values = array(
  152. 'year' => '2006',
  153. 2 => 10,
  154. 'controller' => 'archive',
  155. 'action' => 'show'
  156. );
  157. ]]></programlisting>
  158. <para> Dado que los patrones regex no pueden invertirse fácilmente, tendrá
  159. que preparar una <acronym>URL</acronym> inversa si desea usar un
  160. ayudante de <acronym>URL</acronym> o incluso un método de ensamble de
  161. esta clase. Este path inverso está representado por un string parseable
  162. por <methodname>sprintf()</methodname> y se define como el cuarto parámetro del constructor: </para>
  163. <programlisting language="php"><![CDATA[
  164. $route = new Zend_Controller_Router_Route_Regex(
  165. 'archive/(\d+)',
  166. array( ... ),
  167. array('year' => 1),
  168. 'archive/%s'
  169. );
  170. ]]></programlisting>
  171. <para> Todo esto es algo que ya fue posible de hacer por medio de un objeto
  172. de ruta estandard, por lo tanto podría preguntarese: ¿cuál es la ventaja
  173. de utilizar la ruta Regex?. Principalmente, le permite describir
  174. cualquier tipo de <acronym>URL</acronym> sin restricción alguna.
  175. Imagínese que tiene un blog y desea crear URLs como:
  176. <filename>http://domain.com/blog/archive/01-Using_the_Regex_Router.html</filename>,
  177. y que tiene que descomponer el último elemento del path
  178. <filename>01-Using_the_Regex_Router.html</filename>, en un ID de
  179. artículo y en el título o descripción del artículo; esto no es posible con
  180. el standard route. Con la ruta Regex, puede hacer algo como la siguiente
  181. solución: </para>
  182. <programlisting language="php"><![CDATA[
  183. $route = new Zend_Controller_Router_Route_Regex(
  184. 'blog/archive/(\d+)-(.+)\.html',
  185. array(
  186. 'controller' => 'blog',
  187. 'action' => 'view'
  188. ),
  189. array(
  190. 1 => 'id',
  191. 2 => 'description'
  192. ),
  193. 'blog/archive/%d-%s.html'
  194. );
  195. $router->addRoute('blogArchive', $route);
  196. ]]></programlisting>
  197. <para> Como puede ver, esto añade una enorme cantidad de flexibilidad por
  198. encima del standard route. </para>
  199. </sect3>