2014-09-21 2 views
4

Симфонический новичок здесь. После прочтения некоторых документов Symfony и некоторых ответов здесь, в SO, я сейчас почти полностью смущен. Я пытаюсь использовать компонент консольного приложения и создать небольшое консольное приложение, поддерживающее db.Приложение для консоли Symfony: инъекция зависимостей

Многие люди заявляют, что для использования функций DI Symfony было бы достаточно наследовать мой командный класс не из Symfony \ Component \ Console \ Command \ Command, а из ContainerAwareCommand. Однако, когда я пытаюсь это сделать, я получаю ошибку Method Not Found при вызове application :: getKernel().

У меня такое ощущение, что функции DI на самом деле недоступны в консольном приложении на базе консоли Компонент. Существует ли другое консольное приложение Symfony, например, на основе полномасштабной структуры?

Мне очень нравится простая структура, предоставляемая консольным компонентом Symfony \ Component \ Console \ Application. Но вопрос тогда - что делать для инъекции зависимостей и DBAL? Все примеры, которые я нахожу, относятся к полной структуре Symfony и заставляют меня задерживаться.

+0

Учитывая, что вы новичок в S2, я бы предложил перейти с полным фреймворком только для начала. Получите приложение и немного поработайте над использованием компонентов. Тогда вы можете попытаться вырезать материал. Особенно, если вы хотите получить доступ к DBAL Doctrine 2. Конфигурация для этого немного больна. – Cerad

ответ

1

Если ваша команда расширяет ContainerAwareCommand

... 
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; 
... 

class MyCommand extends ContainerAwareCommand 
{ 

Контейнер DI можно с помощью метода getContainer(). (Например, в стандартном контроллере), например:

$this->validator = $this->getContainer()->get('validator'); 
+0

Благодарим вас за ответ. Как закончен объект приложения, построенный для указанного выше фрагмента?Когда я попробовал то, что вы предлагаете, у меня возникла ошибка, о которой я упоминал в моем вопросе (метод Application :: getKernel() не найден). Это имеет смысл, потому что приложение, которое я создавал, было экземпляром Symfony \ Component \ Console \ Application, у которого нет ядра –

+1

. Вы не используете полную структуру стека? Так что это нормально, вам нужно будет самостоятельно построить контейнер и ввести его в команду. – COil

+1

Нет, я нет! Приложение недостаточно велико, чтобы принести тяжелые пушки. Это вопрос, о котором идет речь. По какой-то причине документация очень расплывчата по этому поводу. Таким образом, Symfony \ Component \ Console \ Application не имеет никакого контейнера, кроме того, что мы создаем для себя. –

3

Только быстрое обновление на моем прогрессе, если кто-нибудь натыкается на одних и тех же проблем.

  1. Я включил в свой проект фреймворк зависимости зависимостей PHP-DI, который, кажется, работает достаточно хорошо, без конфигурации (пока) - на самом деле он довольно много отражает отражение.
  2. Точно так же Doctrine \ DBAL включен как отдельная библиотека (я выбрал ее часть O/RM, поскольку это действительно крошечный проект, и я нахожусь на гораздо более устойчивой основе с SQL, чем что-либо еще) и соединение просто возвращается поставщиком соединений, который вводится там, где это требуется DI.

Одна вещь, которую я не мог понять, как иметь классы команд инстанцированы библиотекой DI без моей помощи, так что я на самом деле должен был впрыснуть сам контейнер в мой переопределенном класса приложения и переопределить getDefaultCommands() где я затем вытащите экземпляры из контейнера вручную. Не идеально, но придется делать пока.

+3

Привет, автор PHP-DI здесь. Ниже приведен пример использования этого компонента с компонентом Symfony Console (вне рамок Symfony): https://github.com/mnapoli/IsItMaintained/blob/master/bin/console. Если у вас есть какие-либо вопросы, задайте его в StackOverflow с помощью тег 'php-di' или голова в чате: https://gitter.im/mnapoli/PHP-DI –

+0

Спасибо за ссылку. Ну, я закончил делать что-то подобное, за исключением того, что я начал (даже до интеграции DI), создав некоторые команды, созданные по умолчанию в классе приложения. Итак, чтобы продолжить по этому пути, я должен был вставить контейнер в класс приложения и вытащить там экземпляры команд. Пока что все в порядке. –

0

Я не знаю, является ли ваш вопрос по-прежнему актуальным, но у меня есть ответ, когда я наткнулся на одну и ту же проблему.

Вам просто нужно создать ядро ​​самостоятельно и передать его в \ Symfony \ Bundle \ FrameworkBundle \ Console \ Application, который расширяет базовый \ Symfony \ Component \ Console \ Application.

<?php 
// CronRun.php 

require __DIR__.'/../../../../vendor/autoload.php'; 
require_once __DIR__.'/../../../../app/AppKernel.php'; 

$kernel = new AppKernel('prod', false); 
$kernel->loadClassCache(); 

$application = new \Symfony\Bundle\FrameworkBundle\Console\Application($kernel); 
$application->add(new \KingdomHall\TaskBundle\Command\CronCommand()); 
$input = new \Symfony\Component\Console\Input\StringInput('k:c:r'); 
$application->run($input); 
Смежные вопросы