Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for I made a php router with attributes
Simone Gentili
Simone Gentili

Posted on

     

I made a php router with attributes

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='/',){}}
Enter fullscreen modeExit fullscreen mode

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',]]));}}
Enter fullscreen modeExit fullscreen mode

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;}
Enter fullscreen modeExit fullscreen mode

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']);}}
Enter fullscreen modeExit fullscreen mode

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,];
Enter fullscreen modeExit fullscreen mode

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();
Enter fullscreen modeExit fullscreen mode

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',]);}}
Enter fullscreen modeExit fullscreen mode

Then update also the configuration:

$routes=[HomeContoller::class,InfoController::class,ConclusionsController::class,];
Enter fullscreen modeExit fullscreen mode

And if you speak italian you can seemy video on youtub

Top comments(4)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
matheuseduardo profile image
Matheus Eduardo Silva Guimarães
  • Location
    Florianópolis, Brasil
  • Joined

Did you have a github repository with this sample?

CollapseExpand
 
sensorario profile image
Simone Gentili
Father
  • Work
    Software Developer @ radical storage
  • Joined
• Edited on• Edited

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 ^_^

CollapseExpand
 
yura712 profile image
Yura
  • Location
    Belarus, Minsk
  • Work
    Full-stack developer at Fabros
  • Joined

Great article! Thank for pushing PHP forward!

CollapseExpand
 
sensorario profile image
Simone Gentili
Father
  • Work
    Software Developer @ radical storage
  • Joined

Have you seen my automatic dependency injection's article?

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Father
  • Work
    Software Developer @ radical storage
  • Joined

More fromSimone Gentili

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp