Zend_Controller-Router-Route-Regex.xml 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 15156 -->
  3. <!-- Reviewed: no -->
  4. <sect3 id="zend.controller.router.routes.regex">
  5. <title>Zend_Controller_Router_Route_Regex</title>
  6. <para>
  7. Zusätzlich zu den standard statischen Routetypen, ist ein Regular Expression Routetyp vorhanden. Diese
  8. Route bietet mehr Power und Flexibilität als die anderen, aber auf leichten Kosten von Komplexität.
  9. Wärend der selben Zeit, sollte Sie schneller als die Standardroute sein.
  10. </para>
  11. <para>
  12. Wie die Standardroute, muß diese Route mit einer Routendefinition und einigen Standardwerten initialisiert
  13. werden. Lasst uns eine Archivroute als Beispiel erstellen, ähnlich der zuletzt definierten, nur das dieses
  14. Mal die Regex Route verwendet wird:
  15. </para>
  16. <programlisting role="php"><![CDATA[
  17. $route = new Zend_Controller_Router_Route_Regex(
  18. 'archive/(\d+)',
  19. array(
  20. 'controller' => 'archive',
  21. 'action' => 'show'
  22. )
  23. );
  24. $router->addRoute('archive', $route);
  25. ]]></programlisting>
  26. <para>
  27. Jedes definierte Regex Subpattern wird in das Anfrageobjekt injiziiert. Mit dem obigen Beispiel, nachdem
  28. <code>http://domain.com/archive/2006</code> erfolgreich geprüft wurde, kann das resultierende Wertearray
  29. so aussehen:
  30. </para>
  31. <programlisting role="php"><![CDATA[
  32. $values = array(
  33. 1 => '2006',
  34. 'controller' => 'archive',
  35. 'action' => 'show'
  36. );
  37. ]]></programlisting>
  38. <note>
  39. <para>
  40. Führende und folgende Schrägstriche werden von der URL im Router vor dem Vergleich entfernt. Als
  41. Ergebnis, wird ein Vergleich der URL <code>http://domain.com/foo/bar/</code>, ein Regex von
  42. <code>foo/bar</code> inkludieren, aber nicht <code>/foo/bar</code>.
  43. </para>
  44. </note>
  45. <note>
  46. <para>
  47. Zeilenbeginn und Endanker (normalerweise '^' und '$') werden automatisch allen Ausdrücken vor- und
  48. nachgesetzt. Deswegen sollten Sie nicht in den Regular Expressions verwendet werden, und der
  49. komplette String sollte entsprechen.
  50. </para>
  51. </note>
  52. <note>
  53. <para>
  54. Diese Routeklasse verwendet das <code>#</code> Zeichen als Begrenzer. Das bedeutet das ein Hashzeichen
  55. ('#') kommentiert werden muß aber keine Schrägstriche ('/') in der Routendefinition. Da das '#' Zeichen
  56. (Anker genannt) selben an einen Webserver übergeben wird, wird man dieses Zeichen selten in der eigenen
  57. regex verwenden.
  58. </para>
  59. </note>
  60. <para>
  61. Die Inhalte von definierten Subpattern können auf dem üblichen Weg bekommen werden:
  62. </para>
  63. <programlisting role="php"><![CDATA[
  64. public function showAction()
  65. {
  66. $request = $this->getRequest();
  67. $year = $request->getParam(1); // $year = '2006';
  68. }
  69. ]]></programlisting>
  70. <note>
  71. <para>Beachte das der Schlüssel ein Integer ist (1) anstatt ein String ('1').</para>
  72. </note>
  73. <para>
  74. Diese Route wird jetzt noch nicht exakt gleich wie Ihr Gegenspieler, die Standardroute, arbeiten da der
  75. Standard für 'year' noch nicht gesetzt ist. Und was jetzt noch nicht offensichtlich ist, ist das wir ein
  76. Problem mit endenden Schrägstrichen haben, selbst wenn wir einen Standard für das Jahr definieren und das
  77. Subpattern optional machen. Die Lösung ist, den ganzen year Teil optional zu nachen zusammen mit dem
  78. Schrägstrich, aber nur den nummerischen Teil zu holen:
  79. </para>
  80. <programlisting role="php"><![CDATA[
  81. $route = new Zend_Controller_Router_Route_Regex(
  82. 'archive(?:/(\d+))?',
  83. array(
  84. 1 => '2006',
  85. 'controller' => 'archive',
  86. 'action' => 'show'
  87. )
  88. );
  89. $router->addRoute('archive', $route);
  90. ]]></programlisting>
  91. <para>
  92. Jetzt betrachten wir das Problem das möglicherweise schon selbst gefunden wurde. Die Verwendung von Integer
  93. basierten Schlüsseln für Parameter ist keine einfach zu handhabende Lösung und kann, wärend einer langen
  94. Laufzeit, potentiell problematisch sein. Hier kommt der dritte Parameter ins Spiel. Dieser Parameter ist
  95. ein assoziatives Array das einer Karte von Regex Subpatterns zu Parametern benannten Schlüsseln entspricht.
  96. Betrachten wir ein einfacheres Beispiel:
  97. </para>
  98. <programlisting role="php"><![CDATA[
  99. $route = new Zend_Controller_Router_Route_Regex(
  100. 'archive/(\d+)',
  101. array(
  102. 'controller' => 'archive',
  103. 'action' => 'show'
  104. ),
  105. array(
  106. 1 => 'year'
  107. )
  108. );
  109. $router->addRoute('archive', $route);
  110. ]]></programlisting>
  111. <para>
  112. Als Ergebnis werden die folgenden Werte in die Anfrage injiziiert:
  113. </para>
  114. <programlisting role="php"><![CDATA[
  115. $values = array(
  116. 'year' => '2006',
  117. 'controller' => 'archive',
  118. 'action' => 'show'
  119. );
  120. ]]></programlisting>
  121. <para>
  122. Die Karte kann in jede Richtung definiert werden damit Sie in jeder Umgebung funktioniert. Schlüssel können
  123. Variablennamen oder Indezes von Subpattern enthalten:
  124. </para>
  125. <programlisting role="php"><![CDATA[
  126. $route = new Zend_Controller_Router_Route_Regex(
  127. 'archive/(\d+)',
  128. array( ... ),
  129. array(1 => 'year')
  130. );
  131. // ODER
  132. $route = new Zend_Controller_Router_Route_Regex(
  133. 'archive/(\d+)',
  134. array( ... ),
  135. array('year' => 1)
  136. );
  137. ]]></programlisting>
  138. <note>
  139. <para>
  140. Schlüssel von Subpattern müssen durch Integer repräsentiert werden.
  141. </para>
  142. </note>
  143. <para>
  144. Es gilt zu beachten das der nummerische Index in den Anfragewerten jetzt weg ist und eine benannte Variable
  145. statt Ihm angezeigt wird. Natürlich können nummerische und benannte Variablen gemischt werden wenn das
  146. gewünscht ist:
  147. </para>
  148. <programlisting role="php"><![CDATA[
  149. $route = new Zend_Controller_Router_Route_Regex(
  150. 'archive/(\d+)/page/(\d+)',
  151. array( ... ),
  152. array('year' => 1)
  153. );
  154. ]]></programlisting>
  155. <para>
  156. Das führt zu gemischten Werten die in der Anfrage vorhanden sind. Als Beispiel, wird die URL
  157. <code>http://domain.com/archive/2006/page/10</code> zu folgenden Werte führen:
  158. </para>
  159. <programlisting role="php"><![CDATA[
  160. $values = array(
  161. 'year' => '2006',
  162. 2 => 10,
  163. 'controller' => 'archive',
  164. 'action' => 'show'
  165. );
  166. ]]></programlisting>
  167. <para>
  168. Da Regex Patterns nicht einfach rückgängig zu machen sind, muß eine umgekehrte URL vorbereitet werden wenn
  169. ein URL Helfer verwendet werden soll oder sogar eine Herstellungsmethode dieser Klasse. Dieser
  170. umgekehrte Pfad wird durch einen String dargestellt der durch sprintf() durchsucht werden kann und als
  171. vierter Parameter definiert wird:
  172. </para>
  173. <programlisting role="php"><![CDATA[
  174. $route = new Zend_Controller_Router_Route_Regex(
  175. 'archive/(\d+)',
  176. array( ... ),
  177. array('year' => 1),
  178. 'archive/%s'
  179. );
  180. ]]></programlisting>
  181. <para>
  182. Da all das bereits etwas ist das durch die Bedeutung eines standardmäßigen Route Objektes möglich ist
  183. kommt natürlich die Frage aus worin der Vorteil einer regex Route besteht? Primär erlaubt Sie jeden Typ von
  184. URL zu beschreiben ohne irgendwelche Einschränkungen. Angenommen man hat einen Blog und will eine URL wie
  185. die folgende erstellen: <code>http://domain.com/blog/archive/01-Using_the_Regex_Router.html</code>, und
  186. muß das jetzt Pfad Element <code>01-Using_the_Regex_Router.html</code> bearbeiten, in eine Artikel ID und
  187. eine Artikel Titel/Beschreibung; das ist nicht möglich mit der Standardroute. Mit der Regex Route ist
  188. etwas wie die folgende Lösung möglich:
  189. </para>
  190. <programlisting role="php"><![CDATA[
  191. $route = new Zend_Controller_Router_Route_Regex(
  192. 'blog/archive/(\d+)-(.+)\.html',
  193. array(
  194. 'controller' => 'blog',
  195. 'action' => 'view'
  196. ),
  197. array(
  198. 1 => 'id',
  199. 2 => 'description'
  200. ),
  201. 'blog/archive/%d-%s.html'
  202. );
  203. $router->addRoute('blogArchive', $route);
  204. ]]></programlisting>
  205. <para>
  206. Wie man sieht, fügt das ein enormes Potential von Flexibilität zur Stnadardroute hinzu.
  207. </para>
  208. </sect3>
  209. <!--
  210. vim:se ts=4 sw=4 et:
  211. -->