【问题标题】:Lifecycle callbacks not working生命周期回调不起作用
【发布时间】:2018-03-17 16:47:08
【问题描述】:

我目前正在试用 Symfony 4,但我遇到了一些由数据库操作触发的事件(prePersist、preUpdate...)

在 Symfony 3 中,我曾经使用 EntityListener 来完成此任务,但我发现它们在 Symfony 4 文档中确实令人费解。但我也发现了 LifecycleCallbacks,我是这样使用的:

/**
* @ORM\Entity(repositoryClass="App\Repository\PostRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Post
{
     //Attributes and other functions not included for the sake of clarity, but if I use them, consider that they exist
     /**
     * @ORM\PrePersist
     */ 
    public function setPostSlug()
    {
         $title = $this->getPostTitle();
         $title = strtolower($title);

         $keywords = preg_split("/[\s,']+/", $title);
         $slug = implode('-', $keywords);

         dump($slug);

         $this->$slug = $slug;

         return $this;
     }
}

我的帖子是通过 Symfony 表单创建的,在持久化之前,我想将我给帖子的标题分解为一个标准化的字符串,我将在我的 URL 中使用它来访问所述帖子。不幸的是,尽管正确生成了 slug,但该事件永远不会触发持久性。我尝试对 prePersist 和 postPersist 事件进行操作,但都没有成功。我搜索了这个问题,发现 LifecycleCallbacks 需要考虑缓存清除,但这样做没有帮助。

以下是负责创建帖子的操作,如果可能有帮助的话:

/**
 * @Route("/admin/create/post", name="admin-create-post")
 * @param Request $request
 */
public function createPost(Request $request)
{
    $post = new Post();

    $form = $this->createForm(PostType::class, $post);
    $form->handleRequest($request);

    if($form->isSubmitted() && $form->isValid()){
        $em = $this->getDoctrine()->getManager();
        $post = $form->getData();
        $em->persist($post);
        $em->flush();
        $this->redirectToRoute('main');
    }

    return $this->render('admin/new_post.html.twig', array(
        'form' => $form->createView()
    ));
}

您是否知道问题的根源,或者我可以使用哪些其他工具来获得所需的结果?

提前致谢。

【问题讨论】:

  • 它应该以相同的方式工作,您是否在注释或 yaml/xml 中有实体定义?
  • @kuba_ceg 我使用注释来管理所有内容,您可以在帖子类的顶部看到

标签: symfony doctrine-orm doctrine symfony4


【解决方案1】:

我使用 EventListener 处理复杂的生命周期 为此.. 做:

# services.yml

AppBundle\EventListener\YourListener:
    tags:
        - { name: doctrine.event_listener, event: prePersist }

// YourListener.php
namespace AppBundle\EventListener;

class YourListener {
     /**
      * @param LifecycleEventArgs $args
      */
      public function prePersist(LifecycleEventArgs $args): void
      {
          $post = $args->getEntity();

          if ($post instanceof Post) {
             // Do your job
          }
      }
}

但是我像这样使用 symfony EventListenerSubscriber:

    /**
 * This needs to be set through passed argument in case of accident duplicate
 *
 * @ORM\PrePersist()
 */
public function setTrackingNumber()
{
    $this->trackingNumber = NumberCreator::randomStringWithNDigits(self::TRACKING_DIGIT_COUNT);
}

所以我认为你需要像这样在你的 slug setter 中这样做

 /**
 * @ORM\PrePersist
 */ 
public function setSlug()
{
     $title = $this->getPostTitle();
     $title = strtolower($title);

     $keywords = preg_split("/[\s,']+/", $title);
     $slug = implode('-', $keywords);

     dump($slug);

     $this->$slug = $slug;

     return $this;
 }

我认为方法名称有问题...希望对您有所帮助

【讨论】:

  • 好的,我会尝试一下,但是 Symfony 文档中使用的 EventListenerSubscriber 呢?没用吗?
  • @Meleadeles 不,当然不是,我编辑答案,看看那个。
  • @Meleadeles 但请注意这个问题,我认为在第一次坚持后这是工作......当你想用新标题更新你的帖子......像以前的标题一样,我'不确定,但我认为。
  • 好的,方法名称似乎是问题所在,我将其更改为 createSlug,并重新引入了正常的 setter,它工作正常。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-30
  • 2013-05-04
  • 1970-01-01
  • 1970-01-01
  • 2023-01-29
  • 1970-01-01
相关资源
最近更新 更多