
Hi folks!!! I always ear php haters talk about a language I do not know. They do not know the language they are talking about. And to show them a little example of what php8 is able to do, I've create a simple exercice: a php router with php attributes.
Createpublic
folder. I mean, .. a folder called "public". Then create anindex.php
file inside. And follow the steps in this article.
The attribute
First of all, ... you can create a php class Route. the attributes is simple the#[Attribute]
. Attribute syntax starts from#[
and finisci with]
. You can "mark" a class, a method, a property, .... with attributes.
#[Attribute]classRoute{publicfunction__construct(privatestring$method='GET',privatestring$path='/',){}}
A Response class
This is useless for the purpose of this post, but I've made a little video (in italian). And I've just copied and pasted the code here. This object aims to decorate the json for a generic response, with some links. It make easy website navigation at the end of the post.
classResponse{publicfunction__construct(privatearray$json=[]){}publicfunctiongetContent(){returnjson_encode(array_merge($this->json,['@link'=>['http://localhost:8888/','http://localhost:8888/info','http://localhost:8888/conclusions',]]));}}
Handler interface
In some framework we call them controllers. Here I just named them Handler. The point is that each route will call its own handler.
interfaceHandler{publicfunctionhandle():Response;}
The concrete handlers
Now you can create some handlers, and att an attribute to them. Note that someone known annotations. Annotations was just a DocBlock comment. PHP attributes are structured and readable by the interpreter. You can obtain a class attribute using reflection.
#[Route('GET', '/')]classHomeContollerimplementsHandler{publicfunctionhandle():Response{returnnewResponse(['page'=>'home']);}}#[Route('GET', '/info')]classInfoControllerimplementsHandler{publicfunctionhandle():Response{returnnewResponse(['page'=>'info']);}}
Configuration
I've also made a little configuration file: a list of handler, .. controller, .. call them as you like. Doesnt matter.
$routes=[HomeContoller::class,InfoController::class,];
Reading attributes
Here I've create a function. The function read an array of handlers/controllers. For each handlers/controllers get a reflection instance, get attributes from the instance. Attributes (Route) indicate the http method and the path. If the route corresponds to the handler one, then handle the handler.
functionrouter(array$routes):Response{foreach($routesas$handler){$reflection=newReflectionClass($handler);$attributes=$reflection->getAttributes(Route::class);foreach($attributesas$attribute){if($attribute->getArguments()[0]===$_SERVER['REQUEST_METHOD']){if($attribute->getArguments()[1]===$_SERVER['REQUEST_URI']){return(new$handler)->handle();}}}}}$response=router($routes);echo$response->getContent();
Run built-in serve
Now You have your amazing router. You can try it. Just run
php -S localhost:8888 -t public
And see it working.
Conclusions
The conclusion is that php is amazing. A lot of people do not know it. all of them know php3, maybe. Once I heard someone say: "wow, .. php have also classes". So, .. LOL.
Well, .. add a new controller:
#[Route('GET', '/conclusions')]classConclusionsControllerimplementsHandler{publicfunctionhandle():Response{returnnewResponse(['message'=>'If you like this post, ... leave a like','and'=>'and follow me for more post like this',]);}}
Then update also the configuration:
$routes=[HomeContoller::class,InfoController::class,ConclusionsController::class,];
And if you speak italian you can seemy video on youtub
Top comments(4)

Did you have a github repository with this sample?

Yes!! You can see the codehere. Is not on packagist. I've made it at exercice to start to show the way I like to apply tests in a legacy code. Actually the code you can see could be quite different because even if the related video is scheduled, .. the generated code is visible on github right now. In next videos I want also to show how to do a pull request and/or make issues. Feel free to contribute, .. or not ^_^
For further actions, you may consider blocking this person and/orreporting abuse