Как выполнить команду Symfony с контроллера

Существует множество причин, по которым вы должны выполнять консольные команды в контроллере, а не переписывать всю логику внутри контроллера. На самом деле, если вам нужно использовать один и тот же код в двух разных областях, вам может потребоваться изолировать эту логику и предоставить ее в службе. Затем в контроллере, как и в консоли, вы сможете получить доступ к контейнеру, запросить службу и выполнить ее. Однако что, если речь идет о логике стороннего комплекта? Вы не будете копировать код команды из пакета, а затем вставлять его в свой контроллер, черт возьми, нет. Вместо этого рекомендуется просто выполнить консольную команду с контроллера.

В этой статье вы узнаете, как использовать консольную команду непосредственно с вашего контроллера.

Прежде чем продолжить

В этом случае мы собираемся выполнить следующую команду (php bin/console app:print-lines --firstline="Hello" --secondline="World"):

setName('app:print-lines')
// the short description shown while running "php bin/console list"
->setHelp("This command allows you to print some text in the console")
// the full command description shown when running the command with
->setDescription('Prints some text into the console with given parameters.')
// Set options
->setDefinition(
new InputDefinition(array(
new InputOption('firstline', 'a', InputOption::VALUE_REQUIRED,"The first line to be printed","Default First Line Value"),
new InputOption('secondline', 'b', InputOption::VALUE_OPTIONAL,"The second line to be printed","Default First Line Value"),
))
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// outputs multiple lines to the console (adding "\n" at the end of each line)
$output->writeln([
'My Third Symfony command',// A line
'============',// Another line
'',// Empty line
]);
$firstLine = $input->getOption('firstline');
$secondline = $input->getOption('secondline');
$output->writeln("First line value : ".$firstLine);
if($secondline){
$output->writeln("Second line value : ".$secondline);
}
// Instead of retrieve line per line every option, you can get an array of all the providen options :
//$output->writeln(json_encode($input->getOptions()));
}
}

Реализация

Вы можете выполнить любую консольную команду из контроллера, если она не является динамической (команда, с которой вам нужно взаимодействовать) или команда, которая работает с файлами в вашем проекте (например, команда clear cache). От выполнения команды вы можете решить, получать ли вы ввод или нет:

С выходом

Чтобы выполнить команду внутри контроллера, используйте следующий код:

get('kernel');
$application = new Application($kernel);
$application->setAutoExit(false);
$input = new ArrayInput(array(
'command' => 'app:print-lines',
'--firstline' => "Hello",
'--secondline' => "World"
));
$output = new BufferedOutput();
$application->run($input, $output);
// return the output
$content = $output->fetch();
// Send the output of the console command as response
return new Response($content);
}
}

Предыдущий контроллер вернется в ответ "My Third Symfony command ============ First line value : Hello Second line value : World" в браузере.

Без выхода

Если вас не волнует сгенерированный вывод команды, потому что либо он не важен, либо он создает собственный журнал, вы можете игнорировать BufferedOutput, В этом случае, поскольку нет способа узнать, была ли команда успешно выполнена, пользовательская команда будет следующей (она создает текстовый файл в /web папку вашего проекта, чтобы убедиться, что команда была выполнена и с консоли можно выполнить с помощью php bin/console app:create-file-web --filename="test" --extension="txt"):

setName('app:create-file-web')
// the short description shown while running "php bin/console list"
->setHelp("This command creates a file")
// the full command description shown when running the command with
->setDescription('Creates a file with a custom filename')
// Set options
->setDefinition(
new InputDefinition(array(
new InputOption('filename', 'a', InputOption::VALUE_REQUIRED,"The filename","mytextfile"),
new InputOption('extension', 'b', InputOption::VALUE_OPTIONAL,"The extension of the file","txt"),
))
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$filename = $input->getOption('filename');
$extension = $input->getOption('extension');
$webFolder = $this->getContainer()->get('kernel')->getRootDir() . '/../web/';
// Create the file with custom name and extension in the /web path
$myfile = fopen($webFolder. "$filename.$extension", "w");
$txt = "Command succesfully executed";
fwrite($myfile, $txt);
fclose($myfile);
}
}

И это может быть выполнено из контроллера (без извлечения выходных данных), используя следующий код:

Заметка

BufferedOutput не используется вообще, и его необходимо заменить на NullOutput

get('kernel');
$application = new Application($kernel);
$application->setAutoExit(false);
$input = new ArrayInput(array(
'command' => 'app:create-file-web',
'--filename' => "test",
'--extension' => "txt"
));
// Use the NullOutput class instead of BufferedOutput.
$output = new NullOutput();
$application->run($input, $output);
return new Response("Command succesfully executed from the controller");
}
}

Контроллер должен вернуть в ответ «Команда успешно выполнена с контроллера» даже если это не было правильно выполнено. Чтобы проверить, действительно ли он был выполнен, убедитесь, что файл был создан в /web путь вашего проекта. Если вам нужна дополнительная информация о компоненте консоли, пожалуйста, прочитайте документацию здесь.

Ссылка на основную публикацию
Adblock
detector