Symfony2 getdoctrine outside of Model/Controller

柔情痞子 提交于 2020-01-01 03:29:07

问题


I'm trying to getDoctrine() outside of the controller. I've created this service:

config/services.yml

services:
  update_command:
    class: project\projBundle\Command\Update
    arguments: ['@doctrine.orm.entity_manager']

and in my app/config/config.yml

imports:
    - { resource: "@projectprojBundle/Resources/config/services.yml" }

so and the class that I want to use:

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

class Update {
    protected $em;
    public function __construct(EntityManager $em) {
        $this->em = $em;
    }

but every time I want to do this: (I'm doing this right?)

$up = new Update();

i got this error:

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  

回答1:


Simple solution

If you're implementing a Symfony command (that can be executed in a cron tab), you can access the service container from the command.

<?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');
    }
}

That way, you get the entity manager from a command and don't need to declare this class as a service. You can therefore remove the configuration you added in the services.yml file.

An other solution (cleaner)

This solution allows better separation of concerns and can therefore be easily unit tested and reused in other parts of your Symfony application (not only as a command).

Move all the logic part of your "update" command to a dedicated class that you will declare as a service:

<?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
    }
}

Declare it as a service in your services.yml file:

services:
    myproject.mybundle.myupdater:
        class: MyProject\MyBundle\Service\MyUpdater
        arguments: ['@doctrine.orm.entity_manager']

Simply call your service from your command :

<?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();
    }
}



回答2:


You have to either inject your newly created @update_command service or get it from the container in order to have the @doctrine.orm.entity_manager service injected automatically.

You're just creating the object with no argument, not a service. Update expects to retrieve an entity manager instance but you don't provide it.

$up = new Update();

In a ContainerAware class like a controller get your service like this:

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

Otherwise turn the class where you want to use the update_command into a service aswell and inject @update_command as you did with the entity manager in the service itself.




回答3:


remove below codes in app/config/config.yml, your services.yml will be autoload...

imports:
    - { resource: "@projectprojBundle/Resources/config/services.yml" }

in a Action new a instance you can do:

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


来源:https://stackoverflow.com/questions/19855251/symfony2-getdoctrine-outside-of-model-controller

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!