1

I am writing a symfony console command which will be executable by using "php bin/console app:mycommand" (symfony documentation: https://symfony.com/doc/current/console.html#creating-a-command).

In my MyCommand class I need to use the getDoctrine-function, so I have to extend the controller, but I don't see a way how to do that. Any ideas?

Currently I get following error on CLI: Attempted to call an undefined method named "getDoctrine" of class "App\Command\MyCommand".

<?php
  // src/Command/MyCommand.php
  namespace App\Command;

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

  use Symfony\Bundle\FrameworkBundle\Controller\Controller;

  class MyCommand extends Command
  {
    // the name of the command (the part after "bin/console")
    protected static $defaultName = 'app:mycommand';

    protected function configure()
    {

    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
      // Not working, producing mentioned error 
      $em = $this->getDoctrine()->getManager();
    }
  }
?>
1
  • Why would you expect to be able to call that function? What makes you think you "have to extend the controller"? Commented Aug 19, 2019 at 11:14

1 Answer 1

2

The getDoctrine() method is provided by the ControllerTrait, which in turn depends on the ContainerAwareTrait for the container injection. This however will pull additional services and methods that you won't need in a command so instead of injecting the whole container, the recommended approach is that you inject just the service you need, which in this case is the ObjectManager (ObjectManager is the common interface implemented both by the ORM and the ODM, if you use both or you just care about the ORM, you can use Doctrine\ORM\EntityManagerInterface instead).

  <?php
  // src/Command/MyCommand.php
  namespace App\Command;

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

  use Doctrine\Common\Persistence\ObjectManager;

  class MyCommand extends Command
  {
    // the name of the command (the part after "bin/console")
    protected static $defaultName = 'app:mycommand';

    private $manager;

    public function __construct(ObjectManager $manager)
    {
        $this->manager = $manager;
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        // Now you have access to the manager methods in $this->manager
        $repository = $this->manager->getRepository(/*...*/);
    }
  }
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your help! But now I am getting this error on execution. Why does that happen? The ObjectManager is imported. Cannot autowire service "debug.argument_resolver.not_tagged_controller.inner": argument "$manager" of method "__construct()" has type "Doctrine\Persistence\ObjectManager" but this class was not found.
@Ccenter Sorry, I forgot a namespace component. Hopefully it works now
With both namespaces in use, the mentioned error disappears. But I get following runtime error for $em = $this->manager->getDoctrine()->getManager();: Attempted to call an undefined method named "getDoctrine" of class "Doctrine\ORM\EntityManager". What's missing? I Would like to understand that. Over and above that: I found a working solution here: stackoverflow.com/questions/48234418/…
@Ccenter you don't need to call getDoctrine()->getManager() , $this->manager is the EntityManager already and you can call getRepository() directly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.