#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; » между каждой из них. (Да, я знаю, ваш код находится внутри контроллера)