Как использовать мои сущности и менеджеров сущностей в Symfony 2 Console Command? - PullRequest
42 голосов
/ 22 сентября 2011

Я хочу несколько команд терминала для моего приложения Symfony2. Я рассмотрел пример в кулинарной книге , но я не смог выяснить, как получить доступ к моим настройкам, моему менеджеру сущностей и моим сущностям здесь. В конструкторе я получаю контейнер (который должен дать мне доступ к настройкам и сущностям), используя

$this->container = $this->getContainer();

Но этот вызов выдает ошибку:

Неустранимая ошибка: вызов функции-члена getKernel () для необъекта в /Users/fester/Sites/thinkblue/admintool/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Command/ContainerAwareCommand.php онлайн 38

По сути, в ContainerAwareCommand-> getContainer () вызов

$this->getApplication()

возвращает NULL, а не объект, как ожидалось. Я думаю, что я оставил важный шаг, но какой? И как я наконец смогу использовать мои настройки и сущности?

Ответы [ 3 ]

75 голосов
/ 22 сентября 2011

Я думаю, вы не должны извлекать контейнер в конструкторе напрямую.Вместо этого получите его в методе configure или в методе execute.В моем случае я получаю свой менеджер сущностей только в начале метода execute, как этот, и все работает нормально (протестировано с Symfony 2.1).

protected function execute(InputInterface $input, OutputInterface $output)
{
    $entityManager = $this->getContainer()->get('doctrine')->getEntityManager();

    // Code here
}

Я думаю, что создание экземпляра приложенияобъект еще не завершен, когда вы вызываете getContainer в своем конструкторе, что приводит к этой ошибке.Ошибка происходит из-за метода getContainer, связывающего выполнение:

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

Поскольку getApplication еще не является объектом, вы получаете сообщение об ошибке или вызываете метод getKernel для не-объекта.object.

Обновление : В более новой версии Symfony getEntityManager устарел (и может быть уже полностью удален).Вместо этого используйте $entityManager = $this->getContainer()->get('doctrine')->getManager();.Спасибо Chausser за указание.

Обновление 2 : В Symfony 4 автоматическое подключение может использоваться для уменьшения количества кода, необходимого.

Создайте __constructor с переменной EntityManagerInterface.Эта переменная будет доступна в остальных ваших командах.Это соответствует схеме автоматического ввода зависимостей.

class UserCommand extends ContainerAwareCommand { 
  private $em; 

  public function __construct(?string $name = null, EntityManagerInterface $em) { 
    parent::__construct($name); 

    $this->em = $em;
  } 

  protected function configure() { 
    **name, desc, help code here** 
  }

  protected function execute(InputInterface $input, OutputInterface $output) { 
    $this->em->getRepository('App:Table')->findAll();
  }
}

Кредиты @ profm2 для предоставления комментария и примера кода.

10 голосов
/ 14 ноября 2013

расширяет ваш командный класс из ContainerAwareCommand вместо Command

class YourCmdCommand extends ContainerAwareCommand

и получите менеджер сущностей следующим образом:

$em = $this->getContainer()->get('doctrine.orm.entity_manager');
4 голосов
/ 21 марта 2012

Я знаю, что ответ Мэтта решил вопрос, но если у вас более одного менеджера сущностей, вы можете использовать это:

Создайте model.xml с:

<?xml version="1.0" encoding="UTF-8" ?>

<container xmlns="http://symfony.com/schema/dic/services"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://symfony.com/schema/dic/services         http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
    <service id="EM_NAME.entity_manager" alias="doctrine.orm.entity_manager" />
</services>
</container>

Тогдазагрузить этот файл с расширением DI

$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('model.xml');

Тогда вы можете использовать его где угодно.В консоли выполните команду:

$em = $this->getContainer()->get('EM_NAME.entity_manager');

и не забудьте в конце:

$em->flush();

Теперь вы можете использовать ее в качестве аргумента в другой службе в services.yml:

services:
    SOME_SERVICE:
        class: %parameter.class%
        arguments:
            - @EM_NAME.entity_manager

Надеюсь, это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...