Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony2在模型/控制器之外_Symfony_Doctrine - Fatal编程技术网

Symfony2在模型/控制器之外

Symfony2在模型/控制器之外,symfony,doctrine,Symfony,Doctrine,我正在尝试从控制器外部获取Doctrine()。 我已创建此服务: config/services.yml services: update_command: class: project\projBundle\Command\Update arguments: ['@doctrine.orm.entity_manager'] 在我的app/config/config.yml中 imports: - { resource: "@projectprojBundle/R

我正在尝试从控制器外部获取Doctrine()。 我已创建此服务:

config/services.yml

services:
  update_command:
    class: project\projBundle\Command\Update
    arguments: ['@doctrine.orm.entity_manager']
在我的app/config/config.yml中

imports:
    - { resource: "@projectprojBundle/Resources/config/services.yml" }
我想使用的类是:

但每次我想这样做:(我做得对吗?

我得到了这个错误:

Catchable Fatal Error: Argument 1 passed to ...\Update::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in .../Update.php line 7  

删除app/config/config.yml中的以下代码,您的services.yml将自动加载

imports:
    - { resource: "@projectprojBundle/Resources/config/services.yml" }
在新实例的操作中,您可以执行以下操作:

  $up = $this->get('update_command');

您必须注入新创建的
@update\u命令
服务,或者从容器中获取它,以便自动注入
@doctor.orm.entity\u管理器
服务

您只是创建了一个没有参数的对象,而不是一个服务。更新需要检索实体管理器实例,但您没有提供它

$up = new Update();
containerware
类中,像控制器一样获得如下服务:

 $up = $this->container->get('update_command');

否则,将要使用
update\u命令的类也转换为服务,并像在服务本身中使用实体管理器一样注入
@update\u命令。

简单解决方案

如果要实现Symfony命令(可以在cron选项卡中执行),则可以从该命令访问服务容器

<?php
namespace MyProject\MyBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Doctrine\ORM\EntityManager;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class UpdateCommand extends ContainerAwareCommand
{
    protected $em;

    protected function configure()
    {
        $this->setName('myproject:mybundle:update') ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->em = $this->getContainer()->get('doctrine.orm.entity_manager');
    }
}
services.yml
文件中将其声明为服务:

services:
    myproject.mybundle.myupdater:
        class: MyProject\MyBundle\Service\MyUpdater
        arguments: ['@doctrine.orm.entity_manager']
只需通过命令调用您的服务:

<?php
namespace MyProject\MyBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class UpdateCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this->setName('myproject:mybundle:update') ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $myUpdater = $this->getContainer()->get('myproject.mybundle.myupdater');
        $myUpdater->runUpdate();
    }
}

您有供应商提供的symfony2版本吗?这听起来很奇怪…是的,我只是更新了供应商是的,这是正确的答案。顺便说一句,现在更新可以帮助我们,上次我检查这个问题时,new update()不在这里:呵呵,我已经对评论感到好奇了。。。当人们开始使用服务容器时,这可能是最容易犯的错误。您的控制器类也可以作为服务添加到容器中-请参阅。但是在这个类中使用getDoctrine还有其他方法吗?因为我只需要在cron选项卡中从一个扩展了
Symfony\Bundle\FrameworkBundle\controller\controller
的控制器执行此操作,您只需执行类似
$up=new Update($this->getdoctor()->getEntityManager())的操作即可。这样您就不需要创建服务了。剩下的问题是什么?这是symfony解决此问题的方法-使用已定义的服务和依赖项注入是获取实体管理器的最佳实践。复制您的?--!我回答得比你早,当我编辑我的答案并刷新页面时,我看到了你的答案。是的,这正是我想要做的。但是现在我得到了一个不同的错误:PHP致命错误:在第36行的/var/www/project/vendor/symfony/symfony/src/symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.PHP中对非对象调用成员函数getKernel()。我在遵循食谱,我不明白这个错误我编辑了我的代码,这个错误被修复了。您必须将初始化移动到
execute
方法。
containerwarecommand
只是一个本身扩展了
containerware
的类@BrunoRamalho您没有提到您试图在命令中使用实体管理器,但您谈论的是一般的非控制器类,所以这个答案只是我的补充。顺便说一下,另一个不错的解决方案是移动命令的所有逻辑部分(即真正执行更新的代码,不管它是什么)去另一个班。另一个类将在
services.yml
文件中声明为服务(与前面一样),并将实体管理器作为参数。然后,您可以通过命令调用此服务。这将是这样做的最佳做法。我将添加一个解释它的其他答案。您现在可以看看我的其他解决方案,它比第一个更干净,因为它可以轻松地进行单元测试,并且可以在Symfony应用程序的其他地方使用。第一种方法实现起来更快。
<?php
namespace MyProject\MyBundle\Service;

use Doctrine\ORM\EntityManager;

class MyUpdater
{
    protected $em;

    public function __construct($em)
    {
        $this->em = $em;
    }

    public function runUpdate()
    {
        // All your logic code here
    }
}
services:
    myproject.mybundle.myupdater:
        class: MyProject\MyBundle\Service\MyUpdater
        arguments: ['@doctrine.orm.entity_manager']
<?php
namespace MyProject\MyBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class UpdateCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this->setName('myproject:mybundle:update') ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $myUpdater = $this->getContainer()->get('myproject.mybundle.myupdater');
        $myUpdater->runUpdate();
    }
}