Routage

Règles de routage par défaut

La règle de routage par défaut de webman est http://127.0.0.1:8787/{contrôleur}/{action}.

Le contrôleur par défaut est app\controller\IndexController, et l'action par défaut est index.

Par exemple, accéder à :

  • http://127.0.0.1:8787 accède par défaut à la méthode index de la classe app\controller\IndexController
  • http://127.0.0.1:8787/foo accède par défaut à la méthode index de la classe app\controller\FooController
  • http://127.0.0.1:8787/foo/test accède par défaut à la méthode test de la classe app\controller\FooController
  • http://127.0.0.1:8787/admin/foo/test accède par défaut à la méthode test de la classe app\admin\controller\FooController (voir Multi-application)

De plus, webman prend en charge des règles de routage par défaut plus complexes depuis la version 1.4, par exemple

app
├── admin
│   └── v1
│       └── v2
│           └── v3
│               └── controller
│                   └── IndexController.php
└── controller
    ├── v1
    │   └── IndexController.php
    └── v2
        └── v3
            └── IndexController.php

Lorsque vous souhaitez changer le routage d'une requête, veuillez modifier le fichier de configuration config/route.php.

Si vous voulez désactiver le routage par défaut, ajoutez la configuration suivante à la dernière ligne du fichier de configuration config/route.php :

Route::disableDefaultRoute();

Routage à l'aide de closures

Ajoutez le code de routage suivant dans config/route.php

use support\Request;
Route::any('/test', function (Request $request) {
    return response('test');
});

Attention
Étant donné que les fonctions de closure ne font partie d'aucun contrôleur, les valeurs de $request->app, $request->controller et $request->action seront toutes des chaînes vides.

Lorsque l'adresse d'accès est http://127.0.0.1:8787/test, la chaîne test sera renvoyée.

Attention
Le chemin de routage doit commencer par un /, par exemple

use support\Request;
// Utilisation incorrecte
Route::any('test', function (Request $request) {
    return response('test');
});

// Utilisation correcte
Route::any('/test', function (Request $request) {
    return response('test');
});

Routage de classe

Ajoutez le code de routage suivant dans config/route.php

Route::any('/testclass', [app\controller\IndexController::class, 'test']);

Lorsque l'adresse d'accès est http://127.0.0.1:8787/testclass, la valeur de retour de la méthode test de la classe app\controller\IndexController sera renvoyée.

Paramètres de routage

S'il existe des paramètres dans la route, utilisez {key} pour les faire correspondre ; le résultat de la correspondance sera transmis en tant que paramètres aux méthodes du contrôleur approprié (à partir du deuxième paramètre et ainsi de suite), par exemple :

// Correspond à /user/123 /user/abc
Route::any('/user/{id}', [app\controller\UserController::class, 'get']);
namespace app\controller;
use support\Request;

class UserController
{
    public function get(Request $request, $id)
    {
        return response('Paramètre reçu '.$id);
    }
}

Plus d'exemples :

use support\Request;
// Correspond à /user/123, ne correspond pas à /user/abc
Route::any('/user/{id:\d+}', function (Request $request, $id) {
    return response($id);
});

// Correspond à /user/foobar, ne correspond pas à /user/foo/bar
Route::any('/user/{name}', function (Request $request, $name) {
   return response($name);
});

// Correspond à /user /user/123 et /user/abc   [] indique que c'est optionnel
Route::any('/user[/{name}]', function (Request $request, $name = null) {
   return response($name ?? 'tom');
});

// Correspond à toutes les requêtes avec le préfixe /user/
Route::any('/user/[{path:.+}]', function (Request $request) {
    return $request->path();
});

// Correspond à toutes les requêtes options   : indique la règle regex pour ce paramètre nommé
Route::options('[{path:.+}]', function () {
    return response('');
});

Résumé des usages avancés

La syntaxe [] dans le routage Webman est principalement utilisée pour gérer des parties de chemin optionnelles ou des routes dynamiques, elle vous permet de définir des structures de chemin et des règles de correspondance plus complexes pour vos routes.

