Il lit la route URL et analyse les valeurs du chemin, afin qu'il puisse être interprété manuellement ou automatiquement de la manière la plus rapide possible (par exemple, pour implémenter un système MVC).
Contrairement à d'autres bibliothèques, cette bibliothèque n'a pas de dépendances et est contenue dans une seule classe, elle est donc compatible avec n'importe quel projet PHP, par exemple WordPress, Laravel, Drupal, un projet PHP personnalisé, etc.
Cette bibliothèque est basée sur CoC Convention over Configuration . Il réduit le passe-partout mais il a des fonctionnalités fixes. Cette bibliothèque ne permet pas d'utiliser des "routes" personnalisées mais elle couvre pratiquement tous les cas, elle augmente donc les performances et la convivialité tout en sacrifiant la flexibilité.
Disons que nous avons la prochaine URL http://somedomain.dom/Customer/Update/2 Cette bibliothèque convertit cette URL en variables qui pourraient être traitées ou appeler directement une méthode.
route.php
$ route = new RouteOne ( ' http://www.somedomain.dom ' );
$ route -> addPath ( ' api/{controller}/{action}/{id} ' );
$ route -> addPath ( ' {controller}/{action}/{id}/{idparent} ' );
$ route -> fetchPath ();
$ this -> callObjectEx ( ' cocacolacontroller{controller}Controller ' );
classe contrôleurCustomerController.php
namespace cocacola controller ;
class CustomerController {
public function updateAction ( $ id = null , $ idparent = null , $ event = null ) {
echo " We want to update the customer $ id " ;
}
}
Disons que nous effectuons l'opération suivante :
Un utilisateur appelle le site Web suivant http://somedomain.com/Customer/Insert, il souhaite afficher un formulaire pour insérer un client
use eftec RouteOne RouteOne ;
$ route = new RouteOne ( ' . ' , null , null ); // Create the RouteOne Class
$ route -> fetch (); // fetch all the input values (from the route, get, post and such).
$ route -> callObject ( ' somenamespace \ controller \ %sController ' ); // where it will call the class CustomerController*
ou
use eftec RouteOne RouteOne ;
$ route = new RouteOne ( ' . ' , null , null ); // Create the RouteOne Class
$ route -> fetch (); // fetch all the input values (from the route, get, post and such).
$ route -> callObjectEx ( ' somenamespace \ controller \ {controller}Controller ' ); // where it will call the class CustomerController*
Ce code appelle la méthode InsertActionGet (GET), InsertActionPost (POST) ou InsertAction (GET/POST) à l'intérieur de la classe Customer
La méthode appelée s’écrit comme suit :
class Customer {
public function insertAction ( $ id = "" , $ idparent = "" , $ event = "" ) {
// here we do our operation.
}
}
Supposons que nous souhaitions mettre à jour un numéro de client 20 , nous pourrions alors appeler la page suivante
http://somedomain.com/Customer/Update/20
où 20 est le "$id" du client à modifier (il peut s'agir d'un numéro ou d'une chaîne)
Et si nous voulons mettre à jour un client numéro 20 de l'entreprise APPL
http://somedomain.com/Customer/Update/20/APPL
Où APPL est l' identifiant
Maintenant, disons que nous cliquons sur un bouton ou que nous effectuons une action. Il pourrait être capturé par le champ _event , et il est lu par l'argument $event . Cette variable peut être envoyée via GET ou POST.
http://somedomain.com/Customer/Update/20/APPL?_event=click
Remarque : les modules sont obtenus automatiquement si vous utilisez addPath() et fetchPath(), vous n'avez donc pas besoin de le spécifier. Maintenant, disons que notre système est modulaire et que nous avons plusieurs clients (clients internes, externes, etc.)
$ route = new RouteOne ( ' . ' , null , true ); // true indicates it is modular.
ou
$ route = new RouteOne ( ' . ' , null ,[ ' Internal ' ]); // or we determine the module automatically. In this case, every url that starts with Internal
alors
$ route -> fetch ();
$ route -> callObject ( ' somenamespace \ %2s% \ controller \ %1sController ' );
http://somedomain.com/Internal/Customer/Update/20/APPL?_event=click
Ensuite, la première ramification est le nom du module ( Internal ) et il appelle la classe somenamespaceInternalcontrollerCustomerController
le compositeur nécessite eftec/ RouteOne
Linux :
vendor/bin/ RouteOne cli -init (if the binary does not work, then chage the permission to execution)
Fenêtres :
. v endor b in r outeonecli.bat -init
Il créera le fichier .htaccess et les fichiers route.php et route.php auront une configuration par défaut.
const BASEURL = " http://localhost " ; // Base url edit this value.
const BASEWEBNS = " eftec \ controller " ; // Base namespace (web) edit this value
const BASEAPINS = " eftec \ api " ; // Base namespace (api) edit this value
Plus tard, vous pourrez ajouter ou modifier le code dans ce fichier.
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
DirectoryIndex route.php
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ route.php?req=$1 [L,QSA]
</IfModule>
Si votre hébergeur n'autorise pas l'option FollowSymlinks, essayez de la remplacer par Options +SymLinksIfOwnerMatch.
La ligne importante est :
RewriteRule ^(.*)$ route.php?req=$1 [L,QSA] # Le routeur à appeler.
server {
listen 80;
server_name localhost;
root /example.com/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /router.php?req=$document_uri&$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ .php$ {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /.(?!well-known).* {
deny all;
}
}
La ligne importante est :
try_files $uri $uri/ /router.php?req=$document_uri&$query_string;
server {
listen 80;
server_name localhost;
root c:/www;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /router.php?req=$document_uri&$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /.(?!well-known).* {
deny all;
}
}
La ligne importante est :
try_files $uri $uri/ /router.php?req=$document_uri&$query_string;
où router.php est le fichier qui fonctionnera comme routeur. ?req=$1 est important car le système lira l'itinéraire à partir de "req"
// router.php
$ route = new RouteOne (); // Create the RouteOne Class
$ route -> fetch (); // fetch all the input values (from the route, get, post and such).
$ route -> callObject ( ' somenamespace \ controller \ %sController ' ); // where it will call the class somenamespacecontrollerCustomerController
Note:
Si vous souhaitez utiliser un argument différent de "req", alors vous pouvez le modifier en utilisant le code suivant :
$route->argumentName='nouvelargument';
Depuis la 1.21, il est possible d'utiliser un chemin personnalisé au lieu d'un chemin prédéfini. C'est la méthode recommandée. L'autre méthode est toujours présente.
Syntaxe:
chemin clair()
Il efface tous les chemins définis
Syntaxe:
addPath($path, $name = null,callable $middleWare=null)
Il ajoute des chemins qui pourraient être évalués à l'aide de fetchPath()
Exemple:
$ this -> addPath ( ' api/{controller}/{action}/{id:0} ' , ' apipath ' );
$ this -> addPath ( ' /api/{controller}/{action}/{id:0}/ ' , ' apipath ' ); // "/" at the beginner and end are trimmed.
$ this -> addPath ( ' {controller}/{action}/{id:0} ' , ' webpath ' );
$ this -> addPath ( ' {controller:root}/{action}/{id:0} ' , ' webpath ' ); // root path using default
$ this -> addPath ( ' somepath ' , ' namepath ' ,
function ( callable $ next , $ id = null , $ idparent = null , $ event = null ) {
echo " middleware n" ;
$ result = $ next ( $ id , $ idparent , $ event ); // calling the controller
echo " endmiddleware n" ;
return $ result ;
});
Note:
La première partie du chemin, avant le "{" est utilisée pour déterminer quel chemin sera utilisé.
Exemple "path/{controller}" et "path/{controller}/{id}", le système considérera que c'est le même chemin
chaîne de paramètre $path Le chemin, exemple "aaa/{controller}/{action:default}/{id}"
Où default est la valeur par défaut facultative.
paramètre string|null $name (facultatif), le nom du chemin
paramètre callable|null $middleWare Une fonction appelable utilisée pour le middleware.
Le premier argument de la fonction doit être une méthode appelable
Les arguments suivants doivent être les arguments définis par callObjectEx
(identifiant, identifiantparent, événement)
Le chemin peut commencer par un emplacement statique mais le reste du chemin doit être défini par des variables (entourées de {}) et séparées par "/".
Vous pouvez également définir une valeur par défaut pour un chemin en écrivant ":" après le nom de la variable : {name:defaultvalue}
Le nom peut être obtenu en utilisant $this->currentPath. Si vous ajoutez un nom portant le même nom, il est remplacé.
Si vous ne définissez pas de nom, il utilise un numéro automatique.
Le nom est également renvoyé lorsque vous appelez $this->fetchPath()
Exemple:
$ this -> addPath ( ' {controller}/{id}/{idparent} ' );
$ this -> addPath ( ' myapi/otherfolder/{controller}/{id}/{idparent} ' );
$ this -> addPath ( ' {controller:defcontroller}/{action:defaction}/{id:1}/{idparent:2} ' );
// url: /dummy/10/20 =>(controller: dummy, id=10, idparent=20)
// url: /myapi/otherfolder/dummy/10/20 =>(controller: dummy, id=10, idparent=20)
Vous pouvez définir différents chemins, mais il n'utilise que la première partie du chemin qui correspond à une URL. 'path/somepath/{id}' fonctionnera 'path/{id}/other' ne fonctionnera pas
Syntaxe:
récupérerPath()
Il récupère le chemin précédemment défini par addPath et renvoie le nom (ou le numéro) du chemin. S'il n'est pas trouvé, il renvoie false
Exemple:
$ route = new RouteOne ( ' http://www.example.dom ' );
$ route -> addPath ( ' {controller}/{id}/{idparent} ' , ' optionalname ' );
// if the url is : http://www.example.dom/customer/1/200 then it will return
echo $ route -> fetchPath (); // optionalname
echo $ route -> controller ; // customer
echo $ route -> id ; // 1
echo $ route -> idparent ; // 200
Il obtient une valeur de requête (URL).
Remarque : Cette requête n'inclut pas les valeurs "req", "_event" et "_extra"
Exemple:
// http://localhost/..../?id=hi
$ id = $ router -> getQuery ( " id " ); // hi
$ nf = $ router -> getQuery ( " something " , " not found " ); // not found
Il définit une valeur de requête
Exemple:
$ route -> setQuery ( " id " , " hi " );
$ id = $ router -> getQuery ( " id " ); // hi
Sintaxe :
récupérerPath()
Récupérez les valeurs de l'itinéraire et les valeurs sont traitées.
Sintax
callObjectEx($classStructure, $throwOnError, $method, $methodGet, $methodPost,$arguments,$injectArguments)
Il crée une nouvelle instance d'un objet (par exemple, un objet Controller) et appelle la méthode.
Remarque : Il s'agit d'une version avancée de this::callObject()
Cette méthode utilise {} pour remplacer les valeurs basées sur les variables suivantes :
Étiqueter | Description |
---|---|
{contrôleur} | Le nom du contrôleur |
{action} | L'action en cours |
{événement} | L'événement actuel |
{taper} | Le type actuel de chemin (ws,controller,front,api) |
{module} | Le module actuel (si le module est actif) |
{identifiant} | L'identifiant actuel |
{parent identifié} | L'identifiant actuel |
{catégorie} | La catégorie actuelle |
{sous-catégorie} | La sous-catégorie actuelle |
{sous-sous-catégorie} | La sous-sous-catégorie actuelle |
Exemple:
// controller example http://somedomain/Customer/Insert/23
$ this -> callObjectEx ( ' cocacolacontroller{controller}Controller ' );
// it calls the method cocacolacontrollerCustomer::InsertAction(23,'','');
// front example: http://somedomain/product/coffee/nescafe/1
$ this -> callObjectEx ( ' cocacolacontroller{category}Controller ' // the class to call
, false // if error then it throw an error
, ' {subcategory} ' // the method to call (get, post or any other method)
, null // the method to call (method get)
, null // the method to call (method post)
,[ ' subsubcategory ' , ' id ' ] // the arguments to call the method
,[ ' arg1 ' , ' arg2 ' ]); // arguments that will be passed to the constructor of the instance
// it calls the method cocacolacontrollerproduct::coffee('nescafe','1');
Appelez une méthode à l’intérieur d’un objet en utilisant la route actuelle.
Exemple:
Routeur :
$ databaseService = new SomeDatabaseService ();
$ route = new RouteOne ();
$ route -> callObjectEx ( ' cocacolacontroller{controller}Controller ' // the class to call
, false // if error then it throw an error
, ' {action}Action ' // the method to call (get, post or any other method)
, ' {action}Action{verb} ' // the method to call (method get)
, ' {action}Action{verb} ' // the method to call (method post)
,[ ' id ' , ' idparent ' , ' event ' ] // the arguments to call the method
,[ $ databaseService , $ route ]); // (optional)arguments that will be passed to the constructor of the instance
Contrôleur:
namespace cocacola controller ;
class CustomerController {
protected $ databaseService ;
protected $ route ;
public function __construct ( $ databaseService , $ route ) {
// optional: injecting services
$ this -> databaseService = $ databaseService ;
$ this -> route = $ route ;
}
// any action GET or POST
public function GreenAction ( $ id = "" , $ idparent = "" , $ event = "" ) {
}
// GET only action (optional)
public function BlueActionGET ( $ id = "" , $ idparent = "" , $ event = "" ) {
// **my code goes here.**
}
// POST only action (optional)
public function YellowActionPOST ( $ id = "" , $ idparent = "" , $ event = "" ) {
// **my code goes here.**
}
// GET only action (optional)
public function RedActionGET ( $ id = "" , $ idparent = "" , $ event = "" ) {
// **my code goes here.**
}
// any action GET or POST
public function RedAction ( $ id = "" , $ idparent = "" , $ event = "" ) {
// **my code goes here.**
}
}
Résultats:
URL | méthode appelée |
---|---|
http://localhost/Client/Vert (GET) | Action Verte |
http://localhost/Customer/Green/20/30?_event=click (OBTENIR) | GreenAction($id=20, $idparent=30, $event='click') |
http://localhost/Client/Vert (POST) | Action Verte |
http://localhost/Client/Blue (GET) | BlueActionGET |
http://localhost/Customer/Blue (POST) | ERREUR |
http://localhost/Client/Jaune (GET) | ERREUR |
http://localhost/Client/Jaune (POST) | YellowActionPOST |
http://localhost/Client/Red (GET) | RedActionGET (Il a la priorité sur RedAction) |
http://localhost/Client/Red (POST) | Rédaction |
http://localhost/Client/Orange | ERREUR |
Il appelle (inclut) un fichier php en utilisant le nom actuel du contrôleur
Syntaxe:
getHeader($clé, $valueIfNotFound = null)
Il obtient l'en-tête actuel (le cas échéant). Si la valeur n'est pas trouvée, elle renvoie $valueIfNotFound. Notez que la clé $ est toujours convertie en majuscule.
Exemple:
$ token = $ this -> getHeader ( ' token ' , ' TOKEN NOT FOUND ' );
Syntaxe:
getBody($jsonDeserialize = faux, $asAssociative = vrai)
Il récupère le corps d’une requête.
Exemple:
$ body = $ this -> getBody (); // '{"id"=>1,"name"=>john}' (as string)
$ body = $ this -> getBody ( true ); // stdClass {id=>1,name=>john}
$ body = $ this -> getBody ( true , true ); // ["id"=>1,"name"=>john]
Renvoie l'URL de base actuelle sans espace, paramètres ou requêtes
Note : cette fonction repose sur $_SERVER['SERVER_NAME'], et elle peut être modifiée par l'utilisateur final
Il renvoie le serveur actuel sans barre oblique finale.
$ route -> getCurrentServer (); // http://somedomain
Il définit le nom actuel du serveur. Il est utilisé par getCurrentUrl() et getCurrentServer().
Remarque : Si $this->setCurrentServer() n'est pas défini, alors il utilise $_SERVER['SERVER_NAME'] et peut être modifié par l'utilisateur.
$ route -> setCurrentServer ( ' localhost ' );
$ route -> setCurrentServer ( ' 127.0.0.1 ' );
$ route -> setCurrentServer ( ' domain.dom ' );
Il obtient l'URL (complète) basée sur les informations de la classe.
$ route -> getUrl (); // http://somedomain/controller/action/id
$ route -> getUrl ( ' id=20 ' ); // http://somedomain/controller/action/id?id=20
$ route -> getUrl ( ' id=20 ' , true ); // http://somedomain/controller/action/id?id=20&field=20&field2=40
Il crée une URL basée sur des valeurs personnalisées
$ route -> url ( null , " Customer " , " Update " , 20 ); // Customer/Update/20
Il construit une URL (avant) basée sur des valeurs personnalisées
$ route -> url ( null , " Daily " , " Milk " , 20 ); // Daily/Milk/20
Si le sous-domaine est vide ou différent de www, alors il redirige vers www.domain.com.
Remarque : Cela ne fonctionne pas avec localhost, domaine sans TLD (netbios) ou domaines IP. C'est exprès.
Remarque : Si ce code doit être redirigé, il arrête l'exécution du code. Habituellement, il doit être appelé en haut du code
$ route -> alwaysWWW (); // if the domain is somedomain.dom/url, then it redirects to www.somedomain.dom/url
$ route -> alwaysWWW ( true ); // if the domain is http: somedomain.dom/url, then it redirects to https: www.somedomain.dom/url
Si la page est chargée en http, elle redirige vers https.
Remarque : Cela ne fonctionne pas avec localhost, domaine sans TLD (netbios) ou domaines IP. C'est exprès.
Remarque : Si ce code doit être redirigé, il arrête l'exécution du code. Habituellement, il doit être appelé en haut du code
$ route -> alwaysHTTPS (); // http://somedomain.com ---> https://somedomain.com
$ route -> alwaysHTTPS (); // http://localhost ---> // http://localhost
$ route -> alwaysHTTPS (); // http://127.0.0.1 ---> // http://127.0.0.1
$ route -> alwaysHTTPS (); // http://mypc ---> // http://mypc
Si le sous-domaine est www (exemple www.domain.dom), alors il redirige vers un domaine nu domain.dom
Remarque : Cela ne fonctionne pas avec localhost, domaine sans TLD (netbios) ou domaines IP. C'est exprès.
Remarque : Si ce code doit être redirigé, il arrête l'exécution du code. Habituellement, il faut l'appeler en haut du code
$ route -> alwaysNakedDomain (); // if the domain is www.somedomain.dom/url, then it redirects to somedomain.dom/url
$ route -> alwaysNakedDomain ( true ); // if the domain is http: www.somedomain.dom/url, then it redirects to https: somedomain.dom/url
Champ | chemin | Description | Exemple |
---|---|---|---|
$Nomargument | Le nom de l'argument utilisé par Apache .Htaccess et nginx | $this-argumentName='req'; | |
$base | C'est l'URL de base. | $this->base=0; | |
$type | C'est le type d'url (api,ws,controller ou front) | echo $this->type; // API | |
$module | {module} | C'est le module actuel | echo $this->module; |
$contrôleur | {contrôleur} | C'est le contrôleur. | echo $this->contrôleur ; |
$action | {action} | C'est l'action. | echo $this->action; |
$id | {identifiant} | C'est l'identifiant | echo $this->id; |
$événement | {événement} | C'est l'événement (comme "cliquez sur le bouton"). | echo$this->événement; |
$idparent | {parent identifié} | Il s'agit de l'identifiant actuel du parent (le cas échéant) | echo $this->idparent; |
$supplémentaire | {supplémentaire} | C'est l'événement (comme "cliquez sur le bouton) | echo $this->extra; |
$catégorie | {catégorie} | La catégorie actuelle. C'est utile pour le type 'front' | echo $this->category; |
$sous-catégorie | {sous-catégorie} | La sous-catégorie actuelle. C'est utile pour le type 'front' | echo $this->sous-catégorie ; |
$sous-sous-catégorie | {sous-sous-catégorie} | La sous-sous-catégorie actuelle. C'est utile pour le type 'front' | echo $this->sous-sous-catégorie ; |
$identifier | Il s'agit d'un tableau associatif qui permet d'identifier la route api et ws. | $this->identify=['api'=>'apiurl','ws'=>'webservices','controller'=>'']; | |
$isPostBack | c'est vrai si la page est POST, sinon faux. | if ($this->isPostBack) { ... } ; | |
$verbe | {verbe} | Le verbe actuel, cela pourrait être GET, POST, PUT et DELETE. | if ($this->verb) { ... }; |
Exemple:
$ this -> addPath ( ' portal/web/{controller}/{action:list} ' );
$ this -> fetchPath ();
var_dump ( $ this -action); // it shows the current action or the default value "list" if none.
Champ | Description | Exemple |
---|---|---|
$allowedVerbes | Une liste de verbes autorisés | $this->allowedVerbs=['GET', 'POST', 'PUT', 'DELETE']; |
$allowedFields | Une liste avec les champs autorisés utilisés par callObjectEx() | $this->allowedFields=['controller', 'action', 'verb', 'event', 'type', 'module', 'id' , 'idparent', 'catégorie', 'sous-catégorie', 'sous-sous-catégorie']; |
setWhitelist() | Il définit un tableau associatif avec la liste blanche sur contrôleur , action , catégorie , sous-catégorie , sous-sous-catégorie et module . S'il n'est pas défini (valeur par défaut nulle), il autorise toute entrée. Actuellement, cela ne fonctionne qu'avec le contrôleur et la catégorie | $this->setWhitelist('contrôleur','Achat','Facture','Client'); $this->setWhitelist('controller',null) // autorise n'importe quel contrôleur ; |
Mettre une méthode sur liste blanche permet deux opérations :
Par exemple:
// Example, value not in the whitelist: someweb.dom/customer/list
$ this -> setWhiteList ( ' controller ' ,[ ' Product ' , ' Client ' ]);
$ this -> fetch ();
var_dump ( $ this -> controller ); // null or the default value
var_dump ( $ this -> notAllowed ); // true (whitelist error)
// Example, value in the whitelist but with the wrong case: someweb.dom/customer/list
$ this -> setWhiteList ( ' controller ' ,[ ' Customer ' ]);
$ this -> fetch ();
var_dump ( $ this -> controller ); // it shows "Customer" instead of "customer"
var_dump ( $ this -> notAllowed ); // false (not error with the validation of the whitelist)
// reset whitelist for controllers
$ this -> setWhiteList ( ' controller ' , null );
RouteOne contient une CLI de base pour créer et initialiser la configuration. Le binaire RouteOne cli se trouve dans le dossier supplier/bin
./vendor/bin/ RouteOne cli
entrez dans le routeur et appuyez sur Entrée.
Dans le menu du routeur, l'écran suivant s'affichera :
En attente signifie que l'opération est en attente d'exécution ou qu'elle nécessite quelque chose à configurer.
Une fois terminé, la configuration sera marquée comme "ok"
Maintenant, configurons les chemins