Commentaires
king saozer
06/04/2022 à 20:51
Honnêtement, je crois qu'il faut aller plus lentement que ça. On a besoin de bien assimiler. depuis je ne sais pas dans quel dossier créer les fichiers, sauf le fichier Route.json que je viens de découvrir dans la fonction file_get_contents
Aurélien Vaast
09/08/2020 à 16:59
Bonjour, déjà il faut bien faire attention au fichier .htaccess, si ton projet n'est pas à la racine du serveur web, il faut préciser le dossier dans le FallbackResource /[dossier]/index.php Ensuite, il suffit d'utiliser des regex dans le path de la route, le routeur va la traiter avec un preg_match donc ([0-9]*) pour un identifiant devrais fonctionner.
thomas da silva
04/08/2020 à 14:13
Bonjour, je viens d'essayer de mettre en place votre routeur en poo sauf que seul la route principale(page d'accueil) s'ouvre correctement et les autres pages raffiche la page d'accueil. Dans le document .json quand je var_dump la route de la page des posts par exemple il ne la trouve pas. Savez vous ou le probleme provient? je peux vous envoyer mon github si vous voulez.

Le concept


Maintenant, il faut que l'on puisse trouver la route qui correspond à une requête Http. Tu va donc construire une classe Router, elle doit posséder :

  • Une propriété listRoute

  • Un constructeur pour


    • Charger les fichiers de route json, tu peux utiliser la fonction file_get_contents

    • Transformer le fichier en objet et les mettre dans la propriété listRoutes. tu peux utiliser la fonction json_decode


  • Une méthode findRoute, qui


    • Prend en paramètre un objet HttpRequest

    • Recherche la ou les routes associées à cette requête http, la fonction array_filter sera très utile

    • Retourne un objet route construit à partir de la route trouvée

    • ou
    • Retourne une erreur si aucune route, ou plusieurs routes ont été trouvées




la classe Router


Charger le fichier de routes


Arthur, l'apprenti développeurJe vais essayer de faire ça

{"language":"application/x-httpd-php","content":"<?php\n\tclass Router\n\t{\n\t\tprivate $listRoute;\n\t\t\n\t\tpublic function __construct()\n\t\t{\n\t\t\t$stringRoute = file_get_contents('Config/route.json');\n\t\t\t$this->listRoute = json_decode($stringRoute);\n\t\t}\n\t\t\n\t\tpublic function findRoute($httpRequest)\n\t\t{\n\t\t\t$routeFound = array_filter($this->listRoute,function($route){\n\t\t\t\t\"\";\n\t\t\t});\n\t\t}\n\t}","filename":"Router.php"}


Arthur, l'apprenti développeurJe pense que je n'en suis pas loin, mais je ne comprend pas comment utiliser la fonction array_filter.

Effectivement, il ne manque pas grand chose. Pour t'expliquer simplement, la fonction va parcourir le tableau, et il faut retourner une opération booléenne (une instruction qui retourne true ou false), si la condition retourne true, alors l'élément est conservé, si elle retourne false, il est écarté. La fonction retournera donc un tableau, dans lequel tout les éléments répondant à la condition seront présent.

Un petit détail en plus, en définissant cette fonction anonyme à l'intérieur du array_filter, tu définit une nouvelle portée, dans laquelle le paramètre httpRequest n'existera pas. Pour pouvoir utiliser une variable à l’intérieur de cette portée il faut le lui préciser avec le mot clé "use" de la façon suivante :

{"language":"application/x-httpd-php","content":"<?php\n\tarray_filter($array, function($element) use ($variable){\n\t\t\n\t});","filename":"exemple"}


Filtrer les routes


Arthur, l'apprenti développeurD'accord je vois ce qu'il faut faire alors !