: est utilisé pour spécifier les expressions régulières

Groupes de routage

Parfois, le routage contient de nombreux préfixes identiques, nous pouvons alors utiliser des groupes de routage pour simplifier la définition. Par exemple :

Route::group('/blog', function () {
   Route::any('/create', function (Request $request) {return response('create');});
   Route::any('/edit', function (Request $request) {return response('edit');});
   Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});

Équivalent à

Route::any('/blog/create', function (Request $request) {return response('create');});
Route::any('/blog/edit', function (Request $request) {return response('edit');});
Route::any('/blog/view/{id}', function (Request $request, $id) {return response("view $id");});

Utilisation imbriquée des groupes

Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('create');});
      Route::any('/edit', function (Request $request) {return response('edit');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
   });  
});

Middleware de routage

Nous pouvons définir un middleware pour une route ou un groupe de routes.
Par exemple :

Route::any('/admin', [app\admin\controller\IndexController::class, 'index'])->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);

Route::group('/blog', function () {
   Route::any('/create', function () {return response('create');});
   Route::any('/edit', function () {return response('edit');});
   Route::any('/view/{id}', function ($request, $id) {response("view $id");});
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);
# Exemple d'utilisation incorrecte (valide pour webman-framework >= 1.5.7)
Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('create');});
      Route::any('/edit', function (Request $request) {return response('edit');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
   });  
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);
# Exemple d'utilisation correcte
Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('create');});
      Route::any('/edit', function (Request $request) {return response('edit');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
   })->middleware([
        app\middleware\MiddlewareA::class,
        app\middleware\MiddlewareB::class,
    ]);  
});

Routage de ressources

Route::resource('/test', app\controller\IndexController::class);

// Spécification du routage des ressources
Route::resource('/test', app\controller\IndexController::class, ['index','create']);

// Routage des ressources non définies
// Par exemple, si notifier l'adresse d'accès serait pour la route any /test/notify ou /test/notify/{id} et routeName serait test.notify
Route::resource('/test', app\controller\IndexController::class, ['index','create','notify']);
Verbe URI Action Nom de la route
GET /test index test.index
GET /test/create create test.create
POST /test store test.store
GET /test/{id} show test.show
GET /test/{id}/edit edit test.edit
PUT /test/{id} update test.update
DELETE /test/{id} destroy test.destroy
PUT /test/{id}/recovery recovery test.recovery

Génération d'URL

Attention
La génération d'URL pour les groupes imbriqués n'est pas encore prise en charge.

Par exemple, pour la route :

Route::any('/blog/{id}', [app\controller\BlogController::class, 'view'])->name('blog.view');

Nous pouvons utiliser la méthode suivante pour générer l'URL de cette route.

route('blog.view', ['id' => 100]); // Le résultat sera /blog/100

Lors de l'utilisation de l'URL de route dans une vue, vous pouvez utiliser cette méthode, afin que peu importe comment les règles de routage changent, l'URL sera automatiquement générée, évitant ainsi de nombreuses modifications des fichiers de vue en raison des ajustements d'adresse de routage.

Obtention des informations de routage

Via l'objet $request->route, nous pouvons obtenir les informations de routage de la requête actuelle, par exemple

$route = $request->route; // Équivalent à $route = request()->route;
if ($route) {
    var_export($route->getPath());
    var_export($route->getMethods());
    var_export($route->getName());
    var_export($route->getMiddleware());
    var_export($route->getCallback());
    var_export($route->param());
}

Attention
Si la requête actuelle ne correspond à aucune des routes configurées dans le fichier config/route.php, alors $request->route sera null, c'est-à-dire que dans le cas où la route par défaut est utilisée, $request->route sera null.

Gestion des erreurs 404

Lorsque la route ne peut pas être trouvée, le statut 404 est renvoyé par défaut avec le contenu associé au 404.

