命令中的symfony3访问实体管理器

时间:2019-04-25 11:38:47

标签: symfony command

如何从Symfony 3中的命令访问EntityManager?应该是ContainerAware

这是我的代码:

use Symfony\Component\Console\Command\Command;
class MyCommand extends Command
{
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $em = $this->getContainer()->getDoctrine();
        ...
    }
}

我收到此错误:

  

未捕获的Symfony \ Component \ Debug \ Exception \ UndefinedMethodException:尝试调用类“ AppBundle \ Command \ MyCommand”的未定义方法“ getContainer”

如果我从Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand(这是symfony 2方式)扩展过来,也会发生这种情况。

此外,在Doctrine\ORM\EntityManager中注入__construct()无效。

3 个答案:

答案 0 :(得分:1)

2019年最好的唯一清洁方法是使用构造函数注入。 Symfony 3.3 / 4 +中的所有其他内容都将被删除,因此您以后只能通过$this->get()添加自己的工作。

  

此外,在__construct()中注入Doctrine \ ORM \ EntityManager无效

尝试在Doctrine\ORM\EntityManagerInterface中进行__construct()类型声明。

还要确保,该命令在autowire: true配置中具有services.yaml

services:
    # in Symfony 3.3+
    _defaults:
        autowire: true

    App\:
        resource: ../src

    # in Symfony 2.8-3.3
    App\SomeCommand:
        autowire: true

答案 1 :(得分:0)

您不能使用getContainer,因为您的命令类无法识别该容器。

使您的命令扩展 ContainerAwareCommand

这样您就可以使用 getContainer()

 use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;

然后扩展 ContainerAwareCommand

class MyCommand extends ContainerAwareCommand

然后在任何需要的地方使用它:

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

感谢@tomáš-votruba的编辑:

如何在Symfony 4中不推荐使用ContainerAware :

通过注入EntityManager使用它:

因此,与其强行将容器带给实体管理器,不如注入您的构造函数并通过using your command as a service扩展Command:

namespace App\Command;

use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Console\Command\Command;

class MyCommand extends Command {

//add $entityManager attribute

private $entityManager;

public function __construct(ObjectManager $entityManager)
{
    $this->entityManager= $entityManager;

    // you *must* call the parent constructor
    parent::__construct();
}

正如您在构造函数中看到的那样,我们向ObjectManager注入了ObjectManager,ObjectManager是一个接口,而EntityManager是其ORM实现,如果使用默认的 services.yml 或一个设置用于自动装配:

# config/services.yaml
services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        public: false       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.

答案 2 :(得分:0)

我建议不要继承“ ContainerAwareCommand”,而再次使用“ extends Command”。通常,您应该将命令定义为服务,并使用依赖项注入,而不是通过容器使用“ get()”。只需使用__constructor注入即可。对于命令来说,这就是方法。

这是Symfony的建议:

https://symfony.com/doc/current/console/commands_as_services.html