Zend_Controller-Router-Route-Regex.xml 8.3 KB

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