如何从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()
不起作用。
您不能使用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注入entityManager,而EntManager是其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.
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
我建议不要继承“ContainerAwareCommand”并再次使用“extends Command”。通常,您应该将命令定义为服务并使用依赖注入,而不是通过容器使用“get()”。只需使用__constructor注入。这是要走的路,也是命令。
这就是Symfony的建议:
https://symfony.com/doc/current/console/commands_as_services.html