Symfony2在模型/控制器之外
我正在尝试从控制器外部获取Doctrine()。 我已创建此服务: config/services.ymlSymfony2在模型/控制器之外,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
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();
}
}