Zend_Controller-Router.xml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- EN-Revision: 15617 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.controller.router" xmlns:xi="http://www.w3.org/2001/XInclude">
  5. <title>Routeur Standard</title>
  6. <sect2 id="zend.controller.router.introduction">
  7. <title>Introduction</title>
  8. <para>
  9. <classname>Zend_Controller_Router_Rewrite</classname> est le routeur par défaut
  10. du framework. Le routage consiste à analyser l'URI définie (la partie après l'URL de
  11. base) et la décomposer en valeurs déterminant quels module, contrôleur et action
  12. doivent recevoir la requête. Ces valeurs sont encapsulées dans un objet de requête
  13. <classname>Zend_Controller_Request_Http</classname> qui est alors injecté dans
  14. <classname>Zend_Controller_Dispatcher_Standard</classname> pour y être traité Le
  15. routage n'est effectué qu'une seule fois par requête&#160;: juste avant que le premier
  16. contrôleur ne soit traité (distribué)
  17. </para>
  18. <para>
  19. <classname>Zend_Controller_Router_Rewrite</classname> intervient pour fournir un
  20. environnement de requête similaire à "mod_rewrite", tout en utilisant uniquement du
  21. PHP. Il est désigné sur les principes de Ruby on Rails et ne requière pas de
  22. connaissances particulières en réécriture d'URL. Il est destiné à fonctionner avec une
  23. seule règle de réécriture Apache, dont voici des exemples&#160;:
  24. </para>
  25. <programlisting language="php"><![CDATA[
  26. RewriteEngine on
  27. RewriteRule !\.(js|ico|gif|jpg|png|css|html)$ index.php
  28. ]]></programlisting>
  29. <para>ou (recommandé) :</para>
  30. <programlisting language="php"><![CDATA[
  31. RewriteEngine On
  32. RewriteCond %{REQUEST_FILENAME} -s [OR]
  33. RewriteCond %{REQUEST_FILENAME} -l [OR]
  34. RewriteCond %{REQUEST_FILENAME} -d
  35. RewriteRule ^.*$ - [NC,L]
  36. RewriteRule ^.*$ index.php [NC,L]
  37. ]]></programlisting>
  38. <para>
  39. Le routeur de réécriture peut aussi être utilisé avec un serveur Web IIS
  40. (versions &lt;= 7.0) si <ulink url="http://www.isapirewrite.com">Isapi_Rewrite</ulink>
  41. a été installée comme une extension Isap avec la règle suivante&#160;:
  42. </para>
  43. <programlisting language="php"><![CDATA[
  44. RewriteRule ^[\w/\%]*(?:\.(?!(?:js|ico|gif|jpg|png|css|html)$)[\w\%]*$)? /index.php [I]
  45. ]]></programlisting>
  46. <note>
  47. <title>IIS Isapi_Rewrite</title>
  48. <para>
  49. Lorsque IIS est utilisé, <code>$_SERVER['REQUEST_URI']</code> n'existera pas
  50. ou vaudra une chaîne vide. Dans ce cas,
  51. <classname>Zend_Controller_Request_Http</classname> essaiera d'utiliser la valeur
  52. de <code>$_SERVER['HTTP_X_REWRITE_URL']</code>, initialisée par l'extension
  53. Isapi_Rewrite.
  54. </para>
  55. </note>
  56. <para>
  57. IIS 7.0 introduit un moodule de réécriture d'URL natif, et il peut être configuré
  58. comme ceci&#160;:
  59. </para>
  60. <programlisting language="xml"><![CDATA[
  61. <?xml version="1.0" encoding="UTF-8"?>
  62. <configuration>
  63. <system.webServer>
  64. <rewrite>
  65. <rules>
  66. <rule name="Imported Rule 1" stopProcessing="true">
  67. <match url="^.*$" />
  68. <conditions logicalGrouping="MatchAny">
  69. <add input="{REQUEST_FILENAME}"
  70. matchType="IsFile" pattern=""
  71. ignoreCase="false" />
  72. <add input="{REQUEST_FILENAME}"
  73. matchType="IsDirectory"
  74. pattern="" ignoreCase="false" />
  75. </conditions>
  76. <action type="None" />
  77. </rule>
  78. <rule name="Imported Rule 2" stopProcessing="true">
  79. <match url="^.*$" />
  80. <action type="Rewrite" url="index.php" />
  81. </rule>
  82. </rules>
  83. </rewrite>
  84. </system.webServer>
  85. </configuration>
  86. ]]></programlisting>
  87. <para>Si vous utilisez Lighttpd, la règle de réécriture suivante est valide&#160;:</para>
  88. <programlisting language="lighttpd"><![CDATA[
  89. url.rewrite-once = (
  90. ".*\?(.*)$" => "/index.php?$1",
  91. ".*\.(js|ico|gif|jpg|png|css|html)$" => "$0",
  92. "" => "/index.php"
  93. )
  94. ]]></programlisting>
  95. </sect2>
  96. <sect2 id="zend.controller.router.usage">
  97. <title>Utilisation d'un routeur</title>
  98. <para>
  99. Pour utiliser un routeur et le configurer, vous devez le récupérer et ajouter des
  100. routes&#160;:
  101. </para>
  102. <programlisting language="php"><![CDATA[
  103. /* Créer un routeur */
  104. $router = $frontctrl->getRouter();
  105. // retourne un routeur de réécriture par défaut
  106. $router->addRoute(
  107. 'user',
  108. new Zend_Controller_Router_Route('user/:username',
  109. array('controller' => 'user',
  110. 'action' => 'info'))
  111. );
  112. ]]></programlisting>
  113. </sect2>
  114. <sect2 id="zend.controller.router.basic">
  115. <title>Utilisation basique du routeur de réécriture</title>
  116. <para>
  117. Le coeur de ce routeur repose sur le concept de routes personnalisées. Les routes
  118. sont ajoutées en appelant la méthode <code>addRoute()</code> et en lui passant une
  119. instance implémentant <classname>Zend_Controller_Router_Route_Interface</classname>.
  120. Exemple&#160;:
  121. </para>
  122. <programlisting language="php"><![CDATA[
  123. $router->addRoute('user',
  124. new Zend_Controller_Router_Route('user/:username'));
  125. ]]></programlisting>
  126. <para>
  127. Le routeur de réécriture est fourni avec six types de route, dont une
  128. spéciale&#160;:
  129. </para>
  130. <itemizedlist mark="opencircle">
  131. <listitem>
  132. <para><xref linkend="zend.controller.router.routes.standard" /></para>
  133. </listitem>
  134. <listitem>
  135. <para><xref linkend="zend.controller.router.routes.static" /></para>
  136. </listitem>
  137. <listitem>
  138. <para><xref linkend="zend.controller.router.routes.regex" /></para>
  139. </listitem>
  140. <listitem>
  141. <para><xref linkend="zend.controller.router.routes.hostname" /></para>
  142. </listitem>
  143. <listitem>
  144. <para><xref linkend="zend.controller.router.routes.chain" /></para>
  145. </listitem>
  146. <listitem>
  147. <para><xref linkend="zend.controller.router.default-routes"/> *</para>
  148. </listitem>
  149. </itemizedlist>
  150. <para>
  151. Chaque route peut être utilisée plusieurs fois pour créer un chaîne de routes
  152. représentant un schéma de routage personnalisé. La route du module, en revanche, ne
  153. devrait être utilisée qu'une seule fois, elle est en générale la route la plus
  154. générique (par défaut). Chaque route sera définie un peu plus tard.
  155. </para>
  156. <para>
  157. Le premier paramètre de <code>addRoute</code> est le nom de la route. Il sera
  158. utilisé plus tard pour la sélectionner (par exemple pour générer un URL. Le deuxième
  159. paramètre étant l'objet route lui-même.
  160. </para>
  161. <note>
  162. <para>
  163. L'utilisation la plus plausible du nom de la route est illustrée dans l'aide
  164. vue "url"&#160;:
  165. </para>
  166. <programlisting language="php"><![CDATA[
  167. <a href="<?= $this->url(array('username' => 'martel'), 'user') ?>">
  168. Martel
  169. </a>
  170. ]]></programlisting>
  171. <para>Ce qui donnera un "href"&#160;: <code>user/martel</code>.</para>
  172. </note>
  173. <para>
  174. Le routage consiste simplement à itérer toutes les routes reçues et à les faire
  175. correspondre à l'URI de la requête courante. Dès qu'une correspondance est établie, les
  176. variables sont injectées dans l'objet <classname>Zend_Controller_Request</classname>
  177. utilisé après dans le distributeur et dans les contrôleurs. Si aucune correspondance
  178. n'est trouvée, la route suivante dans la pile est analysée.
  179. </para>
  180. <para>
  181. Si vous devez déterminer quelle route a été trouvée, vous pouvez utilisez la
  182. méthode <code>getCurrentRouteName()</code>, qui vous retournera l'identifiant utilisé
  183. pour enregistrer la route dans le routeur. Si vous souhaitez récupérer l'objet de la
  184. route actuelle, vous pouvez utiliser <code>getCurrentRoute()</code>.
  185. </para>
  186. <note>
  187. <title>Pile LIFO</title>
  188. <para>
  189. Les routes sont analysées dans l'ordre LIFO : dernière fournie, première
  190. analysée. Veillez à définir les routes les génériques en premier donc.
  191. </para>
  192. </note>
  193. <note>
  194. <title>Paramètres de la requête</title>
  195. <para>
  196. Les paramètres de la requête proviennent de l'utilisateur, ou des routes
  197. définies. Ils seront plus tard accessibles via
  198. <classname>Zend_Controller_Request::getParam()</classname> ou la méthode
  199. <classname>Zend_Controller_Action::_getParam()</classname>.
  200. </para>
  201. </note>
  202. <para>
  203. Il y a trois valeurs spéciales qui peuvent être utilisées dans la définition de
  204. vos routes&#160;: - "module", "controller" et "action" -. Ces valeurs sont utilisées par
  205. <classname>Zend_Controller_Dispatcher</classname> pour trouver les contrôleurs et
  206. action à distribuer.
  207. </para>
  208. <note>
  209. <title>Valeurs spéciales</title>
  210. <para>
  211. Le nom de ces valeurs peut être changé dans
  212. <classname>Zend_Controller_Request_Http</classname> avec les méthodes
  213. <code>setControllerKey</code> et <code>setActionKey</code>.
  214. </para>
  215. </note>
  216. </sect2>
  217. <sect2 id="zend.controller.router.default-routes">
  218. <title>Routes par défaut</title>
  219. <para>
  220. Zend_Controller_Router_Rewrite possède des routes par défaut qui vont
  221. correspondre pour des URI du type <code>controller/action</code>. De plus, un nom de
  222. module peut être spécifié comme premier élément du chemin, autorisant ainsi des URI du
  223. type <code>module/controller/action</code>. Enfin, chaque paramètres de la requête sera
  224. trouvé à la fin de la requête, comme
  225. <code>controller/action/var1/value1/var2/value2</code>.
  226. </para>
  227. <para>Exemples avec ces routes&#160;:</para>
  228. <programlisting language="php"><![CDATA[
  229. // Considérons :
  230. $ctrl->setControllerDirectory(
  231. array(
  232. 'default' => '/path/to/default/controllers',
  233. 'news' => '/path/to/news/controllers',
  234. 'blog' => '/path/to/blog/controllers'
  235. )
  236. );
  237. Module seulement:
  238. http://example/news
  239. module == news
  240. Un module invalide dirige vers le contrôleur:
  241. http://example/foo
  242. controller == foo
  243. Module + controller:
  244. http://example/blog/archive
  245. module == blog
  246. controller == archive
  247. Module + controller + action:
  248. http://example/blog/archive/list
  249. module == blog
  250. controller == archive
  251. action == list
  252. Module + controller + action + params:
  253. http://example/blog/archive/list/sort/alpha/date/desc
  254. module == blog
  255. controller == archive
  256. action == list
  257. sort == alpha
  258. date == desc
  259. ]]></programlisting>
  260. <para>
  261. La route par défaut est simplement un objet
  262. <classname>Zend_Controller_Router_Route_Module</classname>, stocké sous le nom
  263. "default" dans le routeur de réécriture(RewriteRouter). Il est conçu comme ceci&#160;:
  264. </para>
  265. <programlisting language="php"><![CDATA[
  266. $compat = new Zend_Controller_Router_Route_Module(array(),
  267. $dispatcher,
  268. $request);
  269. $this->addRoute('default', $compat);
  270. ]]></programlisting>
  271. <para>
  272. Si vous ne souhaitez pas cette route par défaut, créez en une et stocker la avec
  273. le nom "default" (écrasement), ou supprimez la route avec
  274. <code>removeDefaultRoutes()</code>&#160;:
  275. </para>
  276. <programlisting language="php"><![CDATA[
  277. // Supprime les routes par défaut
  278. $router->removeDefaultRoutes();
  279. ]]></programlisting>
  280. </sect2>
  281. <sect2 id="zend.controller.router.rewritebase">
  282. <title>Base URL et sous dossiers</title>
  283. <para>
  284. Le routeur de réécriture peut être utilisé dans des sous dossiers (comme
  285. <code>http://domain.com/~user/application-root/</code>), dans un tél cas, l'URL de base
  286. de l'application (<code>/~user/application-root</code>) devrait être automatiquement
  287. détectée par <classname>Zend_Controller_Request_Http</classname> et utilisée
  288. ensuite.
  289. </para>
  290. <para>
  291. Si ça n'était pas le cas, vous pouvez spécifier votre propre base URL dans
  292. <classname>Zend_Controller_Request_Http</classname> en appelant
  293. <code>setBaseUrl()</code> (voyez
  294. <xref linkend="zend.controller.request.http.baseurl" />)&#160;:
  295. </para>
  296. <programlisting language="php"><![CDATA[
  297. $request->setBaseUrl('/~user/application-root/');
  298. ]]></programlisting>
  299. </sect2>
  300. <sect2 id="zend.controller.router.global.parameters">
  301. <title>Paramètres globaux</title>
  302. <para>
  303. Vous pouvez régler des paramètres globaux dans un routeur, qui sont
  304. automatiquement fournis à la route lors de son assemblage, grâce à la fonction
  305. <code>setGlobalParam()</code>. Si un paramètre global est réglé mais qu'il est aussi
  306. fourni directement à la méthode d'assemblage, le paramètre utilisateur écrase le
  307. paramètre global. Vous pouvez régler un paramètre global de cette manière&#160;:
  308. </para>
  309. <programlisting language="php"><![CDATA[
  310. $router->setGlobalParam('lang', 'en');
  311. ]]></programlisting>
  312. </sect2>
  313. <sect2 id="zend.controller.router.routes">
  314. <title>Types de route</title>
  315. <xi:include href="Zend_Controller-Router-Route.xml" />
  316. <xi:include href="Zend_Controller-Router-Route-Static.xml" />
  317. <xi:include href="Zend_Controller-Router-Route-Regex.xml" />
  318. <xi:include href="Zend_Controller-Router-Route-Hostname.xml" />
  319. <xi:include href="Zend_Controller-Router-Route-Chain.xml">
  320. <xi:fallback>
  321. <xi:include href="../../en/module_specs/Zend_Controller-Router-Route-Chain.xml" />
  322. </xi:fallback>
  323. </xi:include>
  324. </sect2>
  325. <sect2 id="zend.controller.router.add-config">
  326. <title>Utiliser Zend_Config avec le RewriteRouter</title>
  327. <para>
  328. Il arrive qu'il soit plus commode d'éditer un fichier de configuration de routes,
  329. plutôt que d'éditer un code source. Ceci est rendu possible par la méthode
  330. <code>addConfig()</code>. Vous créez un objet compatible Zend_Config et vous le passez
  331. à cette méthode.
  332. </para>
  333. <para>Par exemple, voyons un fichier INI :</para>
  334. <programlisting language="php"><![CDATA[
  335. [production]
  336. routes.archive.route = "archive/:year/*"
  337. routes.archive.defaults.controller = archive
  338. routes.archive.defaults.action = show
  339. routes.archive.defaults.year = 2000
  340. routes.archive.reqs.year = "\d+"
  341. routes.news.type = "Zend_Controller_Router_Route_Static"
  342. routes.news.route = "news"
  343. routes.news.defaults.controller = "news"
  344. routes.news.defaults.action = "list"
  345. routes.archive.type = "Zend_Controller_Router_Route_Regex"
  346. routes.archive.route = "archive/(\d+)"
  347. routes.archive.defaults.controller = "archive"
  348. routes.archive.defaults.action = "show"
  349. routes.archive.map.1 = "year"
  350. ; OU: routes.archive.map.year = 1
  351. ]]></programlisting>
  352. <para>
  353. Ce fichier INI peut être lu dans grâce à un objet <classname>Zend_Config</classname>
  354. comme suit&#160;:
  355. </para>
  356. <programlisting language="php"><![CDATA[
  357. $config = new Zend_Config_Ini('/path/to/config.ini', 'production');
  358. $router = new Zend_Controller_Router_Rewrite();
  359. $router->addConfig($config, 'routes');
  360. ]]></programlisting>
  361. <para>
  362. Nous indiquons au routeur d'utiliser la section "routes" du fichier INI. Chaque
  363. clé de premier niveau représente le nom de la route, ainsi nous avons dans l'exemple ci
  364. dessus "archive" et "news". Chaque route attend alors au moins une entrée "route" avec
  365. une ou plusieurs entrées "defaults"&#160;; optionnellement nous pouvons rajouter des
  366. paramètres obligatoires. Tout ceci correspond aux trois arguments fournis par l'objet
  367. implémentant <classname>Zend_Controller_Router_Route_Interface</classname>. Une entrée
  368. optionnelle "type" peut être utilisée pour indiquer le type de classe de routage à
  369. utiliser, il s'agit par défaut de <classname>Zend_Controller_Router_Route</classname>.
  370. Dans l'exemple au dessus, la route "news" va utiliser
  371. <classname>Zend_Controller_Router_Route_Static</classname>.
  372. </para>
  373. </sect2>
  374. <sect2 id="zend.controller.router.subclassing">
  375. <title>Dérivation de l'objet Router</title>
  376. <para>
  377. Le routeur par défaut, dit de réécriture, devrait suffire dans la majorité des
  378. projets. Tout ce qu'il peut être nécessaire de faire, est d'ajouter des routes
  379. particulières selon vos besoins.
  380. </para>
  381. <para>
  382. Cependant, si vous voulez utiliser votre propre logique de routage, une interface
  383. est disponible. <classname>Zend_Controller_Router_Interface</classname> ne définit
  384. qu'une seule méthode&#160;:
  385. </para>
  386. <programlisting language="php"><![CDATA[
  387. interface Zend_Controller_Router_Interface
  388. {
  389. /**
  390. * @param Zend_Controller_Request_Abstract $request
  391. * @throws Zend_Controller_Router_Exception
  392. * @return Zend_Controller_Request_Abstract
  393. */
  394. public function route(Zend_Controller_Request_Abstract $request);
  395. }
  396. ]]></programlisting>
  397. <para>
  398. Le processus de routage n'intervient qu'une fois : lorsque la requête est reçue
  399. par le système. Le routeur doit alors déterminer un contrôleur, une action et de
  400. paramètres optionnel et les spécifier dans un objet de requête, qui est ensuite passé
  401. au distributeur. Si il n'est pas possible de router une requête, alors l'objet de
  402. requête devrait être laissé tel-quel.
  403. </para>
  404. </sect2>
  405. </sect1>