File: Zend_Controller-Router.xml

package info (click to toggle)
zendframework 1.12.9%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 133,584 kB
  • sloc: xml: 1,311,829; php: 570,173; sh: 170; makefile: 125; sql: 121
file content (527 lines) | stat: -rw-r--r-- 21,982 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.controller.router" xmlns:xi="http://www.w3.org/2001/XInclude">
    <title>Der Standard Router</title>

    <sect2 id="zend.controller.router.introduction">
        <title>Einführung</title>

        <para>
            <classname>Zend_Controller_Router_Rewrite</classname> ist der Standard Router des
            Frameworks. Routing ist der Prozess der Übernahme und Zerteilung einer
            <acronym>URI</acronym> (dem Teil der <acronym>URI</acronym> der nach der Basis
            <acronym>URL</acronym> kommt), um zu ermitteln, welches Modul, welcher Controller und
            welche Aktion des Controllers die Anfrage erhalten soll. Die Definition des Moduls, des
            Controllers, der Aktion sowie weiterer Parameter wird in einem Objekt mit Namen
            <classname>Zend_Controller_Dispatcher_Token</classname> gekapselt, das dann vom
            <classname>Zend_Controller_Dispatcher_Standard</classname> verarbeitet wird. Das Routing
            geschieht nur einmal: wenn zu Beginn die Anfrage erhalten wird und bevor der erste
            Controller aufgerufen wird.
        </para>

        <para>
            <classname>Zend_Controller_Router_Rewrite</classname> wurde entwickelt, um mit reinen
            <acronym>PHP</acronym> Strukturen eine mod_rewrite ähnliche Funktionalität zu erlauben.
            Es richtet sich sehr frei nach dem Ruby on Rails Routing und benötigt kein tieferes
            Wissen über <acronym>URL</acronym> Weiterleitung des Webservers. Es wurde entwickelt, um
            mit einer einzigen mod_rewrite Regel zu arbeiten.
        </para>

        <programlisting language="php"><![CDATA[
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css|html)$ index.php
]]></programlisting>

        <para>
            oder (bevorzugt):
        </para>

        <programlisting language="php"><![CDATA[
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
]]></programlisting>

        <para>
            Der Rewrite Router kann auch mit dem <acronym>IIS</acronym> Webserver verwendet werden
            (Versionen &lt;= 7.0), wenn <ulink
                url="http://www.isapirewrite.com">Isapi_Rewrite</ulink> als Isapi
            Erweiterung installiert wurde und folgende Umschreibungsregel verwendet wird:
        </para>

        <programlisting language="php"><![CDATA[
RewriteRule ^[\w/\%]*(?:\.(?!(?:js|ico|gif|jpg|png|css|html)$)[\w\%]*$)? /index.php [I]
]]></programlisting>

        <note>
            <title>IIS Isapi_Rewrite</title>

            <para>
                Bei Verwendung von <acronym>IIS</acronym>, wird
                <varname>$_SERVER['REQUEST_URI']</varname> entweder nicht vorhanden oder auf einen
                leeren String gesetzt sein. In diesem Fall wird
                <classname>Zend_Controller_Request_Http</classname> versuchen, den durch die
                <classname>Isapi_Rewrite</classname> Erweiterung gesetzten Wert
                <varname>$_SERVER['HTTP_X_REWRITE_URL']</varname> zu verwenden.
            </para>
        </note>

        <para>
            <acronym>IIS</acronym> 7.0 führt ein natives <acronym>URL</acronym> Rewriting Modul
            ein, und kann wie folgt konfiguriert werden:
        </para>

        <programlisting language="xml"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
     <system.webServer>
         <rewrite>
             <rules>
                 <rule name="Imported Rule 1" stopProcessing="true">
                     <match url="^.*$" />
                     <conditions logicalGrouping="MatchAny">
                         <add input="{REQUEST_FILENAME}"
                             matchType="IsFile" pattern=""
                             ignoreCase="false" />
                         <add input="{REQUEST_FILENAME}"
                             matchType="IsDirectory"
                             pattern="" ignoreCase="false" />
                     </conditions>
                     <action type="None" />
                 </rule>
                 <rule name="Imported Rule 2" stopProcessing="true">
                     <match url="^.*$" />
                     <action type="Rewrite" url="index.php" />
                 </rule>
             </rules>
         </rewrite>
     </system.webServer>
