13

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?

1

6 Answers 6

25

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;
Sign up to request clarification or add additional context in comments.

2 Comments

Actually it would be even better to inject directly the entity manager in constructor: public function __construct(EntityManagerInterface $entityManager) then use it directly in execute with $this->entityManager.
I think the answer should reflect what symfony considers best practice: Add as a typed parameter in the constructor and let the autowire figure it out
25

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

}

Comments

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

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

Comments

2

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.

Comments

1

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

Comments

-3

I use this syntax :

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

Comments

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.