Запуск более одной консольной команды в контроллере Symfony 2

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

Я хочу запустить три существующие консольные команды в Symfony 2 с контроллера. Поэтому я написал для этого три отдельные функции (см. ниже). Мне удалось запустить 'doctrine:mapping:import' (код ниже) без каких-либо проблем внутри контроллера. Следующее, что я хотел сделать, это создать объекты на основе импортированных файлов сопоставления. Я не мог запустить команду 'doctrine:generate:entities' без выключения и загрузки ядра (я думаю, что это плохая идея, посмотрите на код ниже). Без выключения и загрузки ядра оно не будет генерировать сущности для меня. Но после выключения и загрузки ядра оно создает для меня сущности (теперь я немного счастлив). Следующая проблема, с которой я сталкиваюсь, возникает при запуске команды 'doctrine:generate:form' (код приведен ниже). Когда я запускаю этот код сразу после создания сущностей, он говорит: «Класс «ИМЯ МОЕГО КЛАССА» не существует». Этого не может быть. Потому что я запускаю команду сборки формы после создания объектов. Даже я пытаюсь найти класс, действительно ли он существует, физически обращаясь к файлу. И это там. Так что я полностью застрял здесь, я бы сказал.

Ну, я знаю, что это длинный вопрос. Если кто-то может сказать, что заставляет генерировать сущности не создавать сущности без выключения и загрузки команды kernal и form builder, которые не работают, даже файлы сущностей есть, это было бы действительно очень ценно. Однако я заметил одну вещь: эти команды (3 функции) отлично работают, когда я запускаю их по одной. Но я хочу вызывать эти 3 функции одну за другой. Итак, в основном проблема возникла, когда я последовательно вызываю эти 3 функции.

Код для 'doctrine:mapping:import'

public function executeImportCommandAction($filter)
{
    $kernel = $this->container->get('kernel');        
    $app = new Application($kernel);
    $app->setAutoExit(false);
    $input = new \Symfony\Component\Console\Input\ArrayInput(
            array('command' => 'doctrine:mapping:import', 'bundle' => 'TESTClientBundle', '--filter'
        => $filter, 'mapping-type' => 'yml'));
    $app->doRun($input, new \Symfony\Component\Console\Output\ConsoleOutput());
}

Код для 'doctrine:generate:entities'

public function executeBuildFormCommandActions($entity)
{
    $kernel = $this->container->get('kernel');        
    $kernel->shutdown();
    $kernel->boot();
    $app = new Application($kernel);       
    $app->setAutoExit(false);

    $input = new \Symfony\Component\Console\Input\ArrayInput(
            array('command' => 'doctrine:generate:entities', 'name' => 'TESTClientBundle',
        '--no-backup' => 'true'));
    $app->doRun($input, new \Symfony\Component\Console\Output\ConsoleOutput());
}

Код для «доктрины: генерировать: форма»

public function executeBuildFormCommandActions($entity)
{
    #$kernel = $this->container->get('kernel');        

    $app = new Application($kernel);
    $app->setAutoExit(false);

    $input = new \Symfony\Component\Console\Input\ArrayInput(
            array('command' => 'doctrine:generate:form', 'entity' => 'TESTVClientBundle:'.$entity.''));
    $app->doRun($input, new \Symfony\Component\Console\Output\ConsoleOutput());
}

Заранее большое спасибо. Ваше здоровье!


person Anjana Silva    schedule 20.06.2014    source источник


Ответы (2)


Знаете ли вы, что существует компонент процесса? http://symfony.com/doc/current/components/process.html

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

person vincecore    schedule 21.06.2014
comment
Спасибо за внимание. Выглядит интересно. Я попробую. Ваше здоровье! - person Anjana Silva; 22.06.2014

Прежде всего, я должен поблагодарить @vincecore за подсказку относительно компонента Symfony Process. Мне удалось обойти с помощью компонента Process, чтобы добиться того, чего я хотел достичь. Я предполагаю, что отключение загрузки ядра не является правильным подходом, хотя оно работает хорошо. Однако сгенерировать форму не получилось даже после работы с ядром. Это фрагмент кода, который я обнаружил работающим при запуске всех 'doctrine:mapping:import', 'doctrine:generate:entities' и 'doctrine:generate: form' консольные команды внутри контроллера. Для ясности я хотел бы проиллюстрировать код, связанный с созданием формы.

public function executeBuildFormCommandActions($form_file)
{
    $move_to_project = 'C:/xampp5.5.11/htdocs/proj_test/';
    $commandline = "php app/console doctrine:generate:form TESTClientBundle:$form_file";
    $form_type_file = $this->get('kernel')->getRootDir() . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'TEST'
            . DIRECTORY_SEPARATOR . 'ClientBundle' . DIRECTORY_SEPARATOR .
            'Form' . DIRECTORY_SEPARATOR . $form_file.'Type.php';
    if(is_file($form_type_file)){
        unlink($form_type_file);
    }        

    $process = new \Symfony\Component\Process\Process($commandline);
    $process->setWorkingDirectory($move_to_project);
    $process->run();        
    try {
        if (!$process->isSuccessful()) {                
            throw new \RuntimeException($process->getErrorOutput());
        }            
        echo $process->getOutput().'<hr/>';
    } catch (\RuntimeException $r) {
        echo $r->getMessage();
    } 
}

Преимущество этого подхода (компонент «Процесс») заключается в том, что вы можете напрямую выполнять команду во время ее выполнения с помощью командной консоли. Однако без установки рабочего каталога в папку проекта это не сработало в первую очередь. Это очевидно, и причина этого факта в том, что команда не может получить доступ к «приложению/консоли» где-либо за пределами папки проекта. Поэтому мне пришлось переместить консольные команды в папку проекта ($process->setWorkingDirectory($move_to_project)) как выполнение команд в папке проекта. Остальные две функции (импорт и создание сущностей) также одинаковы, меняются только команды и аргументы.

Надеюсь, это поможет кому-то, кто пытается и не находит удачи, когда дело доходит до запуска более чем одной командной консоли внутри контроллера Symfony 2.

Ваше здоровье!

person Anjana Silva    schedule 23.06.2014
comment
Использовать процесс лучше, но как запустить более одной команды в контроллере? Вот в чем вопрос. - person Vincent Guyard; 18.11.2016
comment
@VincentGuyard вышеуказанная функция уже находится внутри контроллера. Посмотрите на это поближе. Ваше здоровье :) - person Anjana Silva; 20.11.2016
comment
Когда я выполняю команду с помощью new Process(), мой php зависает и не позволяет мне выполнить другую команду. Что я сделал, так это выполнил все мои команды только в одной, используя && между каждым из них. (Да, я знаю, ваш код находится внутри контроллера) - person Vincent Guyard; 20.11.2016