</configuration>
]]></programlisting>

        <para>
            Bei der Verwendung von Lighttpd, ist folgende Umschreibungsregel gültig:
        </para>

        <programlisting language="lighttpd"><![CDATA[
url.rewrite-once = (
    ".*\?(.*)$" => "/index.php?$1",
    ".*\.(js|ico|gif|jpg|png|css|html)$" => "$0",
    "" => "/index.php"
)
]]></programlisting>
    </sect2>

    <sect2 id="zend.controller.router.usage">
        <title>Einen Router verwenden</title>

        <para>
            Um den Rewrite Router richtig zu verwenden, muß er instanziiert, einige
            benutzerdefinierte Routen hinzufügt und in den Controller einbunden werden. Der folgende
            Code veranschaulicht die Vorgehensweise:
        </para>

        <programlisting language="php"><![CDATA[
// Einen Router erstellen

$router = $ctrl->getRouter(); // gibt standardmäßig einen Rewrite Router zurück
$router->addRoute(
    'user',
    new Zend_Controller_Router_Route('user/:username',
                                     array('controller' => 'user',
                                           'action' => 'info'))
);
]]></programlisting>
    </sect2>

    <sect2 id="zend.controller.router.basic">
        <title>Grundsätzliche Rewrite Router Operationen</title>

        <para>
            Das Herz des RewriteRouters ist die Definition von Benutzerdefinierten Routen. Routen
            werden durch aufruf der addRoute Methode des RewriteRouters hinzugefügt und übergeben
            eine neue Instanz einer Klasse die
            <classname>Zend_Controller_Router_Route_Interface</classname> implementiert. Z.B.:
        </para>

        <programlisting language="php"><![CDATA[
$router->addRoute('user',
                  new Zend_Controller_Router_Route('user/:username'));
]]></programlisting>

        <para>
            Der Rewrite Router kommt mit sechs Basistypen von Routen (eine von denen ist speziell):
            is special):
        </para>

        <itemizedlist mark="opencircle">
            <listitem>
                <para>
                    <link
                        linkend="zend.controller.router.routes.standard">Zend_Controller_Router_Route</link>
                </para>
            </listitem>

            <listitem>
                <para>
                    <link
                        linkend="zend.controller.router.routes.static">Zend_Controller_Router_Route_Static</link>
                </para>
            </listitem>

            <listitem>
                <para>
                    <link
                        linkend="zend.controller.router.routes.regex">Zend_Controller_Router_Route_Regex</link>
                </para>
            </listitem>

            <listitem>
                <para>
                    <link
                        linkend="zend.controller.router.routes.hostname">Zend_Controller_Router_Route_Hostname</link>
                </para>
            </listitem>

            <listitem>
                <para>
                    <link
                        linkend="zend.controller.router.routes.chain">Zend_Controller_Router_Route_Chain</link>
                </para>
            </listitem>

            <listitem>
                <para>
                    <link
                        linkend="zend.controller.router.default-routes">Zend_Controller_Router_Rewrite</link>
                    *
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Routen können unzählige Male verwendet werden um eine Kette oder benutzerdefinierte
            Routing Schemas von Anwendungen zu erstellen. Es kann jede beliebige Anzahl von Routen
            in jeder beliebigen Konfiguration verwendet werden, mit Ausnahme der Modul Route, welche
            nur einmal verwendet werden sollte, und möglicherweise die am meisten standardmäßige
            Route ist (z.B., als ein Standard). Jede Route wird später detailiert beschrieben.
        </para>

        <para>
            Der erste Parameter für addRoute ist der Name der Route. Er wird als Handle verwendet um
            die Route außerhalb des Routers zu erhalten (z.B. für den Zweck der
            <acronym>URL</acronym> Erzeugung). Der zweite Parameter ist die Route selbst.
        </para>

        <note>
            <para>
                Die gewöhnlichste Verwendung des Namens der Route ist gegeben durch die Zwecke des
                <classname>Zend_View</classname> Url Helfers:
            </para>

            <programlisting language="php"><![CDATA[
<a href=
"<?php echo $this->url(array('username' => 'martel'), 'user') ?>">Martel</a>
]]></programlisting>

            <para>
                Was zu folgender href führt: <filename>user/martel</filename>.
            </para>
        </note>

        <para>
            Routen ist ein einfacher Prozess des Durchlaufens aller vorhandenen Routen und
            Vergleichens deren Definitionen mit der aktuellen Anfrage <acronym>URI</acronym>. Wenn
            ein positiver Vergleich gefunden wird, werden variable Werte von der Instanz des Routers
            zurückgegeben, und werden für die spätere Verwendung im Dispatcher in das
            <classname>Zend_Controller_Request</classname> Objekt iniziiert, sowie in von Benutzern
            erstellten Controllern. Bei einem negativen Ergebnis des Vergleiches, wird die nächste
            Route in der Kette geprüft.
        </para>

        <para>
            Wenn man herausfinden will welche Route gepasst hat, kann man die
            <methodname>getCurrentRouteName()</methodname> Methode verwenden, die den Identifikator
            zurückgibt der verwendet wurde als die Route im Router registriert wurde. Wenn man das
            aktuelle Route Objekt benötigt, kann <methodname>getCurrentRoute()</methodname>
            verwendet werden.
        </para>

        <note>
            <title>Umgekehrter Vergleich</title>

            <para>
                Routen werden in umgekehrter Reihenfolge verglichen. Deswegen muß sichergestellt
                werden das die generellen Routen zuerst definiert werden.
            </para>
        </note>

        <note>
            <title>Zurückgegebene Werte</title>

            <para>
                Werte die vom Routen zurückgegeben werden kommen von <acronym>URL</acronym>
                Parametern oder Benutzerdefinierten Router Standards. Diese Variablen sind später
                durch die <methodname>Zend_Controller_Request::getParam()</methodname> oder
                <methodname>Zend_Controller_Action::_getParam()</methodname>Methoden verwendbar.
            </para>
        </note>

        <para>
            Es gibt drei spezielle Variablen welche in den Routen verwendet werden können -
            'module', 'controller' und 'action'. Diese speziellen Variablen werden durch
            <classname>Zend_Controller_Dispatcher</classname> verwendet um einen Controller und die
            Aktion zu funden zu der verwiesen wird.
        </para>

        <note>
            <title>Spezielle Variablen</title>

            <para>
                Die Namen dieser speziellen Variablen kann unterschiedlich sein wenn entschieden
                wird die Standards in <classname>Zend_Controller_Request_Http</classname> mithilfe
                der <methodname>setControllerKey()</methodname> und
                <methodname>setActionKey()</methodname> Methode zu Ändern.
            </para>
        </note>
    </sect2>

    <sect2 id="zend.controller.router.default-routes">
        <title>Standard Routen</title>

        <para>
            <classname>Zend_Controller_Router_Rewrite</classname> kommt mit einer Standard Route
            vorkonfiguriert, welche <acronym>URI</acronym>s im Sinn von
            <filename>controller/action</filename> entspricht. Zusätzlich kann ein Modul Name als
            erstes Pfad Element definiert werden, welches <acronym>URI</acronym>s in der Form von
            <filename>module/controller/action</filename> erlaubt. Letztendlich wird es auch allen
            zusätzlichen Parametern entsprechen die der <acronym>URI</acronym> standardmäßig
            hinzugefügt wurden - <filename>controller/action/var1/value1/var2/value2</filename>.
        </para>

        <para>
            Einige Beispiele wie solche Routen verglichen werden:
        </para>

        <programlisting language="php"><![CDATA[
// Folgende Annahme:
$ctrl->setControllerDirectory(
    array(
        'default' => '/path/to/default/controllers',
        'news'    => '/path/to/news/controllers',
        'blog'    => '/path/to/blog/controllers'
    )
);

Nur Modul:
http://example/news
    module == news

Ungültiges Modul, geht an den Controller Namen:
http://example/foo
    controller == foo

Modul + Controller:
http://example/blog/archive
    module     == blog
    controller == archive

Modul + Controller + Aktion:
http://example/blog/archive/list
    module     == blog
    controller == archive
    action     == list

Modul + Controller + Aktion + Parameter:
http://example/blog/archive/list/sort/alpha/date/desc
    module     == blog
    controller == archive
    action     == list
    sort       == alpha
    date       == desc
]]></programlisting>

        <para>
            Die Standardroute ist einfach ein
            <classname>Zend_Controller_Router_Route_Module</classname> Objekt welches unter dem
            Namen (Index) 'default' im RewriteRouter gespeichert ist. Es wird mehr oder weniger wie
            folgt erstellt:
        </para>

        <programlisting language="php"><![CDATA[
$compat = new Zend_Controller_Router_Route_Module(array(),
                                                  $dispatcher,
                                                  $request);
$this->addRoute('default', $compat);
]]></programlisting>

        <para>
            Wenn diese spezielle Standard Route im eigenen Routing Schema nicht gewünscht ist, kann
            Sie durch Erstellung einer eigenen 'default' Route überschrieben werden (z.B. durch
            Speichern unter dem Namen 'default') oder dem kompletten Entfernen durch verwenden von
            <methodname>removeDefaultRoutes()</methodname>:
        </para>

        <programlisting language="php"><![CDATA[
// Löschen aller Standard Routen
$router->removeDefaultRoutes();
]]></programlisting>
    </sect2>

    <sect2 id="zend.controller.router.rewritebase">
        <title>Basis URL und Unterverzeichnisse</title>

        <para>
            Der Rewrite Router kann in Unterverzeichnissen verwendet werden (z.B.
            <filename>http://domain.com/user/application-root/</filename>) und in diesem Fall
            sollte die Basis <acronym>URL</acronym> der Anwendung
            (<filename>/user/application-root</filename>) automatisch durch
            <classname>Zend_Controller_Request_Http</classname> erkannt und auch verwendet werden.
        </para>

        <para>
            Sollte die Basis <acronym>URL</acronym> nicht richtig erkannt werden kann diese mit
            eigenen Basispfad überschrieben werden durch Verwendung von
            <classname>Zend_Controller_Request_Http</classname> und Auruf der
            <methodname>setBaseUrl()</methodname> Methode (siehe <link
                linkend="zend.controller.request.http.baseurl">Basis URL und
                Unterverzeichnisse</link>):
        </para>

        <programlisting language="php"><![CDATA[
$request->setBaseUrl('/~user/application-root/');
]]></programlisting>
    </sect2>

    <sect2 id="zend.controller.router.global.parameters">
        <title>Globale Parameter</title>

        <para>
            Man kann in einem Router globale Parameter setzen die der Route automatisch zur
            Verfügung stehen wenn Sie durch <methodname>setGlobalParam()</methodname> eingefügt
            werden. Wenn ein globaler Parameter gesetzt ist, aber auch direkt an die Assemble
            Methode gegeben wird, überschreibt der Benutzer-Parameter den Globalen-Parameter.
            Globale Parameter können auf folgendem Weg gesetzt werden:
        </para>

        <programlisting language="php"><![CDATA[
$router->setGlobalParam('lang', 'en');
]]></programlisting>
    </sect2>

    <sect2 id="zend.controller.router.routes">
        <title>Router Typen</title>
        <xi:include href="Zend_Controller-Router-Route.xml" />
        <xi:include href="Zend_Controller-Router-Route-Static.xml" />
        <xi:include href="Zend_Controller-Router-Route-Regex.xml" />
        <xi:include href="Zend_Controller-Router-Route-Hostname.xml" />
        <xi:include href="Zend_Controller-Router-Route-Chain.xml" />
        <xi:include href="Zend_Controller-Router-Route-Rest.xml" />
    </sect2>

    <sect2 id="zend.controller.router.add-config">
        <title>Zend_Config mit dem RewriteRouter verwenden</title>

        <para>
            Manchmal ist es praktischer, eine Konfigurationsdatei mit neuen Routen zu
            aktualisieren, als den Code zu ändern. Dies ist mit Hilfe der
            <methodname>addConfig()</methodname> Methode möglich. Im Wesentlichen kann man eine
            <classname>Zend_Config</classname> kompatible Konfiguration erstellen, in seinem Code
            einlesen und an den RewriteRouter übergeben:
        </para>

        <para>
            Als Beispiel wird die folgende <acronym>INI</acronym> Datei angenommen:
        </para>

        <programlisting language="php"><![CDATA[
[production]
routes.archive.route = "archive/:year/*"
routes.archive.defaults.controller = archive
routes.archive.defaults.action = show
routes.archive.defaults.year = 2000
routes.archive.reqs.year = "\d+"

routes.news.type = "Zend_Controller_Router_Route_Static"
routes.news.route = "news"
routes.news.defaults.controller = "news"
routes.news.defaults.action = "list"

routes.archive.type = "Zend_Controller_Router_Route_Regex"
routes.archive.route = "archive/(\d+)"
routes.archive.defaults.controller = "archive"
routes.archive.defaults.action = "show"
routes.archive.map.1 = "year"
; OR: routes.archive.map.year = 1
]]></programlisting>

        <para>
            Die oben angeführte <acronym>INI</acronym> Datei kann dann wie folgt in ein
            <classname>Zend_Config</classname> Objekt eingelesen werden:
        </para>

        <programlisting language="php"><![CDATA[
$config = new Zend_Config_Ini('/path/to/config.ini', 'production');
$router = new Zend_Controller_Router_Rewrite();
$router->addConfig($config, 'routes');
]]></programlisting>

        <para>
            Im oberen Beispiel teilen wir dem Router mit, den 'routes' Bereich der
            <acronym>INI</acronym> Datei für seine Routen zu verwenden. Jeder Schlüssel auf erster
            Ebene in diesem Bereich wird verwendet, um den Namen der Routen zu definieren; das obige
            Beispiel definiert die Routen 'archive' und 'news'. Jede Route erfordert dann mindestens
            einen 'route' Eintrag und einen oder mehrere 'defaults' Einträge; optional können eine
            oder mehrere 'reqs' (kurz für 'required', d.h. erforderlich) Einträge angegeben werden.
            Alles in allem entspricht dies den drei Argumenten, die an ein
            <classname>Zend_Controller_Router_Route_Interface</classname> Objekt übergeben werden.
            Ein Optionsschlüssel 'type' kann verwendet werden, um den Typ der Routenklasse für
            diese Route anzugeben; standardmäßig wird
            <classname>Zend_Controller_Router_Route</classname> verwendet. Im obigen Beispiel wird
            die 'news' Route definiert, um
            <classname>Zend_Controller_Router_Route_Static</classname> zu verwenden.
        </para>
    </sect2>

    <sect2 id="zend.controller.router.subclassing">
        <title>Erben vom Router</title>

        <para>
            Der Standard Rewrite Router sollte die meisten Funktionalitäten die benötigt werden zur
            Verfügung stellen; meistens wird es nur notwendig sein einen neuen Router Typen zu
            erstellen um neue oder modifizierte Funktionalitäten für die verfügbaren Routen zu
            bieten.
        </para>

        <para>
            So gesehen, wird man in einigen Fällen ein anderes Routing Paradigma verwenden wollen.
            Das Interface <classname>Zend_Controller_Router_Interface</classname> bietet die
            minimalen Information die benötigt werden um einen Router er erstellen und besteht aus
            einer einzigen Methode.
        </para>

        <programlisting language="php"><![CDATA[
interface Zend_Controller_Router_Interface
{
  /**
   * @param  Zend_Controller_Request_Abstract $request
   * @throws Zend_Controller_Router_Exception
   * @return Zend_Controller_Request_Abstract
   */
  public function route(Zend_Controller_Request_Abstract $request);
}
]]></programlisting>

        <para>
            Das Routing findet nur einmal statt, wenn die Anfrage das erste Mal vom System erhalten
            wird. Der Zweck des Routers ist es, Controller, Aktion und optionale Parameter auf Basis
            der Anfrageumgebung zu ermitteln und im Request zu setzen. Das Request Objekt wird dann
            an den Dispatcher übergeben. Wenn es nicht möglich ist, eine Route auf einen Dispatch
            Token abzubilden, soll der Router nichts mit dem Request Objekt machen.
        </para>
    </sect2>
</sect1>