Ответ
Да, регулярно создаю консольные команды в Symfony для различных задач: обработка данных, миграции, cron-задачи и утилиты администрирования.
Структура команды:
// src/Command/ProcessOrdersCommand.php
namespace AppCommand;
use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;
use SymfonyComponentConsoleInputInputArgument;
use AppServiceOrderProcessor;
class ProcessOrdersCommand extends Command
{
protected static $defaultName = 'app:orders:process';
protected static $defaultDescription = 'Process pending orders';
private OrderProcessor $orderProcessor;
public function __construct(OrderProcessor $orderProcessor)
{
$this->orderProcessor = $orderProcessor;
parent::__construct();
}
protected function configure(): void
{
$this->addArgument('date', InputArgument::OPTIONAL, 'Process date (Y-m-d)', date('Y-m-d'));
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$date = $input->getArgument('date');
$output->writeln(sprintf('<info>Processing orders for %s</info>', $date));
$processed = $this->orderProcessor->processByDate($date);
$output->writeln(sprintf('<comment>Processed %d orders</comment>', $processed));
return Command::SUCCESS;
}
}
Ключевые особенности:
- Внедрение зависимостей — команды полноценные сервисы с DI
- Стили вывода —
<info>,<error>,<comment>для форматирования - Прогресс-бар —
ProgressBarдля длительных операций - Вопросы —
QuestionHelperдля интерактивного ввода - Тестирование —
CommandTesterдля юнит-тестов - Логирование — интеграция с Monolog через
LoggerAwareInterface
Ответ 18+ 🔞
Бля, ну вот смотри, регулярно приходится эти консольные команды в Symfony пилить. То данные обработать, то миграции какие, то по крону задачи запустить, то админские утилиты. В общем, работа такая, ёпта.
Структура, бля, команды:
// src/Command/ProcessOrdersCommand.php
namespace AppCommand;
use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;
use SymfonyComponentConsoleInputInputArgument;
use AppServiceOrderProcessor;
class ProcessOrdersCommand extends Command
{
protected static $defaultName = 'app:orders:process';
protected static $defaultDescription = 'Process pending orders';
private OrderProcessor $orderProcessor;
public function __construct(OrderProcessor $orderProcessor)
{
$this->orderProcessor = $orderProcessor;
parent::__construct();
}
protected function configure(): void
{
$this->addArgument('date', InputArgument::OPTIONAL, 'Process date (Y-m-d)', date('Y-m-d'));
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$date = $input->getArgument('date');
$output->writeln(sprintf('<info>Processing orders for %s</info>', $date));
$processed = $this->orderProcessor->processByDate($date);
$output->writeln(sprintf('<comment>Processed %d orders</comment>', $processed));
return Command::SUCCESS;
}
}
А теперь, сука, самое интересное — ключевые фишки, которые надо знать, чтобы не быть распиздяем:
- Внедрение зависимостей — это не просто какой-то там класс, это полноценный сервис, ёб твою мать. Все зависимости автоматом подтягиваются, красота.
- Стили вывода — вот это вообще песня.
<info>,<error>,<comment>— сразу видно, где успех, а где всё накрылось медным тазом. Без этого в консоли — манда с ушами. - Прогресс-бар — если операция долгая, как будто на дворе 2002-й год и ты ждёшь загрузки, то юзай
ProgressBar. А то пользователь подумает, что всё в пизду полетело. - Вопросы —
QuestionHelperдля интерактива. Типа «Ты уверен, чувак?». Доверия ебать ноль к юзеру, лучше переспросить. - Тестирование —
CommandTesterв помощь. Чтобы потом не орать «какого хуя не работает?!», когда на проде всё ебанько. - Логирование — через
LoggerAwareInterfaceс Monolog'ом. Чтобы потом, если что, не бздеть, а знать, где и что взъебнулось.
Вот так вот, коротко и по делу. Главное — не выёбывайся со сложной логикой прямо в команде, выноси в сервисы. А то получится пиздопроебибна, а не команда.