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 (499 lines) | stat: -rw-r--r-- 20,465 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
<?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>Routeur Standard</title>

    <sect2 id="zend.controller.router.introduction">
        <title>Introduction</title>

        <para>
            <classname>Zend_Controller_Router_Rewrite</classname> est le routeur par défaut
            du framework. Le routage consiste à analyser l'URI définie (la partie après l'URL de
            base) et la décomposer en valeurs déterminant quels module, contrôleur et action
            doivent recevoir la requête. Ces valeurs sont encapsulées dans un objet de requête
            <classname>Zend_Controller_Request_Http</classname> qui est alors injecté dans
            <classname>Zend_Controller_Dispatcher_Standard</classname> pour y être traité Le
            routage n'est effectué qu'une seule fois par requête&#160;: juste avant que le premier
            contrôleur ne soit traité (distribué)
        </para>

        <para>
            <classname>Zend_Controller_Router_Rewrite</classname> intervient pour fournir un
            environnement de requête similaire à "mod_rewrite", tout en utilisant uniquement du
            <acronym>PHP</acronym>. Il est désigné sur les principes de Ruby on Rails et ne requière pas de
            connaissances particulières en réécriture d'URL. Il est destiné à fonctionner avec une
            seule règle de réécriture Apache, dont voici des exemples&#160;:
        </para>

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

        <para>ou (recommandé) :</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>
            Le routeur de réécriture peut aussi être utilisé avec un serveur Web <acronym>IIS</acronym>
            (versions &lt;= 7.0) si <ulink url="http://www.isapirewrite.com">Isapi_Rewrite</ulink>
            a été installée comme une extension Isap avec la règle suivante&#160;:
        </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>
                Lorsque <acronym>IIS</acronym> est utilisé, <varname>$_SERVER['REQUEST_URI']</varname> n'existera pas
                ou vaudra une chaîne vide. Dans ce cas,
                <classname>Zend_Controller_Request_Http</classname> essaiera d'utiliser la valeur
                de <varname>$_SERVER['HTTP_X_REWRITE_URL']</varname>, initialisée par l'extension
                Isapi_Rewrite.
            </para>
        </note>

        <para>
            <acronym>IIS</acronym> 7.0 introduit un moodule de réécriture d'URL natif, et il peut être configuré
            comme ceci&#160;:
        </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>Si vous utilisez Lighttpd, la règle de réécriture suivante est valide&#160;:</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>Utilisation d'un routeur</title>

        <para>
            Pour utiliser un routeur et le configurer, vous devez le récupérer et ajouter des
            routes&#160;:
        </para>

        <programlisting language="php"><![CDATA[
/* Créer un routeur */
$router = $frontctrl->getRouter();
// retourne un routeur de réécriture par défaut
$router->addRoute(
    'user',
    new Zend_Controller_Router_Route('user/:username',
                                     array('controller' => 'user',
                                           'action' => 'info'))
);
]]></programlisting>

    </sect2>

    <sect2 id="zend.controller.router.basic">

        <title>Utilisation basique du routeur de réécriture</title>

        <para>
            Le coeur de ce routeur repose sur le concept de routes personnalisées. Les routes
            sont ajoutées en appelant la méthode <methodname>addRoute()</methodname> et en lui passant une
            instance implémentant <classname>Zend_Controller_Router_Route_Interface</classname>.
            Exemple&#160;:
        </para>

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

        <para>
            Le routeur de réécriture est fourni avec six types de route, dont une
            spéciale&#160;:
        </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>&#160;*
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Chaque route peut être utilisée plusieurs fois pour créer un chaîne de routes
            représentant un schéma de routage personnalisé. La route du module, en revanche, ne
            devrait être utilisée qu'une seule fois, elle est en générale la route la plus
            générique (par défaut). Chaque route sera définie un peu plus tard.
        </para>

        <para>
            Le premier paramètre de <code>addRoute</code> est le nom de la route. Il sera
            utilisé plus tard pour la sélectionner (par exemple pour générer un <acronym>URL</acronym>. Le deuxième
            paramètre étant l'objet route lui-même.
        </para>

        <note>
            <para>
                L'utilisation la plus plausible du nom de la route est illustrée dans l'aide
                vue "url"&#160;:
            </para>
            <programlisting language="php"><![CDATA[
<a href="<?php echo $this->url(array('username' => 'martel'), 'user') ?>">
Martel
</a>
]]></programlisting>
            <para>Ce qui donnera un "href"&#160;: <code>user/martel</code>.</para>
        </note>

        <para>
            Le routage consiste simplement à itérer toutes les routes reçues et à les faire
            correspondre à l'URI de la requête courante. Dès qu'une correspondance est établie, les
            variables sont injectées dans l'objet <classname>Zend_Controller_Request</classname>
            utilisé après dans le distributeur et dans les contrôleurs. Si aucune correspondance
            n'est trouvée, la route suivante dans la pile est analysée.
        </para>

        <para>
            Si vous devez déterminer quelle route a été trouvée, vous pouvez utilisez la
            méthode <methodname>getCurrentRouteName()</methodname>, qui vous retournera l'identifiant utilisé
            pour enregistrer la route dans le routeur. Si vous souhaitez récupérer l'objet de la
            route actuelle, vous pouvez utiliser <methodname>getCurrentRoute()</methodname>.
        </para>

        <note>
            <title>Pile LIFO</title>
            <para>
                Les routes sont analysées dans l'ordre LIFO : dernière fournie, première
                analysée. Veillez à définir les routes les génériques en premier donc.
            </para>
        </note>

        <note>
            <title>Paramètres de la requête</title>
            <para>
                Les paramètres de la requête proviennent de l'utilisateur, ou des routes
                définies. Ils seront plus tard accessibles via
                <methodname>Zend_Controller_Request::getParam()</methodname> ou la méthode
                <methodname>Zend_Controller_Action::_getParam()</methodname>.
            </para>
        </note>

        <para>
            Il y a trois valeurs spéciales qui peuvent être utilisées dans la définition de
            vos routes&#160;: - "module", "controller" et "action" -. Ces valeurs sont utilisées par
            <classname>Zend_Controller_Dispatcher</classname> pour trouver les contrôleurs et
            action à distribuer.
        </para>

        <note>
            <title>Valeurs spéciales</title>
            <para>
                Le nom de ces valeurs peut être changé dans
                <classname>Zend_Controller_Request_Http</classname> avec les méthodes
                <code>setControllerKey</code> et <code>setActionKey</code>.
            </para>
        </note>

    </sect2>

    <sect2 id="zend.controller.router.default-routes">

        <title>Routes par défaut</title>

        <para>
            Zend_Controller_Router_Rewrite possède des routes par défaut qui vont
            correspondre pour des <acronym>URI</acronym> du type <code>controller/action</code>. De plus, un nom de
            module peut être spécifié comme premier élément du chemin, autorisant ainsi des <acronym>URI</acronym> du
            type <code>module/controller/action</code>. Enfin, chaque paramètres de la requête sera
            trouvé à la fin de la requête, comme
            <code>controller/action/var1/value1/var2/value2</code>.
        </para>

        <para>Exemples avec ces routes&#160;:</para>

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

Module seulement:
http://example/news
    module == news

Un module invalide dirige vers le contrôleur:
http://example/foo
    controller == foo

Module + controller:
http://example/blog/archive
    module     == blog
    controller == archive

Module + controller + action:
http://example/blog/archive/list
    module     == blog
    controller == archive
    action     == list

Module + controller + action + params:
http://example/blog/archive/list/sort/alpha/date/desc
    module     == blog
    controller == archive
    action     == list
    sort       == alpha
    date       == desc
]]></programlisting>

        <para>
            La route par défaut est simplement un objet
            <classname>Zend_Controller_Router_Route_Module</classname>, stocké sous le nom
            "default" dans le routeur de réécriture(RewriteRouter). Il est conçu comme ceci&#160;:
        </para>

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

        <para>
            Si vous ne souhaitez pas cette route par défaut, créez en une et stocker la avec
            le nom "default" (écrasement), ou supprimez la route avec
            <methodname>removeDefaultRoutes()</methodname>&#160;:
        </para>

        <programlisting language="php"><![CDATA[
// Supprime les routes par défaut
$router->removeDefaultRoutes();
]]></programlisting>
    </sect2>

    <sect2 id="zend.controller.router.rewritebase">
        <title>Base URL et sous dossiers</title>

        <para>
            Le routeur de réécriture peut être utilisé dans des sous dossiers (comme
            <code>http://domain.com/~user/application-root/</code>), dans un tél cas, l'URL de base
            de l'application (<code>/~user/application-root</code>) devrait être automatiquement
            détectée par <classname>Zend_Controller_Request_Http</classname> et utilisée
            ensuite.
        </para>

        <para>
            Si ça n'était pas le cas, vous pouvez spécifier votre propre base <acronym>URL</acronym>
            dans <classname>Zend_Controller_Request_Http</classname> en appelant
            <methodname>setBaseUrl()</methodname> (voyez <link
                linkend="zend.controller.request.http.baseurl">Base de l'URL et
                sous-dossiers</link>)&#160;:
        </para>

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

    <sect2 id="zend.controller.router.global.parameters">
        <title>Paramètres globaux</title>

        <para>
            Vous pouvez régler des paramètres globaux dans un routeur, qui sont
            automatiquement fournis à la route lors de son assemblage, grâce à la fonction
            <methodname>setGlobalParam()</methodname>. Si un paramètre global est réglé mais qu'il est aussi
            fourni directement à la méthode d'assemblage, le paramètre utilisateur écrase le
            paramètre global. Vous pouvez régler un paramètre global de cette manière&#160;:
        </para>

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

    <sect2 id="zend.controller.router.routes">
        <title>Types de route</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:fallback>
                <xi:include href="../../en/module_specs/Zend_Controller-Router-Route-Chain.xml" />
            </xi:fallback>
        </xi:include>
        <xi:include href="Zend_Controller-Router-Route-Rest.xml">
            <xi:fallback>
                <xi:include href="../../en/module_specs/Zend_Controller-Router-Route-Rest.xml" />
            </xi:fallback>
        </xi:include>
    </sect2>

    <sect2 id="zend.controller.router.add-config">
        <title>Utiliser Zend_Config avec le RewriteRouter</title>

        <para>
            Il arrive qu'il soit plus commode d'éditer un fichier de configuration de routes,
            plutôt que d'éditer un code source. Ceci est rendu possible par la méthode
            <methodname>addConfig()</methodname>. Vous créez un objet compatible Zend_Config et vous le passez
            à cette méthode.
        </para>

        <para>Par exemple, voyons un fichier <acronym>INI</acronym> :</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"
; OU: routes.archive.map.year = 1
]]></programlisting>

        <para>
            Ce fichier <acronym>INI</acronym> peut être lu dans grâce à un objet <classname>Zend_Config</classname>
            comme suit&#160;:
        </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>
            Nous indiquons au routeur d'utiliser la section "routes" du fichier <acronym>INI</acronym>. Chaque
            clé de premier niveau représente le nom de la route, ainsi nous avons dans l'exemple ci
            dessus "archive" et "news". Chaque route attend alors au moins une entrée "route" avec
            une ou plusieurs entrées "defaults"&#160;; optionnellement nous pouvons rajouter des
            paramètres obligatoires. Tout ceci correspond aux trois arguments fournis par l'objet
            implémentant <classname>Zend_Controller_Router_Route_Interface</classname>. Une entrée
            optionnelle "type" peut être utilisée pour indiquer le type de classe de routage à
            utiliser, il s'agit par défaut de <classname>Zend_Controller_Router_Route</classname>.
            Dans l'exemple au dessus, la route "news" va utiliser
            <classname>Zend_Controller_Router_Route_Static</classname>.
        </para>
    </sect2>

    <sect2 id="zend.controller.router.subclassing">
        <title>Dérivation de l'objet Router</title>

        <para>
            Le routeur par défaut, dit de réécriture, devrait suffire dans la majorité des
            projets. Tout ce qu'il peut être nécessaire de faire, est d'ajouter des routes
            particulières selon vos besoins.
        </para>

        <para>
            Cependant, si vous voulez utiliser votre propre logique de routage, une interface
            est disponible. <classname>Zend_Controller_Router_Interface</classname> ne définit
            qu'une seule méthode&#160;:
        </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>
            Le processus de routage n'intervient qu'une fois : lorsque la requête est reçue
            par le système. Le routeur doit alors déterminer un contrôleur, une action et de
            paramètres optionnel et les spécifier dans un objet de requête, qui est ensuite passé
            au distributeur. Si il n'est pas possible de router une requête, alors l'objet de
            requête devrait être laissé tel-quel.
        </para>
    </sect2>
</sect1>