symfony3 получить доступ к диспетчеру сущностей из команды - PullRequest
1 голос
/ 25 апреля 2019

Как получить доступ к EntityManager по команде в Symfony 3? Предполагается, что это будет ContainerAware.

Это мой код:

use Symfony\Component\Console\Command\Command;
class MyCommand extends Command
{
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $em = $this->getContainer()->getDoctrine();
        ...
    }
}

И я получаю эту ошибку:

Uncaught Symfony \ Component \ Debug \ Exception \ UndefinedMethodException: попытка вызова неопределенного метода с именем "getContainer" из класса "AppBundle \ Command \ MyCommand"

Это происходит также, если я продолжаю с Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand (который был способом Symfony 2).

Кроме того, введение Doctrine\ORM\EntityManager в __construct() не сработало.

Ответы [ 3 ]

1 голос
/ 25 апреля 2019

Лучший чистый способ в 2019 году - использовать конструктор инъекций .Все остальное удаляется в Symfony 3.3 / 4 +, так что в будущем вы только добавите себе дополнительную работу с $this->get().

Также добавьте Doctrine \ ORM \ EntityManager в __construct () didn 't работа

Попробуйте Doctrine\ORM\EntityManagerInterface объявление типа в __construct().

Также убедитесь, что команда имеет autowire: true в конфигурации services.yaml:

services:
    # in Symfony 3.3+
    _defaults:
        autowire: true

    App\:
        resource: ../src

    # in Symfony 2.8-3.3
    App\SomeCommand:
        autowire: true
0 голосов
/ 25 апреля 2019

Я бы предложил не наследовать от «ContainerAwareCommand» и снова использовать «extends Command». Как правило, вы должны определить свою команду как службу и использовать внедрение зависимостей вместо использования «get ()» через контейнер. Просто используйте инъекцию __constructor. Это путь, в том числе для команд.

Вот как Symfony предложил бы это:

https://symfony.com/doc/current/console/commands_as_services.html

0 голосов
/ 25 апреля 2019

Вы не можете использовать getContainer, потому что ваш командный класс не знает о контейнере.

Расширение вашей команды ContainerAwareCommand

Так что вы можете использовать getContainer ()

 use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;

Затем расширяет ContainerAwareCommand :

class MyCommand extends ContainerAwareCommand

А затем используйте его где угодно:

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

РЕДАКТИРОВАТЬ благодаря @ tomáš-votruba:

ОДНАКО Контейнерное ПО устарело в Symfony 4:

Использование EntityManager путем введения его:

Таким образом, вместо принудительного получения менеджера сущностей с контейнером, вместо этого введите в свой конструктор и расширьте Command на , используя вашу команду в качестве службы :

namespace App\Command;

use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Console\Command\Command;

class MyCommand extends Command {

//add $entityManager attribute

private $entityManager;

public function __construct(ObjectManager $entityManager)
{
    $this->entityManager= $entityManager;

    // you *must* call the parent constructor
    parent::__construct();
}

Как вы можете видеть в конструкторе, мы внедряем entityManager с ObjectManager, который является интерфейсом, тогда как EntityManager является его реализацией ORM, вы можете сделать это, если вы используете services.yml по умолчанию или тот, который настроен на автопроводку:

# config/services.yaml
services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        public: false       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...