本文目录导读:

我来详细介绍PHP Symfony框架中控制台命令的创建和使用。
创建控制台命令
基础命令类
// src/Command/MyCustomCommand.php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class MyCustomCommand extends Command
{
// 命令名称(必需)
protected static $defaultName = 'app:my-custom';
protected function configure()
{
$this
->setDescription('执行自定义任务')
->setHelp('这个命令用于执行特定的业务逻辑')
// 添加参数
->addArgument('name', InputArgument::REQUIRED, '用户名称')
->addArgument('age', InputArgument::OPTIONAL, '年龄', 25)
// 添加选项
->addOption('format', 'f', InputOption::VALUE_REQUIRED, '输出格式(json/text)', 'text')
->addOption('verbose', 'v', InputOption::VALUE_NONE, '是否详细输出');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
// 获取参数
$name = $input->getArgument('name');
$age = $input->getArgument('age');
$format = $input->getOption('format');
$isVerbose = $input->getOption('verbose');
// 输出信息
$output->writeln('<info>开始执行命令...</info>');
if ($isVerbose) {
$output->writeln(sprintf('处理用户: %s (年龄: %d)', $name, $age));
}
// 根据格式输出
if ($format === 'json') {
$output->writeln(json_encode([
'name' => $name,
'age' => $age,
'message' => '执行成功'
]));
} else {
$output->writeln('<comment>任务完成!</comment>');
}
// 返回执行状态
return Command::SUCCESS; // 或 Command::FAILURE
}
}
运行命令
# 基本用法 php bin/console app:my-custom John # 带参数 php bin/console app:my-custom John 30 # 带选项 php bin/console app:my-custom John --format=json -v # 查看帮助 php bin/console help app:my-custom
实用命令示例
数据库相关命令
// src/Command/DatabaseCleanupCommand.php
class DatabaseCleanupCommand extends Command
{
protected static $defaultName = 'app:cleanup-database';
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
parent::__construct();
}
protected function configure()
{
$this
->setDescription('清理过期数据')
->addOption('days', null, InputOption::VALUE_REQUIRED, '保留天数', 30);
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$days = $input->getOption('days');
$date = new \DateTime("-{$days} days");
// 删除过期日志
$logs = $this->entityManager
->getRepository(Log::class)
->createQueryBuilder('l')
->delete()
->where('l.createdAt < :date')
->setParameter('date', $date)
->getQuery()
->execute();
$output->writeln(sprintf('已删除 %d 条过期记录', $logs));
return Command::SUCCESS;
}
}
数据导入命令
// src/Command/ImportUsersCommand.php
class ImportUsersCommand extends Command
{
protected static $defaultName = 'app:import-users';
private $entityManager;
private $projectDir;
public function __construct(EntityManagerInterface $entityManager, string $projectDir)
{
$this->entityManager = $entityManager;
$this->projectDir = $projectDir;
parent::__construct();
}
protected function configure()
{
$this
->setDescription('从CSV文件导入用户')
->addArgument('file', InputArgument::REQUIRED, 'CSV文件路径');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$file = $input->getArgument('file');
// 创建进度条
$progress = new ProgressBar($output, 100);
$progress->start();
if (!file_exists($file)) {
$output->writeln("<error>文件不存在: {$file}</error>");
return Command::FAILURE;
}
$handle = fopen($file, 'r');
$headers = fgetcsv($handle);
$count = 0;
while (($row = fgetcsv($handle)) !== false) {
$user = new User();
$user->setName($row[0]);
$user->setEmail($row[1]);
$this->entityManager->persist($user);
$count++;
// 批量刷新
if ($count % 20 === 0) {
$this->entityManager->flush();
$progress->advance();
}
}
fclose($handle);
$this->entityManager->flush();
$progress->finish();
$output->writeln("\n<info>成功导入 {$count} 个用户</info>");
return Command::SUCCESS;
}
}
高级特性
命令分组
// 将命令分组 protected static $defaultName = 'user:create'; protected static $defaultName = 'user:delete'; protected static $defaultName = 'email:send';
交互式输入
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Question\ConfirmationQuestion;
protected function execute(InputInterface $input, OutputInterface $output): int
{
$helper = $this->getHelper('question');
// 确认问题
$question = new ConfirmationQuestion(
'确定要执行此操作吗? (y/n) ',
false
);
if (!$helper->ask($input, $output, $question)) {
$output->writeln('<error>操作已取消</error>');
return Command::SUCCESS;
}
// 隐藏输入(如密码)
$question = new Question('请输入密码: ');
$question->setHidden(true);
$question->setHiddenFallback(false);
$password = $helper->ask($input, $output, $question);
return Command::SUCCESS;
}
表格输出
use Symfony\Component\Console\Helper\Table;
protected function execute(InputInterface $input, OutputInterface $output): int
{
$table = new Table($output);
$table
->setHeaders(['ID', '名称', '邮箱'])
->setRows([
[1, '张三', 'zhangsan@example.com'],
[2, '李四', 'lisi@example.com'],
]);
$table->render();
return Command::SUCCESS;
}
定时任务(Cron)
在 config/services.yaml 中配置:
services:
App\Command\MyScheduledCommand:
tags:
- { name: console.command }
Crontab配置:
# 每天凌晨2点执行 0 2 * * * /usr/bin/php /path/to/project/bin/console app:cleanup-database --days=30 # 每小时执行 0 * * * * /usr/bin/php /path/to/project/bin/console app:send-emails
这些命令可以帮助你自动化各种任务,从简单的数据处理到复杂的业务逻辑实现。