Le Routing est une fonctionnalité qui fait correspondre les URLs aux actions du
controller. En définissant des routes, vous pouvez séparer la façon dont votre
application est intégrée de la façon dont ses URLs sont structurées.
Le Routing dans CakePHP englobe aussi l’idée de routing inversé, où un tableau
de paramètres peut être transformé en une URL. En utilisant le routing inversé,
vous pouvez reconstruire la structure d’URL de votre application sans mettre à
jour tous vos codes.
Tour Rapide
Cette section va vous apprendre les utilisations les plus habituelles du Router
de CakePHP. Typiquement si vous voulez afficher quelque chose en page d’accueil,
vous ajoutez ceci au fichier config/routes.php:
/** @var \Cake\Routing\RouteBuilder $routes */
$routes->connect('/', ['controller' => 'Articles', 'action' => 'index']);
Ceci va exécuter la méthode index
dans ArticlesController
quand la page
d’accueil de votre site est visitée. Parfois vous avez besoin de routes
dynamiques qui vont accepter plusieurs paramètres, ce sera par exemple le cas
d’une route pour voir le contenu d’un article:
$routes->connect('/articles/*', ['controller' => 'Articles', 'action' => 'view']);
La route ci-dessus accepte toute URL qui ressemble à /articles/15
et appelle
la méthode view(15)
dans ArticlesController
. En revanche, ceci ne va pas
empêcher les visiteurs d’accéder à une URLs ressemblant à
/articles/foobar
. Si vous le souhaitez, vous pouvez restreindre certains
paramètres grâce à une expression régulière:
// En utilisant l'interface fluide
$routes->connect(
'/articles/{id}',
['controller' => 'Articles', 'action' => 'view'],
)
->setPatterns(['id' => '\d+'])
->setPass(['id']);
// En passant un tableau d'options
$routes->connect(
'/articles/{id}',
['controller' => 'Articles', 'action' => 'view'],
['id' => '\d+', 'pass' => ['id']]
);
Dans l’exemple précédent, le caractère jocker *
est remplacé par un
placeholder {id}
. Utiliser les placeholders nous permet de valider les
parties de l’URL, dans ce cas, nous utilisons l’expression régulière \d+
pour que seuls les chiffres fonctionnent. Finalement, nous disons au Router de
traiter le placeholder id
comme un argument de fonction pour la fonction
view()
en spécifiant l’option pass
. Vous pourrez en voir plus sur leur
utilisation plus tard.
Le Router de CakePHP peut aussi faire correspondre les routes en reverse. Cela
signifie qu’à partir d’un tableau contenant des paramètres similaires, il est
capable de générer une chaîne URL:
use Cake\Routing\Router;
echo Router::url(['controller' => 'Articles', 'action' => 'view', 'id' => 15]);
// Va afficher
/articles/15
Les routes peuvent aussi être labellisées avec un nom unique, cela vous permet
de rapidement leur faire référence lors de la construction des liens plutôt
que de spécifier chacun des paramètres de routing:
// Dans le fichier routes.php
$routes->connect(
'/upgrade',
['controller' => 'Subscriptions', 'action' => 'create'],
['_name' => 'upgrade']
);
use Cake\Routing\Router;
echo Router::url(['_name' => 'upgrade']);
// Va afficher
/upgrade
Pour aider à garder votre code de router « DRY », le router apporte le concept
de “scopes”. Un scope (une étendue) défini un segment de chemin commun, et
optionnellement des routes par défaut. Toute route connectée à l’intérieur d’un
scope héritera du chemin et des routes par défaut du scope qui la contient:
$routes->scope('/blog', ['plugin' => 'Blog'], function (RouteBuilder $routes) {
$routes->connect('/', ['controller' => 'Articles']);
});
Le route ci-dessus matchera /blog/
et renverra
Blog\Controller\ArticlesController::index()
.
Le squelette d’application contient quelques routes pour vous aider à commencer.
Une fois que vous avez ajouté vos propres routes, vous pouvez retirer les routes
par défaut si vous n’en avez pas besoin.
Connecter les Routes
Pour garder votre code DRY, vous pouvez utiliser les “routing scopes”.
Les scopes de Routing permettent non seulement de garder votre code DRY mais
aident aussi le Router à optimiser son travail. Comme vous l’avez vu
précédemment. Cette méthode va par défaut vers le scope /
. Pour créer un
scope et connecter certaines routes, nous allons utiliser la méthode
scope()
:
// Dans config/routes.php
use Cake\Routing\RouteBuilder;
use Cake\Routing\Route\DashedRoute;
$routes->scope('/', function (RouteBuilder $routes) {
// Connect the generic fallback routes.
$routes->fallbacks(DashedRoute::class);
});
La méthode connect()
prend jusqu’à trois paramètres: l’URL que vous souhaitez
faire correspondre, les valeurs par défaut pour les éléments de votre route, et les
options de route. Ces options inlcuent fréquemment des règles d’expressions régulières
pour aider le router à faire correspondre les éléments dans l’URL.
Le format basique pour une définition de route est:
$routes->connect(
'/url/template',
['targetKey' => 'targetValue'],
['option' => 'matchingRegex']
);
Le premier paramètre est utilisé pour dire au router quelle sorte d’URL vous
essayez de contrôler. L’URL est une chaîne normale délimitée par des slashes,
mais peut aussi contenir une wildcard (*) ou Les Eléments de Route. Utiliser
une wildcard dit au router que vous êtes prêt à accepter tout argument
supplémentaire fourni. Les Routes sans un * ne matchent que le modèle exact
de pattern fourni.
Une fois que vous avez spécifié une URL, vous utilisez les deux derniers paramètres
de connect()
pour dire à CakePHP que faire avec la requête une fois
qu’elle a été matchée. La deuxième paramètre définit la route “cible”.
Il peut être défini soit comme un tableau, soit comme chaîne de destination.
Quelques exemples de routes cibles sont:
// Cible sous forme de tableau vers un contrôleur de l'application
$routes->connect(
'/users/view/*',
['controller' => 'Users', 'action' => 'view']
);
$routes->connect('/users/view/*', 'Users::view');
// Cible sous forme de tableau vers un contrôleur préfixé de plugin
$routes->connect(
'/admin/cms/articles',
['prefix' => 'Admin', 'plugin' => 'Cms', 'controller' => 'Articles', 'action' => 'index']
);
$routes->connect('/admin/cms/articles', 'Cms.Admin/Articles::index');
La première route que nous connectons correspond aux URL commençant par /users/view
et fait correspondre ces requêtes à UsersController->view()
. Le dernier /*
indique au
routeur pour passer tous les segments supplémentaires comme arguments de méthode. Par exemple,
/users/view/123
serait mappé à UsersController->view(123)
.
L’exemple ci-dessus illustre également les chaînes cibles. Les chaînes cibles fournissent
une manière compacte de définir la destination d’une route. Les chaînes cibles ont la
syntaxe suivante:
[Plugin].[Prefix]/[Controller]::[action]
Quelques exemples de chaînes cibles sont:
// Contrôleur d'application
'Bookmarks::view'
// Contrôleur d'application possédant un préfix
Admin/Bookmarks::view
// Contrôleur de plugin
Cms.Articles::edit
// Contrôleur de plugin possédant un préfix
Vendor/Cms.Management/Admin/Articles::view
Auparavant, nous avons utilisé l’étoile greedy (/*
) pour capturer des segments de
chemin supplémentaires, il y aussi la syntaxe de l’étoile trailing (/**
).
Utiliser une étoile double trailing, va capturer le reste de l’URL en
tant qu’argument unique passé. Ceci est utile quand vous voulez utilisez un
argument qui incluait un /
dedans:
$routes->connect(
'/pages/**',
['controller' => 'Pages', 'action' => 'show']
);
L’URL entrante de /pages/the-example-/-and-proof
résulterait en un argument
unique passé the-example-/-and-proof
.
Vous pouvez utiliser le deuxième paramètre de connect()
pour fournir tout
les paramètres de routing qui formeront alors des valeurs par défaut de la route:
$routes->connect(
'/government',
['controller' => 'Pages', 'action' => 'display', 5]
);
Cet exemple montre comment vous pouvez utiliser le deuxième paramètre de
connect()
pour définir les paramètres par défaut. Si vous construisez un
site qui propose des produits pour différentes catégories de clients, vous
pourriez considérer la création d’une route. Cela vous permet de vous lier à
/government
plutôt qu’à /pages/display/5
.
Une utilisation classique du routing consiste à créer des segments d’URL
qui ne correspondent pas aux noms de vos contrôleurs ou de vos modèles.
Imaginons qu’au lieu de vouloir accéder à une URL /users/some_action/5
,
vous souhaitiez y accéder via /cooks/une_action/5
. Pour ce faire,
vous devriez configurer la route suivante:
$routes->connect(
'/cooks/{action}/*', ['controller' => 'Users']
);
Cela dit au Router que toute URL commençant par /cooks/
devrait être envoyée
au UsersController
. L’action appelée dépendra de la valeur du paramètre
{action}
. En utilisant Les Eléments de Route, vous pouvez créer des routes
variables, qui acceptent des entrées utilisateur ou des variables. La route
ci-dessus utilise aussi l’étoile greedy. L’étoile greedy indique au
Router
que cette route devrait accepter tout argument de position
supplémentaire donné. Ces arguments seront rendus disponibles dans le tableau
Arguments Passés.
Quand on génère les URLs, les routes sont aussi utilisées. Utiliser
['controller' => 'Users', 'action' => 'some_action', 5]
en URL va sortir
/cooks/some_action/5
si la route ci-dessus est la première correspondante
trouvée.
Les routes connectées jusque là fonctionneront avec n’importe quel verbe HTTP.
Si vous souhaitez construire une API REST, vous aurez probablement besoin de faire
correspondre des actions HTTP à des méthodes de controller différentes.
Le RouteBuilder
met à disposition des méthodes qui rendent plus facile la
définition de routes pour des verbes HTTP spécifiques:
// Crée une route qui ne répondra qu'aux requêtes GET.
$routes->get(
'/cooks/{id}',
['controller' => 'Users', 'action' => 'view'],
'users:view'
);
// Crée une route qui ne répondra qu'aux requêtes PUT
$routes->put(
'/cooks/{id}',
['controller' => 'Users', 'action' => 'update'],
'users:update'
);
Les méthodes ci-dessus mappent la même URL à des actions différentes en fonction
du verbe HTTP utilisé. Les requêtes GET pointeront sur l’action “view” tandis que les
requêtes PUT pointeront sur l’action “update”. Les méthodes suivantes sont disponibles
pour les verbes:
GET
POST
PUT
PATCH
DELETE
OPTIONS
HEAD
Toutes ces méthodes retournent une instance de Route ce qui vous permet d’utiliser les
setters fluides pour configurer plus précisément vos
routes.
Les Eléments de Route
Vous pouvez spécifier vos propres éléments de route et ce faisant
cela vous donne le pouvoir de définir des emplacements dans l’URL où les
paramètres pour les actions du controller doivent se trouver. Quand
une requête est faite, les valeurs pour ces éléments de route se
trouvent dans $this->request->getParam()
dans le controller. Quand vous
définissez un élément de route personnalisé, vous pouvez spécifier en option
une expression régulière - ceci dit à CakePHP comment savoir si l’URL est
correctement formée ou non. Si vous choisissez de ne pas fournir une expression
régulière, tout caractère autre que /
sera traité comme une partie du
paramètre:
$routes->connect(
'/{controller}/{id}',
['action' => 'view']
)->setPatterns(['id' => '[0-9]+']);
$routes->connect(
'/{controller}/{id}',
['action' => 'view'],
['id' => '[0-9]+']
);
Cet exemple simple montre comment créer une manière rapide de voir les modèles
à partir de tout contrôleur en élaborant une URL qui ressemble à
/controllername/{id}
. L’URL fournie à connect()
spécifie deux éléments de
route: {controller}
et {id}
. L’élément {controller}
est l’élément de
route par défaut de CakePHP, donc le router sait comment matcher et identifier
les noms de contrôleurs dans les URLs. L’élément {id}
est un élément de route
personnalisé, et doit être clarifié plus loin en spécifiant une expression
régulière correspondante dans le troisième paramètre de connect()
.
CakePHP ne produit pas automatiquement d’urls en minuscule avec des tirets quand
vous utilisez le paramètre {controller}
. Si vous avez besoin de ceci,
l’exemple ci-dessus peut être réécrit en:
use Cake\Routing\Route\DashedRoute;
// Crée un builder avec une classe de Route différente.
$routes->scope('/', function (RouteBuilder $routes) {
$routes->setRouteClass(DashedRoute::class);
$routes->connect('/{controller}/{id}', ['action' => 'view'])
->setPatterns(['id' => '[0-9]+']);
$routes->connect(
'/{controller}/{id}',
['action' => 'view'],
['id' => '[0-9]+']
);
});
La classe spéciale DashedRoute
va s’assurer que les paramètres
{controller}
et {plugin}
sont correctement mis en minuscule et avec des
tirets.
Note
Les Patrons utilisés pour les éléments de route ne doivent pas contenir
de groupes capturés. S’ils le font, le Router ne va pas fonctionner
correctement.
Une fois que cette route a été définie, la requête /apples/5
est la même
que celle requêtant /apples/view/5
. Les deux appelleraient la méthode view()
de ApplesController. A l’intérieur de la méthode view()
, vous aurez besoin
d’accéder à l’ID passé à $this->request->getParam('id')
.
Si vous avez un unique controller dans votre application et que vous ne
voulez pas que le nom du controller apparaisse dans l’URL, vous pouvez mapper
toutes les URLs aux actions dans votre controller. Par exemple, pour mapper
toutes les URLs aux actions du controller home
, par ex avoir des URLs
comme /demo
à la place de /home/demo
, vous pouvez faire ce qui suit:
$routes->connect('/{action}', ['controller' => 'Home']);
Si vous souhaitez fournir une URL non sensible à la casse, vous pouvez utiliser
les modificateurs en ligne d’expression régulière:
$routes->connect(
'/{userShortcut}',
['controller' => 'Teachers', 'action' => 'profile', 1],
)->setPatterns(['userShortcut' => '(?i:principal)']);
Un exemple de plus, et vous serez un pro du routing:
$routes->connect(
'/{controller}/{year}/{month}/{day}',
['action' => 'index']
)->setPatterns([
'year' => '[12][0-9]{3}',
'month' => '0[1-9]|1[012]',
'day' => '0[1-9]|[12][0-9]|3[01]'
]);
C’est assez complexe, mais montre comme les routes peuvent vraiment
devenir puissantes. L’URL fournie a quatre éléments de route. Le premier
nous est familier: c’est une route par défaut qui dit à CakePHP d’attendre
un nom de controller.
Ensuite, nous spécifions quelques valeurs par défaut. Quel que soit le
controller, nous voulons que l’action index()
soit appelée.
Finalement, nous spécifions quelques expressions régulières qui vont
matcher les années, mois et jours sous forme numérique. Notez que les
parenthèses (le groupe de capture) ne sont pas supportées dans les expressions
régulières. Vous pouvez toujours spécifier des alternatives, comme
dessus, mais vous ne pouvez pas les grouper avec les parenthèses.
Une fois définie, cette route va matcher /articles/2007/02/01
,
/articles/2004/11/16
, gérant les requêtes
pour les actions index()
de leurs controllers respectifs, avec les paramètres de
date dans $this->request->getParam()
.
Eléments de Routes réservés
Il y a plusieurs éléments de route qui ont une signification spéciale dans
CakePHP, et ne devraient pas être utilisés à moins que vous ne souhaitiez
spécifiquement utiliser leur signification.
controller
Utilisé pour nommer le controller pour une route.
action
Utilisé pour nommer l’action de controller pour une route.
plugin
Utilisé pour nommer le plugin dans lequel un controller est
localisé.
prefix
Utilisé pour Prefix de Routage.
_ext
Utilisé pour Routage des extensions de fichiers.
_base
Défini à false
pour retirer le chemin de base de l’URL générée.
Si votre application n’est pas dans le répertoire racine, cette option peut
être utilisée pour générer les URLs qui sont “liées à cake”.
_scheme
Défini pour créer les liens sur les schémas différents comme
webcal ou ftp. Par défaut, au schéma courant.
_host
Définit l’hôte à utiliser pour le lien. Par défaut à l’hôte courant.
_port
Définit le port si vous avez besoin de créer les liens sur des ports
non-standards.
_full
Si à true
, la valeur de App.fullBaseUrl
vue dans
Configuration Générale sera ajoutée devant les URL générées.
#
Vous permet de définir les fragments de hash d’URL.
_https
Défini à true
pour convertir l’URL générée à https, ou false
pour forcer http.
_method
Definit la méthode HTTP à utiliser. Utile si vous travaillez avec
Créer des Routes RESTful.
_name
Nom de route. Si vous avez configuré les routes nommées, vous
pouvez utiliser cette clé pour les spécifier.
Passer des Paramètres à l’Action
Quand vous connectez les routes en utilisant
Les Eléments de Route vous voudrez peut-être que des éléments routés
soient passés comme arguments à la place. L’option pass
défini une liste
des éléments de route qui doivent également être rendu disponibles en tant qu’arguments
passés aux fonctions du contrôleur:
// src/Controller/BlogsController.php
public function view($articleId = null, $slug = null)
{
// du code ici...
}
// routes.php
Router::scope('/', function ($routes) {
$routes->connect(
'/blog/{id}-{slug}', // E.g. /blog/3-CakePHP_Rocks
['controller' => 'Blogs', 'action' => 'view']
)
// Défini les éléments de route dans le template de route
// à passer en tant qu'arguments à la fonction. L'ordre est
// important car cela fera simplement correspondre `$id` and `$slug`
// avec le premier et le second paramètre (respectivement).
->setPass(['id', 'slug'])
// Defini un pattern que `id` doit avoir.
->setPatterns([
'id' => '[0-9]+',
]);
});
Maintenant, grâce aux possibilités de routing inversé, vous pouvez passer
dans le tableau d’URL comme ci-dessous et CakePHP sait comment former l’URL
comme définie dans les routes:
// view.php
// ceci va retourner un lien vers /blog/3-CakePHP_Rocks
echo $this->Html->link('CakePHP Rocks', [
'controller' => 'Blog',
'action' => 'view',
'id' => 3,
'slug' => 'CakePHP_Rocks'
]);
// Vous pouvez aussi utiliser des paramètres indexés numériquement.
echo $this->Html->link('CakePHP Rocks', [
'controller' => 'Blog',
'action' => 'view',
3,
'CakePHP_Rocks'
]);
Utilisation du Routage de Chemin
Nous avons parlé des cibles de chaîne ci-dessus. La même chose
fonctionne également pour la génération d’URL en utilisant Router::pathUrl()
:
echo Router::pathUrl('Articles::index');
// donnera par exemple: /articles
echo Router::pathUrl('MyBackend.Admin/Articles::view', [3]);
// donnera par exemple: /admin/my-backend/articles/view/3
Astuce
Le support IDE pour la saisie semi-automatique du routage de chemin peut être activé avec
CakePHP IdeHelper Plugin.
Utiliser les Routes Nommées
Parfois vous trouvez que taper tous les paramètres de l’URL pour une route est
trop verbeux, ou bien vous souhaitez tirer avantage des améliorations de la
performance que les routes nommées permettent. Lorsque vous connectez les
routes, vous pouvez spécifier une option _name
, cette option peut être
utilisée par le routing inversé pour identifier la route que vous souhaitez
utiliser:
// Connecter une route avec un nom.
$routes->connect(
'/login',
['controller' => 'Users', 'action' => 'login'],
['_name' => 'login']
);
// Nommage d'une route liée à un verbe spécifique
$routes->post(
'/logout',
['controller' => 'Users', 'action' => 'logout'],
'logout'
);
// Génère une URL en utilisant une route nommée.
$url = Router::url(['_name' => 'logout']);
// Génère une URL en utilisant une route nommée,
// avec certains args query string
$url = Router::url(['_name' => 'login', 'username' => 'jimmy']);
Si votre template de route contient des éléments de route comme {controller}
,
vous aurez besoin de fournir ceux-ci comme options de Router::url()
.
Note
Les noms de Route doivent être uniques pour l’ensemble de votre application.
Le même _name
ne peut être utilisé deux fois, même si les noms
apparaissent dans un scope de routing différent.
Quand vous construisez vos noms de routes, vous voudrez probablement coller
à certaines conventions pour les noms de route. CakePHP facilite la construction
des noms de route en vous permettant de définir des préfixes de nom dans chaque
scope:
$routes->scope('/api', ['_namePrefix' => 'api:'], function (RouteBuilder $routes) {
// le nom de cette route sera `api:ping`
$routes->get('/ping', ['controller' => 'Pings'], 'ping');
});
// Génère une URL correspondant à la route 'ping'
Router::url(['_name' => 'api:ping']);
// Utilisation du namePrefix avec plugin()
$routes->plugin('Contacts', ['_namePrefix' => 'contacts:'], function (RouteBuilder $routes) {
// Connecte les routes.
});
// Ou avec prefix()
$routes->prefix('Admin', ['_namePrefix' => 'admin:'], function (RouteBuilder $routes) {
// Connecte les routes.
});
Vous pouvez aussi utiliser l’option _namePrefix
dans les scopes imbriqués et
elle fonctionne comme vous pouvez vous y attendre:
$routes->plugin('Contacts', ['_namePrefix' => 'contacts:'], function (RouteBuilder $routes) {
$routes->scope('/api', ['_namePrefix' => 'api:'], function (RouteBuilder $routes) {
// Le nom de cette route sera `contacts:api:ping`
$routes->get('/ping', ['controller' => 'Pings'], 'ping');
});
});
// Génère une URL correspondant à la route 'ping'
Router::url(['_name' => 'contacts:api:ping']);
Les routes connectées dans les scopes nommés auront seulement des noms ajoutés
si la route est aussi nommée. Les routes sans nom ne se verront pas appliquées
_namePrefix
.
Prefix de Routage
-
static Cake\Routing\RouterBuilder::prefix($name, $callback)
De nombreuses applications nécessitent une section d’administration dans
laquelle les utilisateurs privilégiés peuvent faire des modifications.
Ceci est souvent réalisé grâce à une URL spéciale telle que
/admin/users/edit/5
. Dans CakePHP, les préfixes de routage peuvent être
activés en utilisant la méthode de portée (scope) prefix
:
use Cake\Routing\Route\DashedRoute;
$routes->prefix('Admin', function (RouteBuilder $routes) {
// Toutes les routes ici seront préfixées avec `/admin`, et
// l'élément de route `'prefix' => 'Admin'` sera ajouté qui
// sera requis lors de la génération d'URL pour ces routes
$routes->fallbacks(DashedRoute::class);
});
Les préfixes sont mappés aux sous-espaces de noms dans l’espace de nom
Controller
de votre application. En ayant des préfixes en tant que
controller séparés, vous pouvez créer des contrôleurs plus petits et/ou
plus simples. Les comportements communs aux controllers préfixés et non-préfixés
peuvent être encapsulés via l’héritage, les Components (Composants), ou
les traits. En utilisant notre exemple des utilisateurs, accéder à l’url
/admin/users/edit/5
devrait appeler la méthode edit()
de notre
App\Controller\Admin\UsersController
en passant 5 comme premier paramètre.
Le fichier de vue utilisé serait templates/Admin/Users/edit.php.
Vous pouvez faire correspondre l’URL /admin à votre action index()
du controller Pages en utilisant la route suivante:
$routes->prefix('Admin', function (RouteBuilder $routes) {
// Parce que vous êtes dans le scope admin, vous n'avez pas besoin
// d'inclure le prefix /admin ou l'élément de route admin.
$routes->connect('/', ['controller' => 'Pages', 'action' => 'index']);
});
Quand vous créez des routes préfixées, vous pouvez définir des paramètres de
route supplémentaires en utilisant l’argument $options
:
$routes->prefix('Admin', ['param' => 'value'], function (RouteBuilder $routes) {
// Routes connectées ici sont préfixées par '/admin' et
// ont la clé 'param' de routing définie.
$routes->connect('/{controller}');
});
Les préfixes de plusieurs mots sont par défaut convertis en utilisant l’inflexion
en tirets (dasherize), c’est-à-dire que MyPrefix
serait mappé sur
my-prefix
dans l’URL. Assurez-vous de définir un chemin d’accès pour ces
préfixes si vous souhaitez utiliser un format différent comme par exemple le
soulignement:
$routes->prefix('MyPrefix', ['path' => '/my_prefix'], function (RouteBuilder $routes) {
// Les routes connectées ici sont préfixées par '/my_prefix'
$routes->connect('/{controller}');
});
Vous pouvez aussi définir les préfixes dans les scopes de plugin:
$routes->plugin('DebugKit', function (RouteBuilder $routes) {
$routes->prefix('Admin', function (RouteBuilder $routes) {
$routes->connect('/{controller}');
});
});
Ce qui est au-dessus va créer un template de route de type
/debug-kit/admin/{controller}
. La route connectée aura les éléments de
route plugin
et prefix
définis.
Quand vous définissez des préfixes, vous pouvez imbriquer plusieurs préfixes
si besoin:
$routes->prefix('Manager', function (RouteBuilder $routes) {
$routes->prefix('Admin', function (RouteBuilder $routes) {
$routes->connect('/{controller}/{action}');
});
});
Ce qui est au-dessus va créer un template de route de type
/manager/admin/{controller}/{action}
. La route connectée aura l’élément de
route prefix
défini à Manager/Admin
.
Le préfixe actuel sera disponible à partir des méthodes du controller avec
$this->request->getParam('prefix')
Quand vous utilisez les routes préfixées, il est important de définir l’option
prefix
, et d’utiliser le même format CamelCased que celui utilisé
dans la méthode prefix()
. Voici comment construire ce lien en utilisant le
helper HTML:
// Aller vers une route préfixée.
echo $this->Html->link(
'Manage articles',
['prefix' => 'Manager/Admin', 'controller' => 'Articles', 'action' => 'add']
);
// Enlever un prefix
echo $this->Html->link(
'View Post',
['prefix' => false, 'controller' => 'Articles', 'action' => 'view', 5]
);
Note
Vous devez connecter les routes préfixées avant de connecter les routes
fallback.
Création de liens vers des routes de préfixe
Vous pouvez créer des liens qui pointent vers un préfixe, en ajoutant la clé
de préfixe à votre tableau d’URL:
echo $this->Html->link(
'New admin todo',
['prefix' => 'Admin', 'controller' => 'TodoItems', 'action' => 'create']
);
Lorsque vous utilisez l’imbrication, vous devez les chaîner ensemble:
echo $this->Html->link(
'New todo',
['prefix' => 'Admin/MyPrefix', 'controller' => 'TodoItems', 'action' => 'create']
);
Cela serait lié à un contrôleur avec l’espace de noms App\\Controller\\Admin\\MyPrefix
et le chemin de fichier src/Controller/Admin/MyPrefix/TodoItemsController.php
.
Note
Le préfixe est CamelCased ici, même si le résultat du routage est en
pointillés. La route elle-même fera l’inflexion si nécessaire.
Routing des Plugins
-
static Cake\Routing\RouterBuilder::plugin($name, $options = [], $callback)
Les routes des Plugins doivent être créées en utilisant la méthode
plugin()
. Cette méthode crée un nouveau scope pour les routes de plugin:
$routes->plugin('DebugKit', function (RouteBuilder $routes) {
// Les routes connectées ici sont préfixées par '/debug_kit' et ont
// l'élément de route plugin défini à 'DebugKit'.
$routes->connect('/{controller}');
});
Lors de la création des scopes de plugin, vous pouvez personnaliser le chemin de
l’élément avec l’option path
:
$routes->plugin('DebugKit', ['path' => '/debugger'], function (RouteBuilder $routes) {
// Les routes connectées ici sont préfixées par '/debugger' et ont
// l'élément de route plugin défini à 'DebugKit'.
$routes->connect('/{controller}');
});
Lors de l’utilisation des scopes, vous pouvez imbriquer un scope de plugin dans
un scope de prefix:
$routes->prefix('Admin', function (RouteBuilder $routes) {
$routes->plugin('DebugKit', function (RouteBuilder $routes) {
$routes->connect('/{controller}');
});
});
Le code ci-dessus va créer une route similaire à
/admin/debug-kit/{controller}
. Elle aura les éléments de route
prefix
et plugin
définis. Référez-vous à la section Routes de Plugins
pour avoir plus d’informations sur comment construire des routes de plugin.
Créer des Liens vers des Routes de Plugins
Vous pouvez créer des liens qui pointent vers un plugin, en ajoutant la clé
plugin
au tableau de l’URL:
echo $this->Html->link(
'New todo',
['plugin' => 'Todo', 'controller' => 'TodoItems', 'action' => 'create']
);
Inversement, si la requête active est une requête de plugin et que vous
souhaitez créer un lien qui n’a pas de plugin, vous pouvez faire ceci:
echo $this->Html->link(
'New todo',
['plugin' => null, 'controller' => 'Users', 'action' => 'profile']
);
En définissant 'plugin' => null
, vous dites au Router que vous souhaitez
créer un lien qui n’appartient pas à un plugin.
Routing Favorisant le SEO
Certains développeurs préfèrent utiliser des tirets dans les URLs, car cela
semble donner un meilleur classement dans les moteurs de recherche.
La classe DashedRoute
fournit à votre application la possibilité de créer
des URLs avec des tirets pour vos plugins, contrôleurs, et les noms d’action en
camelCase
.
Par exemple, si nous avons un plugin ToDo
avec un controller TodoItems
et une action showItems()
, la route générée sera
/to-do/todo-items/show-items
avec le code qui suit:
use Cake\Routing\Route\DashedRoute;
$routes->plugin('ToDo', ['path' => 'to-do'], function (RouteBuilder $routes) {
$routes->fallbacks(DashedRoute::class);
});
Matching des Méthodes HTTP Spécifiques
Les routes peuvent « matcher » des méthodes HTTP spécifiques en utilisant
les méthodes spécifiques:
$routes->scope('/', function (RouteBuilder $routes) {
// Cette route matchera seulement les requêtes POST.
$routes->post(
'/reviews/start',
['controller' => 'Reviews', 'action' => 'start']
);
// Matcher plusieurs verbes
$routes->connect(
'/reviews/start',
[
'controller' => 'Reviews',
'action' => 'start',
]
)->setMethods(['POST', 'PUT']);
});
Vous pouvez « matcher » plusieurs méthodes HTTP en fournissant un tableau.
Puisque que l’option _method
est une clé de routage, elle est utilisée à la
fois dans le parsing des URL et la génération des URL. Pour générer des URL pour
des routes spécifiques, vous devez utiliser la clé _method
lors de la génération:
$url = Router::url([
'controller' => 'Reviews',
'action' => 'start',
'_method' => 'POST',
]);
Matching de Noms de Domaine Spécifiques
Les routes peuvent utiliser l’option _host
pour « matcher » des noms de
domaines spécifiques. Vous pouvez utiliser la wildcard *.
pour « matcher »
n’importe quelle sous-domaine:
$routes->scope('/', function (RouteBuilder $routes) {
// Cette route ne va "matcher" que sur le domaine http://images.example.com
$routes->connect(
'/images/default-logo.png',
['controller' => 'Images', 'action' => 'default']
)->setHost('images.example.com');
// Cette route matchera sur tous les sous-domaines http://*.example.com
$routes->connect(
'/images/old-log.png',
['controller' => 'Images', 'action' => 'oldLogo']
)->setHost('*.example.com');
});
L’option _host
est également utilisée dans la génération d’URL. Si votre option _host
spécifie un domaine exact, ce domaine sera inclus dans l’URL générée.
Cependant, si vous utilisez un caractère générique, vous devrez fournir le _host
paramètre lors de la génération d’URL:
// Si vous avez cette route
$routes->connect(
'/images/old-log.png',
['controller' => 'Images', 'action' => 'oldLogo']
)->setHost('images.example.com');
// Vous aurez besoin de ceci pour générer l'URL correspondante
echo Router::url([
'controller' => 'Images',
'action' => 'oldLogo',
'_host' => 'images.example.com',
]);
Routing des Extensions de Fichier
-
static Cake\Routing\RouterBuilder::extensions(string|array|null $extensions, $merge = true)
Pour manipuler différentes extensions de fichier avec vos routes, vous pouvez
définir vos extensions en utilisant la méthode
Cake\Routing\RouteBuilder::setExtensions()
:
$routes->scope('/', function (RouteBuilder $routes) {
$routes->setExtensions(['json', 'xml']);
});
Ceci affectera toutes les routes qui seront connectées après cet appel,
à setExtensions()
en incluant celles qui ont été connectées dans des scopes imbriqués.
Pour restreindre les extensions à un scope spécifique, vous pouvez les définir
en utilisant la méthode Cake\Routing\RouteBuilder::extensions()
.
Note
Le réglage des extensions devrait être la première chose que vous devriez
faire dans un scope, car les extensions seront appliquées uniquement aux
routes qui sont définies après la déclaration des extensions.
Lorsque vous définissez des routes dans le même scope mais dans deux appels
différents, les extensions ne seront pas héritées d’un appel à l’autre.
En utilisant des extensions, vous dites au router de supprimer toutes les
extensions de fichiers correspondant, puis d’analyser le reste. Si vous
souhaitez créer une URL comme /page/title-of-page.html
vous devriez créer
un scope comme ceci:
$routes->scope('/page', function (RouteBuilder $routes) {
$routes->setExtensions(['json', 'xml', 'html']);
$routes->connect(
'/{title}',
['controller' => 'Pages', 'action' => 'view']
)->setPass(['title']);
});
Ensuite, pour créer des liens, utilisez simplement:
$this->Html->link(
'Link title',
['controller' => 'Pages', 'action' => 'view', 'title' => 'super-article', '_ext' => 'html']
);
Les extensions de fichier sont utilisées par le
Request Handling (Gestion des requêtes) qui fait la commutation des
vues automatiquement en se basant sur les types de contenu.
Middleware appliqué à une Route
Bien que les middlewares puissent être appliqués à toute votre application, appliquer
les middlewares à des “scopes” de routing offre plus de flexibilité puisque vous
pouvez appliquer des middlewares seulement où ils sont nécessaires permettant à vos
middlewares de ne pas nécessiter de logique spécifique sur le comment/où il doit
s’appliquer.
Note
Le middleware appliqué sera exécuté par RoutingMiddleware,
normalement à la fin de la liste des middleware de votre application.
Avant qu’un middleware ne puisse être appliqué à un scope, il a besoin d’être
enregistré dans la collection de routes:
// dans config/routes.php
use Cake\Http\Middleware\CsrfProtectionMiddleware;
use Cake\Http\Middleware\EncryptedCookieMiddleware;
$routes->scope('/', function (RouteBuilder $routes) {
$routes->registerMiddleware('csrf', new CsrfProtectionMiddleware());
$routes->registerMiddleware('cookies', new EncryptedCookieMiddleware());
});
Une fois enregistré, le middleware peut être appliqué
à des scopes spécifiques:
$routes->scope('/cms', function (RouteBuilder $routes) {
// Enable CSRF & cookies middleware
$routes->applyMiddleware('csrf', 'cookies');
$routes->get('/articles/{action}/*', ['controller' => 'Articles'])
});
Dans le cas où vous auriez des “scopes” imbriqués, les « sous » scopes hériteront
des middlewares apppliqués dans le scope contenant:
$routes->scope('/api', function (RouteBuilder $routes) {
$routes->applyMiddleware('ratelimit', 'auth.api');
$routes->scope('/v1', function (RouteBuilder $routes) {
$routes->applyMiddleware('v1compat');
// Définissez vos routes
});
});
Dans l’exemple ci-dessus, les routes définies dans /v1
auront les middlewares
“ratelimit”, “auth.api”, and “v1compat” appliqués. Si vous ré-ouvrez un scope, les
middlewares appliqués aux routes dans chaque scopes seront isolés:
$routes->scope('/blog', function (RouteBuilder $routes) {
$routes->applyMiddleware('auth');
// Connecter les actions qui nécessitent l'authentification aux 'blog' ici
});
$routes->scope('/blog', function (RouteBuilder $routes) {
// Connecter les actions publiques pour le 'blog' ici
});
Dans l’exemple ci-dessus, les 2 utilisations du scope /blog
ne partagent
pas les middlewares. Par contre, les 2 scopes hériteront des middlewares définis
dans le scope qui les contient.
Grouper les Middlewares
Pour vous aider à garder votre code DRY, les
middlewares peuvent être combinés en groupes. Une fois créés, les groupes peuvent
être appliqués comme des middlewares:
$routes->registerMiddleware('cookie', new EncryptedCookieMiddleware());
$routes->registerMiddleware('auth', new AuthenticationMiddleware());
$routes->registerMiddleware('csrf', new CsrfProtectionMiddleware());
$routes->middlewareGroup('web', ['cookie', 'auth', 'csrf']);
// Appliquer le groupe
$routes->applyMiddleware('web');
Créer des Routes RESTful
Le router aide à générer des routes RESTful pour vos controllers.
Les routes RESTful sont utiles lorsque vous créez des points de terminaison
(endpoint) d’API pour vos applications. Si nous voulions autoriser l’accès REST
à un contrôleur de recette, nous ferions quelque chose comme ceci:
//Dans config/routes.php
$routes->scope('/', function (RouteBuilder $routes) {
$routes->setExtensions(['json']);
$routes->resources('Recipes');
});
La première ligne définit un certain nombre de routes par défaut pour l’accès
REST où la méthode spécifie le format du résultat souhaité (par exemple, xml,
json, rss). Ces routes sont sensibles aux méthodes de requêtes HTTP.
HTTP format |
URL.format |
Action du contrôleur appelée |
GET |
/recipes.format |
RecipesController::index() |
GET |
/recipes/123.format |
RecipesController::view(123) |
POST |
/recipes.format |
RecipesController::add() |
PUT |
/recipes/123.format |
RecipesController::edit(123) |
PATCH |
/recipes/123.format |
RecipesController::edit(123) |
DELETE |
/recipes/123.format |
RecipesController::delete(123) |
Note
La valeur par défaut du modèle pour les ID de ressource ne reconnait que des entiers ou
des UUID. Si vos ID sont différents, vous devrez fournir une expression régulière
via l’option id
. Par exemple. $builder->resources('Recettes', ['id' => '. *'])
.
La classe Router de CakePHP utilise un nombre différent d’indicateurs pour
détecter la méthode HTTP utilisée. Voici la liste dans l’ordre de préférence:
La variable de POST _method
Le header X_HTTP_METHOD_OVERRIDE
Le header REQUEST_METHOD
La variable POST _method
est utile dans l’utilisation d’un navigateur comme
client REST (ou tout ce qui peut faire du POST). Il suffit de configurer la
valeur de _method
avec le nom de la méthode de requête HTTP que vous souhaitez
émuler.
Créer des Routes de Ressources Imbriquées
Une fois que vous avez connecté une ressource dans un scope, vous pouvez aussi
connecter des routes pour des sous-ressources. Les routes de sous-ressources
seront préfixées par le nom de la ressource originale et par son paramètre id.
Par exemple:
$routes->scope('/api', function (RouteBuilder $routes) {
$routes->resources('Articles', function (RouteBuilder $routes) {
$routes->resources('Comments');
});
});
Le code ci-dessus va générer une ressource de route pour articles
et
comments
. Les routes des comments
vont ressembler à ceci:
/api/articles/{article_id}/comments
/api/articles/{article_id}/comments/{id}
Vous pouvez récupérer le champs article_id
de CommentsController
de cette façon:
$this->request->getParam('article_id');
Par défaut les ressources de routes sont connectées au même préfixe que celles de leur scope.
Si vous avez à la fois des contrôleurs de ressources imbriqués et non imbriqués, vous pouvez
utiliser un contrôleur différent dans chaque contexte en utilisant des préfixes:
$routes->scope('/api', function (RouteBuilder $routes) {
$routes->resources('Articles', function (RouteBuilder $routes) {
$routes->resources('Comments', ['prefix' => 'Articles']);
});
});
L’exemple ci-dessus mapperait le champs “Comments” vers
App\Controller\Articles\CommentsController
. Une séparation des contrôleurs
vous permet de simplifier la logique. Les préfixes créés de cette manière sont
compatibles avec Prefix de Routage.
Note
Vous pouvez imbriquer autant de ressources que vous le souhaitez, mais il
n’est pas recommandé d’imbriquer plus de 2 ressources ensembles.
Limiter la Création des Routes
Par défaut, CakePHP va connecter 6 routes pour chaque ressource. Si vous
souhaitez connecter uniquement des routes spécifiques à une ressource, vous
pouvez utiliser l’option only
:
$routes->resources('Articles', [
'only' => ['index', 'view']
]);
Le code ci-dessus devrait créer uniquement les routes de ressource pour la lecture.
Les noms de route sont create
, update
, view
, index
et
delete
.
Changer les Actions du Controller
Vous devrez peut-être modifier le nom des actions du controller qui sont
utilisés lors de la connexion des routes. Par exemple, si votre action
edit()
est nommée put()
, vous pouvez utiliser la clé actions
pour
renommer vos actions:
$routes->resources('Articles', [
'actions' => ['update' => 'put', 'create' => 'add']
]);
Le code ci-dessus va utiliser la méthode put()
pour l’action edit()
, et
add()
au lieu de create()
.
Mapper des Routes de Ressource Supplémentaires
Vous pouvez mapper des méthodes de ressource supplémentaires en utilisant
l’option map
:
$routes->resources('Articles', [
'map' => [
'deleteAll' => [
'action' => 'deleteAll',
'method' => 'DELETE'
]
]
]);
// Ceci connecterait /articles/deleteAll
En plus des routes par défaut, ceci connecterait aussi une route pour
/articles/delete-all. Par défaut le segment de chemin va matcher le nom
de la clé. Vous pouvez utiliser la clé “path” à l’intérieur de la définition
de la ressource pour personnaliser le nom de chemin:
$routes->resources('Articles', [
'map' => [
'updateAll' => [
'action' => 'updateAll',
'method' => 'PUT',
'path' => '/update-many'
],
]
]);
// Ceci connecterait /articles/update-many
Si vous définissez “only” et “map”, assurez-vous que vos méthodes mappées sont
aussi dans la liste “only”.
Router vers une Ressource Préfixée
Les routes vers des ressources peuvent être connectées à des controllers ayant
des préfixes de routage en connectant des routes à l’intérieur d’un scope
préfixé, ou en utilisant l’option prefix
:
$routes->resources('Articles', [
'prefix' => 'Api',
]);
Classes de Route Personnalisée pour les Ressources
Vous pouvez spécifier la clé connectOptions
dans le tableau $options
de
la fonction resources()
pour fournir une configuration personnalisée
utilisée par connect()
:
$routes->scope('/', function (RouteBuilder $routes) {
$routes->resources('Books', [
'connectOptions' => [
'routeClass' => 'ApiRoute',
]
];
});
Inflection de l’URL pour les Routes Ressource
Par défaut le fragment d’URL pour les contrôleurs dont le nom est composé de
plusieurs mots est la forme en underscore du nom du controller. Par exemple,
le fragment d’URL pour BlogPosts
serait /blog-posts.
Vous pouvez spécifier un type d’inflection alternatif en utilisant l’option
inflect
:
$routes->scope('/', function (RouteBuilder $routes) {
$routes->resources('BlogPosts', [
'inflect' => 'underscore' // Utilisera ``Inflector::underscore()``
]);
})
Ce qui est au-dessus va générer des URLs de style /blog_posts*.
Changer le chemin d’un élément
Par défaut, les ressources de routes utilisent le nom de ressource ayant subi
une inflexion en guise de segment d’URL. Vous pouvez définir un segment d’URL
personnalisé à l’aide de l’option path
:
$routes->scope('/', function (RouteBuilder $routes) {
$routes->resources('BlogPosts', ['path' => 'posts']);
});
Générer des URLs
-
static Cake\Routing\RouterBuilder::url($url = null, $full = false)
-
reverse($params, $full = fals
La génération d’URL ou le routing inversé est une fonctionnalité dans CakePHP qui est utilisée
pour vous permettre de changer votre structure d’URL sans avoir à modifier tout votre
code.
Si vous créez des URLs en utilisant des chaînes de caractères comme:
$this->Html->link('View', '/articles/view/' . $id);
Et ensuite plus tard, vous décidez que /articles
devrait vraiment être
appelé “posts” à la place, vous devrez aller dans toute votre application
en renommant les URLs. Cependant, si vous définissiez votre lien comme:
//`link()` utilise Router::url() en interne et accepte un tableau de routage
$this->Html->link(
'View',
['controller' => 'Articles', 'action' => 'view', $id]
);
ou:
//'Router::reverse()' fonctionne sur le tableau de paramètres de requête
//et produira une entrée valide pour la méthode `link()` : une url
//sous forme de chaîne de caractères.
$requestParams = Router::getRequest()->getAttributes('params');
$this->Html->link('View', Router::reverse($requestParams));
Ensuite quand vous décidez de changer vos URLs, vous pouvez le faire en
définissant une route. Cela changerait à la fois le mapping d’URL entrant,
ainsi que les URLs générés.
Le choix de la technique est déterminé par la façon dont vous pouvez prédire
les éléments du tableau de routage.
Utilisation de Router::url()
Router::url()
vous permet d’utiliser des Tableaux de routage
dans les situations où les éléments de tableau requis sont fixes ou facilement déduits.
Il fournira un routage inversé lorsque l’URL de destination est bien définie:
$this->Html->link(
'View',
['controller' => 'Articles', 'action' => 'view', $id]
);
Il est également utile lorsque la destination est inconnue mais suit un
modèle bien défini
$this->Html->link(
'View',
['controller' => $controller, 'action' => 'view', $id]
);
Les éléments qui possèdent des clés numériques sont traités comme Arguments Passés.
Quand vous utilisez les URLs en tableau, vous pouvez définir les paramètres
chaîne de la requête et les fragments de document en utilisant les clés
spéciales:
$routes->url([
'controller' => 'Articles',
'action' => 'index',
'?' => ['page' => 1],
'#' => 'top'
]);
// Cela générera une URL comme:
/articles/index?page=1#top
Vous pouvez également utiliser n’importe quel élément spécial de route lorsque
vous générez des URLs:
_ext
Utilisé pour Routing des Extensions de Fichier .
_base
Défini à false
pour retirer le chemin de base de l’URL générée.
Si votre application n’est pas dans le répertoire racine, cette option peut
être utilisée pour générer les URLs qui sont “liées à cake”.
_scheme
Défini pour créer les liens sur les schémas différents comme
webcal ou ftp. Par défaut, au schéma courant.
_host
Définit l’hôte à utiliser pour le lien. Par défaut à l’hôte courant.
_port
Définit le port si vous avez besoin de créer les liens sur des ports
non-standards.
_method
Définit le verbe HTTP à utiliser pour cette URL.
_full
Si à true
, la valeur de App.fullBaseUrl
vue dans
Configuration Générale sera ajoutée devant les URL générées.
_https
Défini à true
pour convertir l’URL générée à https, ou false
pour forcer http.
_method
Definit la méthode HTTP à utiliser. Utile si vous travaillez avec
Créer des Routes RESTful.
_name
Nom de route. Si vous avez configuré les routes nommées, vous
pouvez utiliser cette clé pour les spécifier.
Utilisation de Router::reverse()
Router::reverse()
vous permet d’utiliser les: ref: request-parameters dans les cas
où l’URL courante modifiée sert de base à celle de destination mais que les éléments
de l’URL courantes ne sont pas prévisibles.
À titre d’exemple, imaginez un blog permettant aux utilisateurs de créer des Articles et
Commentaires, et de marquer les deux comme publié ou brouillon. Les deuxpages d’index
pourrait inclure l’ID utilisateur. L’URL Commentaires pourrait également inclure
un identifiant d’article pour identifier l’article auquel le commentaire fait référence.
Voici les URL correspondant à ce scénario:
/articles/index/42
/comments/index/42/18
Lorsque l’auteur utilise ces pages, il serait pratique d’inclure des liens
qui permettent d’afficher la page avec tous les résultats, publiés uniquement,
ou à l’état brouillon seulement.
Pour garder le code DRY, il serait préférable d’inclure les liens via
un élément:
// element/filter_published.php
$params = $this->getRequest()->getAttribute('params');
/* prépare l'url pour l'état 'Brouillon' */
$params = Hash::insert($params, '?.published', 0);
echo $this->Html->link(__('Brouillon'), Router::reverse($params));
/* prépare l'url pour l'état for 'Publié' */
$params = Hash::insert($params, '?.published', 1);
echo $this->Html->link(__('Publié'), Router::reverse($params));
/* prépare l'url pour tous les articles */
$params = Hash::remove($params, '?.published');
echo $this->Html->link(__('Tous'), Router::reverse($params));
Les liens générés par ces appels de méthode incluraient un ou deux passages
paramètres en fonction de la structure de l’URL actuelle. Et le code
fonctionnerait pour toute URL future, par exemple, si vous commencez à utiliser
pathPrefixes ou si vous prévoyez de passer plus de paramètres.
Tableaux de Routages vs Paramètrees de Requête
La différence significative entre les deux tableaux et leur utilisation dans ces
les méthodes de routage inversé sont dans la manière dont elles incluent les paramètres
passés.
Les tableaux de routage incluent les paramètres fournis en tant que valeurs
sans clé dans le tableau:
$url = [
'controller' => 'Articles',
'action' => 'View',
$id, //a pass parameter
'page' => 3, //un argument de requête (query)
];
Les paramètres de requête incluent les paramètres fournis dans la clé “pass”
du tableau:
$url = [
'controller' => 'Articles',
'action' => 'View',
'pass' => [$id], //the pass parameters
'?' => 'page' => 3, //les arguments de la requête (query)
];
Il est donc possible, si vous le souhaitez, de convertir les paramètres de la requête en
un tableau de routage ou vice versa.