这个例子向我们展示了我们如何为constollers及其方法创建一个自定义注解。我们将创建的注解叫做@Model ,它有三个属性,如下所示。
注释类
declare(strict_types=1);
namespace App\Annotation;
/**
* @Annotation
*/
class Model
{
/**
* @var string
*/
public $namespace;
/**
* @var int
*/
public $version;
/**
* @var array
*/
public $types;
}
模型类
这是可选的:
declare(strict_types=1);
namespace App\Model;
class Country
{
// Whatever
}
控制器
declare(strict_types=1);
namespace App\Controller;
use App\Annotation\Model;
...
/**
* @Route("/countries")
* @Model
*/
class CountryController
{
/**
* @Route(....)
* @Model(
* namespace="App\Model\Country",
* version=1,
* types={"json","xml"}
* )
*/
public function getAll(): Response
{
// ...
}
}
ModelAnnotationListener
declare(strict_types=1);
namespace App\Event\Listener;
use App\Annotation\Model as ModelAnnotation;
use Doctrine\Common\Annotations\Reader;
use ReflectionClass;
use ReflectionException;
use RuntimeException;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
class ModelAnnotationListener
{
private $annotationReader;
public function __construct(Reader $annotationReader)
{
$this->annotationReader = $annotationReader;
}
public function onKernelController(FilterControllerEvent $event): void
{
if (!$event->isMasterRequest()) {
return;
}
$controllers = $event->getController();
if (!is_array($controllers)) {
return;
}
$this->handleAnnotation($controllers);
}
private function handleAnnotation(iterable $controllers): void
{
list($controller, $method) = $controllers;
try {
$controller = new ReflectionClass($controller);
} catch (ReflectionException $e) {
throw new RuntimeException('Failed to read annotation!');
}
$this->handleClassAnnotation($controller);
$this->handleMethodAnnotation($controller, $method);
}
private function handleClassAnnotation(ReflectionClass $controller): void
{
$annotation = $this->annotationReader->getClassAnnotation($controller, ModelAnnotation::class);
if ($annotation instanceof ModelAnnotation) {
print_r($annotation);
}
}
private function handleMethodAnnotation(ReflectionClass $controller, string $method): void
{
$method = $controller->getMethod($method);
$annotation = $this->annotationReader->getMethodAnnotation($method, ModelAnnotation::class);
if ($annotation instanceof ModelAnnotation) {
print_r($annotation);
}
}
}
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\Event\:
resource: '../../src/Event'
App\Event\Listener\ModelAnnotationListener:
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
结果
App\Annotation\Model Object
(
[namespace] =>
[version] =>
[types] =>
)
App\Annotation\Model Object
(
[namespace] => App\Model\Country
[version] => 1
[types] => Array
(
[0] => json
[1] => xml
)
)