| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- <?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 : 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 :
- </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 <= 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 :
- </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 :
- </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 :</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 :
- </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 :
- </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 :
- </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>
- 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" :
- </para>
- <programlisting language="php"><![CDATA[
- <a href="<?php echo $this->url(array('username' => 'martel'), 'user') ?>">
- Martel
- </a>
- ]]></programlisting>
- <para>Ce qui donnera un "href" : <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 : - "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 :</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 :
- </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> :
- </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>) :
- </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 :
- </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 :
- </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" ; 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 :
- </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>
|