Symfony2 - How to access the service in a custom c

2020-02-10 05:58发布

问题:

I am new to Symfony. I have created a custom command which sole purpose is to wipe demo data from the system, but I do not know how to do this.

In the controller I would do:

$nodes = $this->getDoctrine()
    ->getRepository('MyFreelancerPortfolioBundle:TreeNode')
    ->findAll();

$em = $this->getDoctrine()->getManager();
foreach($nodes as $node)
{
    $em->remove($node);
}
$em->flush();

Doing this from the execute() function in the command I get:

Call to undefined method ..... ::getDoctrine();

How would I do this from the execute() function? Also, if there is an easier way to wipe the data other than to loop through them and remove them, feel free to mention it.

回答1:

In order to be able to access the service container your command needs to extend Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand.

See the Command documentation chapter - Getting Services from the Container.

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
// ... other use statements

class MyCommand extends ContainerAwareCommand
{
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $em = $this->getContainer()->get('doctrine')->getEntityManager();
        // ...


回答2:

Since Symfony 3.3 (May 2017) you can use Dependency Injection in commands with ease.

Just use PSR-4 services autodiscovery in your services.yml:

services:
    _defaults:
        autowire: true

    App\Command\:
        resource: ../Command

Then use common Constructor Injection and finally even Commands will have clean architecture:

final class MyCommand extends Command
{
    /**
     * @var SomeDependency
     */
    private $someDependency;

    public function __construct(SomeDependency $someDependency)
    {
        $this->someDependency = $someDependency;

        // this is required due to parent constructor, which sets up name 
        parent::__construct(); 
    }
}

This will (or already did, depends of time reading) become standards since Symfony 3.4 (November 2017), when commands will be lazy loaded.