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

#symfony #symfony-2.3 #symfony-2.4

#symfony #symfony-2.3 #symfony-2.4

Вопрос:

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

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

Ну, я знаю, что это длинный вопрос. Если кто-то может сказать, что заставляет генерировать объекты, чтобы не создавать объекты, не выключая и не загружая команду ядра и 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 SymfonyComponentConsoleInputArrayInput(
            array('command' => 'doctrine:mapping:import', 'bundle' => 'TESTClientBundle', '--filter'
        => $filter, 'mapping-type' => 'yml'));
    $app->doRun($input, new SymfonyComponentConsoleOutputConsoleOutput());
}
  

Код для ‘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 SymfonyComponentConsoleInputArrayInput(
            array('command' => 'doctrine:generate:entities', 'name' => 'TESTClientBundle',
        '--no-backup' => 'true'));
    $app->doRun($input, new SymfonyComponentConsoleOutputConsoleOutput());
}
  

Код для ‘doctrine:generate:form’

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

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

    $input = new SymfonyComponentConsoleInputArrayInput(
            array('command' => 'doctrine:generate:form', 'entity' => 'TESTVClientBundle:'.$entity.''));
    $app->doRun($input, new SymfonyComponentConsoleOutputConsoleOutput());
}
  

Заранее большое спасибо.
Приветствия!

Ответ №1:

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

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

Комментарии:

1. Спасибо за предупреждение. Выглядит интересно. Я попробую. Приветствия!

Ответ №2:

Прежде всего, я должен поблагодарить @vincecore за то, что он предупредил меня о компоненте процесса Symfony. Мне удалось обойти проблему с помощью компонента 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 SymfonyComponentProcessProcess($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();
    } 
}
  

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

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

Приветствия!

Комментарии:

1. Использовать Process лучше, но как запустить более одной команды в контроллере? Вот в чем вопрос.

2. @VincentGuyard вышеупомянутая функция уже находится внутри контроллера. Посмотрите на это поближе. Приветствия 🙂

3. Когда я выполняю команду с помощью new Process(), мой php зависает и не позволяет мне выполнить другую команду. Что я сделал, так это выполнил все мои команды только в одну, используя «amp;amp; » между каждой из них. (Да, я знаю, ваш код находится внутри контроллера)