Si le développeur souhaite intervenir dans le flux commercial lorsque la route n'est pas trouvée, il peut utiliser la méthode de routage de secours fournie par webman Route::fallback($callback). Par exemple, le code suivant redirige vers la page d'accueil lorsque la route n'est pas trouvée.

Route::fallback(function(){
    return redirect('/');
});

De plus, lorsque la route n'existe pas, vous pouvez renvoyer des données JSON, ce qui est très utile lorsque webman est utilisé en tant qu'interface API.

Route::fallback(function(){
    return json(['code' => 404, 'msg' => '404 non trouvé']);
});

Ajout de middleware aux erreurs 404

Par défaut, les requêtes 404 ne passent par aucun middleware. Si vous souhaitez ajouter un middleware aux requêtes 404, veuillez consulter le code suivant.

Route::fallback(function(){
    return json(['code' => 404, 'msg' => '404 non trouvé']);
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);

Liens connexes Page d'erreur 404 500 personnalisée

Désactivation du routage par défaut

// Désactiver le routage par défaut du projet principal, sans impact sur les plugins d'application
Route::disableDefaultRoute();
// Désactiver le routage de l'application admin du projet principal, sans impact sur les plugins d'application
Route::disableDefaultRoute('', 'admin');
// Désactiver le routage par défaut du plugin foo, sans impact sur le projet principal
Route::disableDefaultRoute('foo');
// Désactiver le routage par défaut de l'application admin du plugin foo, sans impact sur le projet principal
Route::disableDefaultRoute('foo', 'admin');
// Désactiver le routage par défaut du contrôleur [\app\controller\IndexController::class, 'index']
Route::disableDefaultRoute([\app\controller\IndexController::class, 'index']);

Désactivation des routes par défaut via annotations

Nous pouvons désactiver le routage par défaut d'un certain contrôleur à l'aide d'annotations, par exemple :

namespace app\controller;
use support\annotation\DisableDefaultRoute;

#[DisableDefaultRoute]
class IndexController
{
    public function index()
    {
        return 'index';
    }
}

De la même manière, nous pouvons également désactiver le routage par défaut d'une méthode d'un certain contrôleur à l'aide d'annotations, par exemple :

namespace app\controller;
use support\annotation\DisableDefaultRoute;

class IndexController
{
    #[DisableDefaultRoute]
    public function index()
    {
        return 'index';
    }
}

Interface de routage

// Définir la route pour une méthode de requête quelconque $uri
Route::any($uri, $callback);
// Définir la route pour la requête get $uri
Route::get($uri, $callback);
// Définir la route pour la requête post $uri
Route::post($uri, $callback);
// Définir la route pour la requête put $uri
Route::put($uri, $callback);
// Définir la route pour la requête patch $uri
Route::patch($uri, $callback);
// Définir la route pour la requête delete $uri
Route::delete($uri, $callback);
// Définir la route pour la requête head $uri
Route::head($uri, $callback);
// Définir la route pour la requête options $uri
Route::options($uri, $callback);
// Définir des routes pour plusieurs types de requêtes en même temps
Route::add(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'], $uri, $callback);
// Groupes de routes
Route::group($path, $callback);
// Routes de ressources
Route::resource($path, $callback, [$options]);
// Désactiver les routes
Route::disableDefaultRoute($plugin = '');
// Route de secours, définit les routes par défaut
Route::fallback($callback, $plugin = '');
// Obtenir toutes les informations de routage
Route::getRoutes();

Si un uri n'a pas de route correspondante (y compris le routage par défaut), et qu'aucune route de secours n'est configurée, une réponse 404 sera renvoyée.

Plusieurs fichiers de configuration de routage

Si vous souhaitez gérer le routage à l'aide de plusieurs fichiers de configuration de routage, par exemple lors de l'utilisation de multi-application, chaque application ayant ses propres configurations de routage, vous pouvez charger des fichiers de configuration externes à l'aide de require.
Par exemple, dans config/route.php

<?php

// Charger la configuration de routage de l'application admin
require_once app_path('admin/config/route.php');
// Charger la configuration de routage de l'application api
require_once app_path('api/config/route.php');