我想在我的项目中使用 postLoad
方法使用侦听器,但出现错误
[TypeError] App\Company\Infrastructure\Persistence\ORM\EventListener\LoadLicensesListener::postLoad(): Argument #1 ($args) must be of type Do
ctrine\ORM\Event\LifecycleEventArgs, App\Company\Domain\Entity\Company given, called in D:\OpenServer\domains\project\vendor\doctrine\orm\lib\Doc
trine\ORM\Event\ListenersInvoker.php on line 108
我的听众
use Doctrine\ORM\Event\LifecycleEventArgs;
final class LoadLicensesListener
{
/**
* @param LifecycleEventArgs $args
*/
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if (!$entity instanceof Copmany) {
// Something to do
$licenses = $entity->relatedLicenses;
$entity->initializeObject($licenses);
}
}
}
我在 Company.orm.xml
<entity-listeners>
<entity-listener class="App\Company\Infrastructure\Persistence\ORM\EventListener\LoadLicensesListener">
<lifecycle-callback type="postLoad" method="postLoad"/>
</entity-listener>
</entity-listeners>
services.yml
App\Company\Infrastructure\Persistence\ORM\EventListener\LoadLicensesListener:
tags:
- { name: doctrine.event_listener, event: postLoad, connection: default }
我哪里做错了?也许我误解了文档 - Symfony Events 或 Doctrine Events
或者我应该在 services.yml
中做一些事情,因为我已经用 EventListeners 更改了一个文件夹?
"doctrine/orm": "2.8.4"
答案 0 :(得分:1)
Doctrine 提供了不同类型的侦听器,“默认”事件侦听器和实体侦听器,这里您在文件 Company.orm.xml
中注册了一个实体侦听器,并为同一类注册了一个“默认”事件侦听器。
选择您想要的侦听器类型并根据文档进行注册。
如果您选择实体侦听器,则第一个参数将是实体本身,这就是您收到此错误的原因。
答案 1 :(得分:1)
我会说你好像配置错了。
尝试在您的 Campany.php 中内部实现 postLoad
方法(注意!没有任何参数)并查看它的输出。
class Company {
// ...
public function postLoad() {
dump(__METHOD__);
}
}
也看看这个https://symfony.com/doc/4.1/doctrine/event_listeners_subscribers.html和这个https://symfony.com/doc/current/bundles/DoctrineBundle/entity-listeners.html
不幸的是,我不熟悉 xml
-configs,所以我无法发现任何可疑之处。
一如既往,有几种方法可以完成它:
Doctrine\Common\EventSubscriber
的 getSubscribedEvents
- 更高级和灵活。一种逻辑可以应用于多个实体这里是 symfony 4.4 和学说 2.7 的例子:
/**
* @ORM\Entity()
* @ORM\Table(name="company")
* @ORM\HasLifecycleCallbacks
*/
class Company {
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
// ... props and methods
/**
* @ORM\PostLoad()
*/
public function doStuffAfterLoading(): void
{
// yor logic
// you can work with $this as usual
// no-return values!
// dump(__METHOD__);
}
}
有了这些注释,services.yml|xml
中不需要额外的条目
use App\Entity\Company;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Events;
final class PostLoadSubscriber implements EventSubscriber {
public functuin __construct()
{
// you can inject some additional services if you need to
// e.g. EntityManager
}
public function getSubscribedEvents()
{
return [
Events::postLoad,
];
}
public function postLoad(LifecycleEventArgs $args)
{
// check if it's right entity and do your stuff
$entity = $args->getObject();
if ($entity instanceof Company) {
// magic...
}
}
}
您需要将此 PostLoadSubscriber
注册为 services.yaml|xml
中的服务