LifecycleEventArgs 参数的学说错误

时间:2021-05-04 03:58:59

标签: symfony doctrine-orm

我想在我的项目中使用 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 EventsDoctrine Events 或者我应该在 services.yml 中做一些事情,因为我已经用 EventListeners 更改了一个文件夹? "doctrine/orm": "2.8.4"

2 个答案:

答案 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,所以我无法发现任何可疑之处。

一如既往,有几种方法可以完成它:

  • simple EntityLifeCycles (docs) - 对于基本的东西很有用,如果你不依赖额外的服务来完成这个特定的任务。逻辑仅适用于该特定实体。
  • 带有 Doctrine\Common\EventSubscribergetSubscribedEvents - 更高级和灵活。一种逻辑可以应用于多个实体
  • 一个事件监听器。

这里是 symfony 4.4 和学说 2.7 的例子:

  1. 实体生命周期:

/**
 * @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 中不需要额外的条目

    • Subscriber - 对一个或多个实体应用相同的逻辑
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 中的服务

相关问题