| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- <?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>
- Zusätzlich zu den standard statischen Routetypen, ist ein Regular Expression Routetyp
- vorhanden. Diese Route bietet mehr Power und Flexibilität als die anderen, aber auf leichten
- Kosten von Komplexität. Wärend der selben Zeit, sollte Sie schneller als die Standardroute
- sein.
- </para>
- <para>
- Wie die Standardroute, muß diese Route mit einer Routendefinition und einigen Standardwerten
- initialisiert werden. Lasst uns eine Archivroute als Beispiel erstellen, ähnlich der zuletzt
- definierten, nur das dieses Mal die Regex Route verwendet wird:
- </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>
- Jedes definierte Regex Subpattern wird in das Anfrageobjekt injiziiert. Mit dem obigen
- Beispiel, nachdem <filename>http://domain.com/archive/2006</filename> erfolgreich geprüft
- wurde, kann das resultierende Wertearray so aussehen:
- </para>
- <programlisting language="php"><![CDATA[
- $values = array(
- 1 => '2006',
- 'controller' => 'archive',
- 'action' => 'show'
- );
- ]]></programlisting>
- <note>
- <para>
- Führende und folgende Schrägstriche werden von der <acronym>URL</acronym> im Router vor
- dem Vergleich entfernt. Als Ergebnis, wird ein Vergleich der <acronym>URL</acronym>
- <filename>http://domain.com/foo/bar/</filename>, ein Regex von
- <filename>foo/bar</filename> inkludieren, aber nicht <filename>/foo/bar</filename>.
- </para>
- </note>
- <note>
- <para>
- Zeilenbeginn und Endanker (normalerweise '^' und '$') werden automatisch allen
- Ausdrücken vor- und nachgesetzt. Deswegen sollten Sie nicht in den Regular Expressions
- verwendet werden, und der komplette String sollte entsprechen.
- </para>
- </note>
- <note>
- <para>
- Diese Routeklasse verwendet das '<emphasis>#</emphasis>' Zeichen als Begrenzer. Das
- bedeutet das ein Hashzeichen ('#') kommentiert werden muß aber keine Schrägstriche ('/')
- in der Routendefinition. Da das '#' Zeichen (Anker genannt) selben an einen Webserver
- übergeben wird, wird man dieses Zeichen selten in der eigenen regex verwenden.
- </para>
- </note>
- <para>
- Die Inhalte von definierten Subpattern können auf dem üblichen Weg bekommen werden:
- </para>
- <programlisting language="php"><![CDATA[
- public function showAction()
- {
- $request = $this->getRequest();
- $year = $request->getParam(1); // $year = '2006';
- }
- ]]></programlisting>
- <note>
- <para>Beachte das der Schlüssel ein Integer ist (1) anstatt ein String ('1').</para>
- </note>
- <para>
- Diese Route wird jetzt noch nicht exakt gleich wie Ihr Gegenspieler, die Standardroute,
- arbeiten da der Standard für 'year' noch nicht gesetzt ist. Und was jetzt noch nicht
- offensichtlich ist, ist das wir ein Problem mit endenden Schrägstrichen haben, selbst wenn
- wir einen Standard für das Jahr definieren und das Subpattern optional machen. Die Lösung
- ist, den ganzen year Teil optional zu nachen zusammen mit dem Schrägstrich, aber nur den
- nummerischen Teil zu holen:
- </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>
- Jetzt betrachten wir das Problem das möglicherweise schon selbst gefunden wurde. Die
- Verwendung von Integer basierten Schlüsseln für Parameter ist keine einfach zu handhabende
- Lösung und kann, während einer langen Laufzeit, potentiell problematisch sein. Hier kommt der
- dritte Parameter ins Spiel. Dieser Parameter ist ein assoziatives Array das einer Karte von
- Regex Subpatterns zu Parametern benannten Schlüsseln entspricht. Betrachten wir ein
- einfacheres Beispiel:
- </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>
- Als Ergebnis werden die folgenden Werte in die Anfrage injiziiert:
- </para>
- <programlisting language="php"><![CDATA[
- $values = array(
- 'year' => '2006',
- 'controller' => 'archive',
- 'action' => 'show'
- );
- ]]></programlisting>
- <para>
- Die Karte kann in jede Richtung definiert werden damit Sie in jeder Umgebung funktioniert.
- Schlüssel können Variablennamen oder Indezes von Subpattern enthalten:
- </para>
- <programlisting language="php"><![CDATA[
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive/(\d+)',
- array( ... ),
- array(1 => 'year')
- );
- // ODER
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive/(\d+)',
- array( ... ),
- array('year' => 1)
- );
- ]]></programlisting>
- <note>
- <para>
- Schlüssel von Subpattern müssen durch Integer repräsentiert werden.
- </para>
- </note>
- <para>
- Es gilt zu beachten das der nummerische Index in den Anfragewerten jetzt weg ist und eine
- benannte Variable statt Ihm angezeigt wird. Natürlich können nummerische und benannte
- Variablen gemischt werden wenn das gewünscht ist:
- </para>
- <programlisting language="php"><![CDATA[
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive/(\d+)/page/(\d+)',
- array( ... ),
- array('year' => 1)
- );
- ]]></programlisting>
- <para>
- Das führt zu gemischten Werten die in der Anfrage vorhanden sind. Als Beispiel, wird die
- <acronym>URL</acronym> <filename>http://domain.com/archive/2006/page/10</filename> zu
- folgenden Werte führen:
- </para>
- <programlisting language="php"><![CDATA[
- $values = array(
- 'year' => '2006',
- 2 => 10,
- 'controller' => 'archive',
- 'action' => 'show'
- );
- ]]></programlisting>
- <para>
- Da Regex Patterns nicht einfach rückgängig zu machen sind, muß eine umgekehrte
- <acronym>URL</acronym> vorbereitet werden wenn ein <acronym>URL</acronym> Helfer verwendet
- werden soll oder sogar eine Herstellungsmethode dieser Klasse. Dieser umgekehrte Pfad wird
- durch einen String dargestellt der durch <methodname>sprintf()</methodname> durchsucht
- werden kann und als vierter Parameter definiert wird:
- </para>
- <programlisting language="php"><![CDATA[
- $route = new Zend_Controller_Router_Route_Regex(
- 'archive/(\d+)',
- array( ... ),
- array('year' => 1),
- 'archive/%s'
- );
- ]]></programlisting>
- <para>
- Da all das bereits etwas ist das durch die Bedeutung eines standardmäßigen Route Objektes
- möglich ist kommt natürlich die Frage aus worin der Vorteil einer regex Route besteht?
- Primär erlaubt Sie jeden Typ von <acronym>URL</acronym> zu beschreiben ohne irgendwelche
- Einschränkungen. Angenommen man hat einen Blog und will eine <acronym>URL</acronym> wie die
- folgende erstellen:
- <filename>http://domain.com/blog/archive/01-Using_the_Regex_Router.html</filename>, und muß
- das jetzt Pfad Element <filename>01-Using_the_Regex_Router.html</filename> bearbeiten, in
- eine Artikel ID und eine Artikel Titel oder Beschreibung; das ist nicht möglich mit der
- Standardroute. Mit der Regex Route ist etwas wie die folgende Lösung möglich:
- </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>
- Wie man sieht, fügt das ein enormes Potential von Flexibilität zur Stnadardroute hinzu.
- </para>
- </sect3>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|