6

Lets say I have the following attribute declaration

#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
class Route
{   
    public function __construct(
        public string $path,
        public ?string $method = null,
        public ?string $alias = null
    )
    {}
}

and I use it in some controller methods like so:

class Controller
{
    #[Route('/index/')]
    #[Route('/home/', alias: 'home')]
    public function index()
    {
        ...
    }
    
    #[Route('/create/', 'POST')]
    public function create(Request $request)
    {
        //...
    }
}

How could I obtain those attribute instances and read it's properties?

2
  • 1
    The manual has some example. Commented Mar 27, 2021 at 8:55
  • @MagnusEriksson of course. I just made a little research and put together information about usage + reflection reading in a practical way for those people who use to search here in SO. Commented Mar 27, 2021 at 13:28

1 Answer 1

12

You can do it by using native php reflection api.

First, you will have to retrieve the desired methods reflection. In the example bellow, I will retrieve all public methods:

$reflectionClass = new ReflectionClass(Controller::class);
$methods = $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC);

This will return an array containing all public methods reflection.

Then, to read it and retrieve those Route instances, simply loop through it and use "newInstance()" attribute reflection method. Like so:

foreach ($methods as $method) {     
    $attributes = $method->getAttributes(Route::class);

    echo "reflecting method '", $method->getName(), "'\r\n";
    foreach ($attributes as $attribute) {
       var_dump($attribute->newInstance());
    }
}

This will output:

reflecting method 'index'
object(Route)#8 (3) {
  ["path"]=>
  string(7) "/index/"
  ["method"]=>
  NULL
  ["alias"]=>
  NULL
}
object(Route)#8 (3) {
  ["path"]=>
  string(6) "/home/"
  ["method"]=>
  NULL
  ["alias"]=>
  string(4) "home"
}

reflecting method 'create'
object(Route)#7 (3) {
  ["path"]=>
  string(8) "/create/"
  ["method"]=>
  string(4) "POST"
  ["alias"]=>
  NULL
}

Here is the gist with the full working example: https://gist.github.com/carloscarucce/fce40cb3299dd69957db001c21422b04

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.