我想在Symfony2应用程序中使用一些终端命令。我已经浏览了example in the cookbook,但我无法在这里找到如何访问我的设置,我的实体经理和我的实体。在构造函数中,我使用
获取容器(应该允许我访问设置和实体)$this->container = $this->getContainer();
但是这个调用会产生错误:
致命错误:在/Users/fester/Sites/thinkblue/admintool/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.php上的非对象上调用成员函数getKernel() 38
基本上,在ContainerAwareCommand-> getContainer()中调用
$this->getApplication()
返回NULL而不是预期的对象。我想我离开了一些重要的一步,但哪一个?我最终将如何使用我的设置和实体?
答案 0 :(得分:75)
我认为你不应该直接在构造函数中检索容器。而是在configure
方法或execute
方法中检索它。在我的例子中,我在execute
方法的开头就得到了我的实体管理器,并且一切正常(使用Symfony 2.1测试)。
protected function execute(InputInterface $input, OutputInterface $output)
{
$entityManager = $this->getContainer()->get('doctrine')->getEntityManager();
// Code here
}
我认为当您在构造函数中调用getContainer
导致此错误时,尚未完成应用程序对象的实例化。该错误来自getContainer
方法来执行:
$this->container = $this->getApplication()->getKernel()->getContainer();
由于getApplication
还不是对象,因此在非对象上出现错误或正在调用方法getKernel
。
更新:在较新版本的Symfony中,getEntityManager
已被弃用(现在可能已完全删除)。请改用$entityManager = $this->getContainer()->get('doctrine')->getManager();
。感谢Chausser指出它。
更新2 :在Symfony 4中,可以使用自动布线来减少所需的代码量。
使用__constructor
变量创建EntityManagerInterface
。可以在其余命令中访问此变量。这遵循自动布线依赖注入方案。
class UserCommand extends ContainerAwareCommand {
private $em;
public function __construct(?string $name = null, EntityManagerInterface $em) {
parent::__construct($name);
$this->em = $em;
}
protected function configure() {
**name, desc, help code here**
}
protected function execute(InputInterface $input, OutputInterface $output) {
$this->em->getRepository('App:Table')->findAll();
}
}
致@promm2提供评论和代码示例。
答案 1 :(得分:10)
从ContainerAwareCommand而不是Command
扩展您的命令类class YourCmdCommand extends ContainerAwareCommand
并获取像这样的实体经理:
$em = $this->getContainer()->get('doctrine.orm.entity_manager');
答案 2 :(得分:4)
我知道Matt的答案解决了这个问题,但如果你有多个实体经理,你可以使用它:
使用:
创建model.xml<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="EM_NAME.entity_manager" alias="doctrine.orm.entity_manager" />
</services>
</container>
然后在DI扩展程序中加载此文件
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('model.xml');
然后你可以在任何地方使用它。 在控制台命令中执行:
$em = $this->getContainer()->get('EM_NAME.entity_manager');
并且最后不要忘记:
$em->flush();
您现在可以将它用作services.yml中其他服务的参数:
services:
SOME_SERVICE:
class: %parameter.class%
arguments:
- @EM_NAME.entity_manager
希望这有助于某人。