Zend_Controller-Router-Route-Regex.xml 8.5 KB

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