如何在Symfony 2控制台命令中使用我的实体和实体管理器?

时间:2011-09-22 09:20:13

标签: php console symfony

我想在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而不是预期的对象。我想我离开了一些重要的一步,但哪一个?我最终将如何使用我的设置和实体?

3 个答案:

答案 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

希望这有助于某人。