【问题标题】:symfony2: inserting data using eventListenersymfony2:使用 eventListener 插入数据
【发布时间】:2025-12-14 08:10:01
【问题描述】:

我正在使用 symfony 2.3。我试图在每个月底为每个广告生成一张发票。为此,我实现了一个名为 InvoiceListener 的侦听器。问题是 updateInvoice() 函数没有将数据插入到发票表中。系统不会呈现错误。正确显示查询的教义调试器。
InvoiceListener.php

class InvoiceListener {

  private $em;

  public function __construct(\Doctrine\ORM\EntityManager $em) {
      $this->em = $em;
  }

  public function process(GetResponseEvent $event) {

      $expire = '2012-01-01';
      $current_month = date("m");
      $current_year = date("y");
      if (date("d") == 1) {
          echo 'first day';
          $this->updateStatus($current_month, $current_year);
          $this->updateInvoice();
      } else {
          echo 'not first day';
          $users = $this->findByRole('ROLE_COMMERCIAL');
          // update invoice
          $this->updateInvoice($users);
      }
  }

  public function updateStatus($current_month, $current_year) {
      $queryBuilder = $this->em->createQueryBuilder();
      $queryBuilder
              ->update('Biginfo\UserBundle\Entity\User', 'u')
              ->set('u.nbrBusiness', 1)
              ->set('u.month', $current_month)
              ->set('u.year', $current_year);
      return $queryBuilder->getQuery()->getResult();
  }

  public function updateInvoice($users) {
      $queryBuilder = $this->em->createQueryBuilder();
      foreach ($users as $user) {
          $queryBuilder
                  ->update('Biginfo\AdminBundle\Entity\Invoice', 'c')
                  ->set('c.commercial', $user->getId())
                  ->set('c.month', $user->getMonth())
                  ->set('c.year', $user->getYear())
                  ->set('c.nbrBusiness', $user->getNbrBusiness());
      }
      return $queryBuilder->getQuery()->getResult();
  }

  /**
   * @param string $role
   *
   * @return array
   */
  public function findByRole($role) {
      $qb = $this->em->createQueryBuilder();
      $qb->select('u')
              ->from('Biginfo\UserBundle\Entity\User', 'u')
              ->where('u.roles LIKE :roles')
              ->setParameter('roles', '%"' . $role . '"%');

      return $qb->getQuery()->getResult();
  }

}

【问题讨论】:

  • "...我正在尝试在每个月底为每个广告生成发票..." - 听起来您需要 Console Command 而不是用 cronjob 调用它。
  • 我同意@BentCoder。对此使用监听器是一种矫枉过正的做法。
  • 也同意@BentCoder,应该使用控制台
  • @BentCoder 你有关于 conjobs 的教程吗?我是新手。

标签: symfony doctrine-orm symfony-2.3


【解决方案1】:

除非我遗漏了什么,否则您的代码只会一次又一次地更新相同的记录,我认为这不是您想要的。要生成新发票,您应该这样更改:

public function updateInvoice($users) {
    $queryBuilder = $this->em->createQueryBuilder();
    $queryBuilder->insert('Biginfo\AdminBundle\Entity\Invoice', 'c');
    foreach ($users as $user) {
        $queryBuilder->values(array(
            'c.commercial' => $user->getId(),
            'c.month' => $user->getMonth(),
            'c.year'=> $user->getYear(),
            'c.nbrBusiness' => $user->getNbrBusiness()
        ))
    }
    return $queryBuilder->getQuery()->getResult();
}

附:您还应该使用占位符,请参阅http://doctrine-dbal.readthedocs.org/en/latest/reference/query-builder.html#binding-parameters-to-placeholders

编辑:“插入”命令

“插入”命令has been added in Doctrine 2.5.0 BETA 3,因此它可能在 Symfony 2.3 中不可用。另一种方法是使用纯 SQL,例如

public function updateInvoice($users) {
    $connection = $this->container->get('doctrine.dbal.default_connection');    
    $values = array();
    foreach ($users as $user) {
        $values[] = "(
            '" . $user->getId() . "',
            '" . $user->getMonth() . "',
            '" . $user->getYear() . "',
            '" . $user->getNbrBusiness() . "'
            )";
    }
    $sql = "INSERT INTO invoice (`commercial`, `month`, `year`, `nbrBusiness`) VALUES " . implode("," , $values);
    $statement = $connection->prepare($sql);
    $statement->execute();
}

【讨论】:

  • 调用未定义的方法 Doctrine\ORM\QueryBuilder::insert()
  • 编辑了我的答案以说明这一点