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
$kernel = $this->getApplication()->getKernel();
$container = $kernel->getContainer();
// Get doctrine
$em = $container->get('doctrine')->getManager();
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();
}
}
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;
}
}
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;
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.
I use this syntax :
$em = $this->getContainer()->get('doctrine')->getEntityManager();