{"language":"application/x-httpd-php","content":"<?php\n\tclass Router\n\t{\n\t\tprivate $listRoute;\n\t\t\n\t\tpublic function __construct()\n\t\t{\n\t\t\t$stringRoute = file_get_contents('Config/route.json');\n\t\t\t$this->listRoute = json_decode($stringRoute);\n\t\t}\n\t\t\n\t\tpublic function findRoute($httpRequest)\n\t\t{\n\t\t\t$routeFound = array_filter($this->listRoute,function($route) use ($httpRequest){\n\t\t\t\treturn $route->path == $httpRequest->getUrl();\n\t\t\t});\n\t\t\t$numberRoute = count($routeFound);\n\t\t\tif($numberRoute > 1 || $numberRoute == 0)\n\t\t\t{\n\t\t\t\treturn \"Error\";\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new Route($routeFound);\t\n\t\t\t}\n\t\t}\n\t}","filename":"Router.php"}


C'est presque ça, il y a juste quelques petits détails que je ne t'ai peut être pas bien précisé. Pour ce qui est de la comparaison de chemin, nous auront par la suite des cas particulier de route avec paramètre dans l'url. Par exemple pour l'affichage d'un article, on pourrait avoir la route "/Article/5" et bien entendu, le 5 peux varier, mais on ne va pas ajouter une nouvelle route pour chaque identifiant en base non plus.

Pour cela, on utilisera des expressions régulières dans le fichier de route, et il faut donc ici, utiliser une fonction qui vérifie une expression régulière, regarde preg_match dans la documentation php.

Gérer les méthodes http et les erreurs


D'autre part, je te rappelle que l'on peut avoir plusieurs fois le même chemin de route, mais avec des méthodes http différentes, il faut donc aussi comparer les méthodes.

Pour rappel, la variable routeFound est un tableau, même s'il ne contiens qu'une route, il faut lui envoyer l'objet en question, et non pas le tableau qui contient cet objet. Tu peux utiliser la fonction array_shift.

Enfin, concernant l'erreur, retourner une chaîne va nous compliquer le travail, il faudra alors vérifier à chaque appel de la méthode findroute si le retour n'est pas une erreur, et en plus de cela, tu n'auras aucun moyen de savoir quelle erreur exactement. Je te propose d'utiliser à la place des exceptions personnalisées, pour arrêter l'execution d'un code et remonter une exception il suffit de faire :

{"language":"application/x-httpd-php","content":"<?php\n\tfunction Exemple(){\n\t\tif($erreur)\n\t\t{\n\t\t\tthrow new MyCustomException();\t\n\t\t}\n\t}","filename":"exemple"}


Je te propose d'utiliser deux exceptions : NoRouteFoundException et MultipleRouteFoundException.

{"language":"application/x-httpd-php","content":"<?php\n\tclass Router\n\t{\n\t\tprivate $listRoute;\n\t\t\n\t\tpublic function __construct()\n\t\t{\n\t\t\t$stringRoute = file_get_contents('Config/route.json');\n\t\t\t$this->listRoute = json_decode($stringRoute);\n\t\t}\n\t\t\n\t\tpublic function findRoute($httpRequest)\n\t\t{\n\t\t\t$routeFound = array_filter($this->listRoute,function($route) use ($httpRequest){\n\t\t\t\treturn preg_match(\"#^\" . $route->path . \"$#\", $httpRequest->getUrl()) && $route->method == $httpRequest->getMethod();\n\t\t\t});\n\t\t\t$numberRoute = count($routeFound);\n\t\t\tif($numberRoute > 1)\n\t\t\t{\n\t\t\t\tthrow new MultipleRouteFoundException();\n\t\t\t}\n\t\t\telse if($numberRoute == 0)\n\t\t\t{\n\t\t\t\tthrow new NoRouteFoundException();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new Route(array_shift($routeFound));\t\n\t\t\t}\n\t\t}\n\t}","filename":"Router.php"}


Arthur, l'apprenti développeurOk cette fois c'est bon ! J'ai juste un doute, les deux exceptions n'existent pas dans Php, ça ne va pas poser de problème?

Effectivement, ça ne pourra pas fonctionner comme ça, on va donc les créer ! J'ai terminé cette partie
Demander de l'assistance