如何读取 php 8 中的 class 方法属性?

How to read class methods attributes in php 8?

假设我有以下属性声明

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

我在一些控制器方法中使用它,如下所示:

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

如何获取这些属性实例并读取其属性?

你可以使用原生 php reflection api.

首先,您必须检索所需的方法反射。 在下面的示例中,我将检索所有 public 方法:

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

这将 return 一个包含所有 public 方法反射的数组。

然后,要读取它并检索那些 Route 个实例,只需遍历它并使用“newInstance()”属性反射方法即可。像这样:

foreach ($methods as $method) {
    $reflectionMethod = new ReflectionMethod(Controller::class, $method->getName());
    
    $attributes = $reflectionMethod->getAttributes(Route::class);

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

这将输出:

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
}

这是完整工作示例的要点: https://gist.github.com/carloscarucce/fce40cb3299dd69957db001c21422b04