Hello and thank you for clicking on this article 😁
Today we're going to talk about experimental code that I've been interested in recently. To contextualize, I finished a PHP course for a promo I had as a trainer.
Once we'd seen the basics and got to the end of the program, we naturally moved on to the MVC and object-oriented aspects of implementing a project in native PHP.
It was at this point that I asked myself the question of how to implement a router in a project of this type, inspired by Symfony. 😉
First of all, we need to keep in mind the basic operation: a list of routes, i.e. urls that will redirect us to a method. These methods can then be found in a class corresponding to a controller for our actions.
To list our routes, we can easily use a simple array in PHP :
Here, the prefix is necessary when using a local server such as Wamp, MAMP, ... because your projects are located in a subfolder such as "www/projet-symfony/". 😊
Now let's get to the heart of the matter: creating a class that can interpret a URL, match it to the specified controller and trigger the associated method.
We also find our array of routes passed in the constructor, so we can check whether each url reached corresponds to one of our written methods.
You'll notice that I'm using namespace here for greater clarity and also to continue writing a router inspired by Symfony. To make them available, you'll need to initialize Composer in your project
then define the PSR rule
From here on in, with the right configuration of your Apache or Nginx web server, your URLs should trigger the methods of your defined Controllers. So we've got functional routing! 😛
"Ok it works fine but I'm used to writing my routes in YAML in my Symfony projects and not in PHP!"
No problem, just create a routes.yaml file and define the same thing as in our PHP file.
Then we'll need to add a method to our router to be able to read this file and convert it into an array. PHP can't interpret YAML directly.
"Well ok that's fine too, but since PHP 8 and therefore the latest versions of Symfony we've also been using attributes to define routes. Can we do that with your router here?"
Yes! It's just as doable with a few additional manipulations.
The idea here is to add a registerRoutes method that will go directly to the existing Controllers to retrieve the information contained in the PHP attributes. We can then once again create an array of routes with the information described above.
On the Controller side, as in Symfony, we write Route attributes directly to the associated methods.
You can now delete your old routes.php and routes.yaml files or rename them to .old and you'll see that your router still works thanks to these attributes. 😛
So now we have a perfectly functional routing system, very much inspired by Symfony. It's not 100% the same, but it won't confuse any developer familiar with Symfony and doesn't require any additional configuration once in place.
I've done this experiment mainly for teaching purposes, as the question came to me as a result of my course, but if you're working on an "in-house" framework, this could be useful.
In any case, here's the Github repo and don't hesitate to let me know if you actually use it! 😊
On that note, I'll see you soon for new adventures 🚗 !