symfony3 从命令访问实体管理器
symfony3 access entitymanager from 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();
...
}
}
我得到这个错误:
Uncaught Symfony\Component\Debug\Exception\UndefinedMethodException: Attempted to call an undefined method named "getContainer" of class "AppBundle\Command\MyCommand"
如果我从 Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand
扩展(这是 symfony 2 方式),也会发生这种情况。
此外,在 __construct()
中注入 Doctrine\ORM\EntityManager
无效。
您不能使用 getContainer,因为您的命令 class 不知道容器。
使您的命令扩展 ContainerAwareCommand
这样你就可以使用getContainer()
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
然后扩展 ContainerAwareCommand :
class MyCommand extends ContainerAwareCommand
然后随处使用它:
$em = $this->getContainer()->get('doctrine')->getManager('default');
感谢@tomáš-votruba 编辑:
然而 ContainerAware 在 Symfony 4 中被 弃用:
通过注入使用 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,它是一个接口,而 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.
我建议不要继承 "ContainerAwareCommand" 并再次使用 "extends Command"。通常,您应该将命令定义为服务并使用依赖注入,而不是通过容器使用 "get()"。只需使用 __constructor 注入即可。这就是要走的路,也适用于命令。
这是 Symfony 的建议:
https://symfony.com/doc/current/console/commands_as_services.html
2019 年最好的唯一干净方法是使用构造函数注入。 Symfony 3.3/4+ 中的任何其他内容都被删除了,所以你将来只会用 $this->get()
.
添加额外的工作
Also, injecting Doctrine\ORM\EntityManager in __construct() didn't work
在 __construct()
中尝试 Doctrine\ORM\EntityManagerInterface
类型声明。
还要确保命令在services.yaml
配置中有autowire: true
:
services:
# in Symfony 3.3+
_defaults:
autowire: true
App\:
resource: ../src
# in Symfony 2.8-3.3
App\SomeCommand:
autowire: true
如何从 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();
...
}
}
我得到这个错误:
Uncaught Symfony\Component\Debug\Exception\UndefinedMethodException: Attempted to call an undefined method named "getContainer" of class "AppBundle\Command\MyCommand"
如果我从 Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand
扩展(这是 symfony 2 方式),也会发生这种情况。
此外,在 __construct()
中注入 Doctrine\ORM\EntityManager
无效。
您不能使用 getContainer,因为您的命令 class 不知道容器。
使您的命令扩展 ContainerAwareCommand
这样你就可以使用getContainer()
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
然后扩展 ContainerAwareCommand :
class MyCommand extends ContainerAwareCommand
然后随处使用它:
$em = $this->getContainer()->get('doctrine')->getManager('default');
感谢@tomáš-votruba 编辑:
然而 ContainerAware 在 Symfony 4 中被 弃用:
通过注入使用 EntityManager :
因此,与其强制使用容器获取实体管理器,不如注入您的构造函数并通过 using your command as a service:
扩展 Commandnamespace 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,它是一个接口,而 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.
我建议不要继承 "ContainerAwareCommand" 并再次使用 "extends Command"。通常,您应该将命令定义为服务并使用依赖注入,而不是通过容器使用 "get()"。只需使用 __constructor 注入即可。这就是要走的路,也适用于命令。
这是 Symfony 的建议:
https://symfony.com/doc/current/console/commands_as_services.html
2019 年最好的唯一干净方法是使用构造函数注入。 Symfony 3.3/4+ 中的任何其他内容都被删除了,所以你将来只会用 $this->get()
.
Also, injecting Doctrine\ORM\EntityManager in __construct() didn't work
在 __construct()
中尝试 Doctrine\ORM\EntityManagerInterface
类型声明。
还要确保命令在services.yaml
配置中有autowire: true
:
services:
# in Symfony 3.3+
_defaults:
autowire: true
App\:
resource: ../src
# in Symfony 2.8-3.3
App\SomeCommand:
autowire: true