【问题标题】:Symfony 4: doctrine in commandSymfony 4:指挥学说
【发布时间】:2018-06-22 09:32:20
【问题描述】:

我正在使用 symfony 4,如果我在 Command 类中,我想访问实体的存储库。没有函数getDoctrine什么的..

我已经通过控制台创建了一个实体,所以我得到了一个实体和一个存储库。

有人知道我如何访问存储库吗?

【问题讨论】:

标签: php symfony doctrine


【解决方案1】:

使用字段注入

class ToolCSVSetStopCommand extends Command
{
  /** @required */
  public EntityManagerInterface $em; //must be public to be injected

  protected function execute(InputInterface $input, OutputInterface $output) {
    $this->em;
  }
}

或方法注入

class ToolCSVSetStopCommand extends Command
{
  /** @required */
  public function setEm(EntityManagerInterface $em) {
    $this->em = $em;
  }

  protected function execute(InputInterface $input, OutputInterface $output) {
    $this->em;
  }
}

【讨论】:

    【解决方案2】:

    Symfony 4 的官方建议是只自动装配你需要的东西。因此,与其注入 ContainerInterface 并从中请求 EntityManager,不如直接注入 EntityManagerInterface:

    use Doctrine\ORM\EntityManagerInterface;
    
    class YourCommand extends Command
    {
    
        private $em;
    
        public function __construct(EntityManagerInterface $em)
        {
            parent::__construct();
            $this->em = $em;
        }
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $this->em->persist($thing);
            $this->em->flush();
        }
    
    }
    

    【讨论】:

      【解决方案3】:
      $kernel = $this->getApplication()->getKernel();
      $container = $kernel->getContainer();
      
      // Get doctrine
      $em = $container->get('doctrine')->getManager();
      

      【讨论】:

        【解决方案4】:

        最佳做法是将此任务委托给服务。 看这个例子:https://symfony.com/doc/current/console.html#getting-services-from-the-service-container

        但是,您也可以向命令添加构造函数并为其提供 ContainerInterface。那你就做$this->container->get('doctrine')->getManager();

        // YourCommand.php
        
        private $container;
        
        public function __construct(ContainerInterface $container)
        {
            parent::__construct();
            $this->container = $container;
        }
        
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $em = $this->container->get('doctrine')->getManager();
        
            // do stuff...
        }
        

        另外,不要忘记在脚本开头添加正确的“使用”语句:

        use Symfony\Component\DependencyInjection\ContainerInterface;
        

        【讨论】:

        • 其实在构造函数中直接注入实体管理器会更好:public function __construct(EntityManagerInterface $entityManager) 然后直接在执行中使用$this->entityManager
        • 我认为答案应该反映 symfony 认为的最佳实践:在构造函数中作为类型化参数添加并让 autowire 解决
        【解决方案5】:

        在这里使用 Symfony 4.2。

        use Symfony\Component\Console\Command\Command;
        use Doctrine\DBAL\Connection;
        
        class ArchiveCommand extends Command
        {
           protected static $defaultName = 'simon:test:archive';
           private $connection;
        
           public function __construct(Connection $connection)
           {
              $this->connection = $connection;
              parent::__construct();
           }
        
           /**
           * {@inheritdoc}
           */
           protected function execute(InputInterface $input, OutputInterface $output)
           {
              $this->connection->prepare('SQL HERE');
           }
        

        与从容器中获取它的方式完全相同,但不推荐从 containerAwareInterface 使用它,现在应该注入。

        【讨论】:

          【解决方案6】:

          我使用这种语法:

              $em = $this->getContainer()->get('doctrine')->getEntityManager();
          

          【讨论】:

            猜你喜欢
            • 2012-06-11
            • 1970-01-01
            • 2016-03-31
            • 1970-01-01
            • 2019-07-30
            • 2011-06-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多