Symfony2 getdoctrine在Model/Controller之外

Bru*_*lho 4 doctrine symfony

我正在尝试在控制器之外获取Doctrine().我创建了这项服务:

配置/ services.yml

services:
  update_command:
    class: project\projBundle\Command\Update
    arguments: ['@doctrine.orm.entity_manager']
Run Code Online (Sandbox Code Playgroud)

在我的app/config/config.yml中

imports:
    - { resource: "@projectprojBundle/Resources/config/services.yml" }
Run Code Online (Sandbox Code Playgroud)

以及我想要使用的类:

namespace project\projBundle\Command;
use Doctrine\ORM\EntityManager;

class Update {
    protected $em;
    public function __construct(EntityManager $em) {
        $this->em = $em;
    }
Run Code Online (Sandbox Code Playgroud)

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

$up = new Update();
Run Code Online (Sandbox Code Playgroud)

我收到了这个错误:

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  
Run Code Online (Sandbox Code Playgroud)

Mic*_*rin 7

简单解决方案

如果要实现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');
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,您从命令中获取实体管理器,而不需要将此类声明为服务.因此,您可以删除在services.yml文件中添加的配置.

另一种解决方案(清洁剂)

该解决方案可以更好地分离关注点,因此可以在Symfony应用程序的其他部分轻松进行单元测试和重用(不仅仅是作为命令).

将"update"命令的所有逻辑部分移动到您将声明为服务的专用类:

<?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
    }
}
Run Code Online (Sandbox Code Playgroud)

将其声明为您services.yml文件中的服务:

services:
    myproject.mybundle.myupdater:
        class: MyProject\MyBundle\Service\MyUpdater
        arguments: ['@doctrine.orm.entity_manager']
Run Code Online (Sandbox Code Playgroud)

只需通过命令调用您的服务:

<?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();
    }
}
Run Code Online (Sandbox Code Playgroud)