Home » Php » php – Symfony 4: doctrine in command

php – Symfony 4: doctrine in command

Posted by: admin July 12, 2020 Leave a comment

Questions:

I am using symfony 4 and I want to access a repository for an entity if I am in the Command class. There is not a function getDoctrine or something..

I have created an Entity through the console, so I got an entity and a repository.

Does anybody know how I can access the repository?

How to&Answers:

The best practice is to delegate this task to a service.
See this example: https://symfony.com/doc/current/console.html#getting-services-from-the-service-container

However you can also add a constructor to the command and give it a ContainerInterface. Then you just do $this->container->get('doctrine')->getManager();

// YourCommand.php

private $container;

public function __construct(ContainerInterface $container)
{
    parent::__construct();
    $this->container = $container;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
    $em = $this->container->get('doctrine')->getManager();

    // do stuff...
}

Also, don’t forget to add the proper “use” statement at the beggining of your script:

use Symfony\Component\DependencyInjection\ContainerInterface;

Answer:

The official Symfony 4 advice is to autowire only what you need. So instead of injecting ContainerInterface and requesting an EntityManager from that, inject EntityManagerInterface directly:

use Doctrine\ORM\EntityManagerInterface;

class YourCommand extends Command
{

    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        parent::__construct();
        $this->em = $em;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->em->persist($thing);
        $this->em->flush();
    }

}

Answer:

$kernel = $this->getApplication()->getKernel();
$container = $kernel->getContainer();

// Get doctrine
$em = $container->get('doctrine')->getManager();

Answer:

Using Symfony 4.2 here.

use Symfony\Component\Console\Command\Command;
use Doctrine\DBAL\Connection;

class ArchiveCommand extends Command
{
   protected static $defaultName = 'simon:test:archive';
   private $connection;

   public function __construct(Connection $connection)
   {
      $this->connection = $connection;
      parent::__construct();
   }

   /**
   * {@inheritdoc}
   */
   protected function execute(InputInterface $input, OutputInterface $output)
   {
      $this->connection->prepare('SQL HERE');
   }

Works exactly as getting it from the container but is deprecated using it from the containerAwareInterface and should be injected now.

Answer:

Using Field injection

class ToolCSVSetStopCommand extends Command
{
  /** @required */
  public EntityManagerInterface $em; //must be public to be injected

  protected function execute(InputInterface $input, OutputInterface $output) {
    $this->em;
  }
}

or Method injection

class ToolCSVSetStopCommand extends Command
{
  /** @required */
  public function setEm(EntityManagerInterface $em) {
    $this->em = $em;
  }

  protected function execute(InputInterface $input, OutputInterface $output) {
    $this->em;
  }
}

Answer:

I use this syntax :

    $em = $this->getContainer()->get('doctrine')->getEntityManager();