[英]How to inherit custom Doctrine class annotation in Symfony?
我创建了一个自定义@TimestampAware
注释,可用于在持久化或更新我的实体时自动更新时间戳属性(请参阅下面的代码)。
当直接在实体类上使用此注释时,一切正常。 但是,在基类上使用注释时,在继承的子类上无法识别。
/**
* @TimestampAware
*/
class SomeEntity { ... } // works fine
/**
* @TimestampAware
*/
class BaseEntity { ... }
class SubEntity extends BaseEntity { ... } // Annotation is not recognized
Doctrine 注释和 Annotation Reader 类的预期行为是直接在当前类上查找注释而不包括其父类吗? 还是我的实现有问题?
我的注释:
use Doctrine\Common\Annotations\Annotation;
use Doctrine\Common\Annotations\Reader;
/**
* @Annotation
* @Target("CLASS")
*/
final class TimestampAware { }
注释侦听器:
use Doctrine\Common\EventSubscriber;
class TimestampAwareSubscriber implements EventSubscriber {
protected $reader;
protected $logger;
public function __construct(Reader $reader, LoggerInterface $logger) {
$this->reader = $reader;
$this->logger = $logger;
}
public function getSubscribedEvents() {
return [
Events::prePersist,
Events::preUpdate,
];
}
public function prePersist(LifecycleEventArgs $args) {
$this->onPersistOrUpdate($args);
}
public function preUpdate(LifecycleEventArgs $args) {
$this->onPersistOrUpdate($args);
}
protected function onPersistOrUpdate(LifecycleEventArgs $args) {
$this->logger->info("Reader: ".get_class($this->reader));
$entity = $args->getEntity();
$reflection = new \ReflectionClass($entity);
$timestampAware = $this->reader->getClassAnnotation(
$reflection,
TimestampAware::class
);
if (!$timestampAware) {
return;
}
// update timestamp...
}
}
Annotation Reader 只检查相关类,它不读取父类的注释。 这可以使用如下代码轻松检查:
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
AnnotationRegistry::registerLoader('class_exists');
/**
* @Annotation
* @Target("CLASS")
*/
class Annotated {}
/**
* @Annotated
**/
class ParentFoo {}
class ChildFoo extends ParentFoo {}
$reader = new AnnotationReader();
$parentAnnotated = $reader->getClassAnnotation(
new ReflectionClass(ParentFoo::class),
Annotated::class
);
var_dump($parentAnnotated);
// Outputs `object(Annotated)#10 (0) {}`
$childAnnotated = $reader->getClassAnnotation(
new ReflectionClass(ChildFoo::class),
Annotated::class
);
var_dump($childAnnotated);
// outputs `null`
如果你想检查父类,你必须自己做。 ReflectionClass
提供了getParentClass()
方法,您可以用它来检查类层次结构。
顺便说一句,我发现这个包声称可以扩展注释,以便它们可以直接与继承一起使用。 没看好不好
除了@yivi 的精彩回答之外,我还想分享我用来解决问题的代码。 也许这有助于其他人如何遇到同样的问题:
protected function onPersistOrUpdate(LifecycleEventArgs $args) {
$this->logger->info("Reader: ".get_class($this->reader));
$entity = $args->getEntity();
$reflection = new \ReflectionClass($entity);
$timestampAware = $this->reader->getClassAnnotation(
$reflection,
TimestampAware::class
);
while (!$timestampAware && $reflection = $reflection->getParentClass()) {
$timestampAware = $this->reader->getClassAnnotation(
$reflection,
TimestampLogAware::class
);
}
if (!$timestampAware) {
return;
}
// update timestamp...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.