Maker Bundle 生成命令后必须手动修改 configure() 中的 setName() 才能使用冒号分隔的命令名(如 app:backup:users),因默认只支持短横线;且文件路径、类名、命名空间须严格遵循约定:src/Command/XxxCommand.php、XxxCommand 结尾、App\Command 命名空间并继承 Command,否则命令不会被自动发现。

能直接用 make:command 生成,但生成后必须手动改 configure() 里的 setName() 才能得到类似 app:backup:users 这种冒号分隔的命令名——Maker Bundle 默认只认短横线,不解析冒号。
命令类放哪、叫啥名、继承谁
三个硬性条件缺一不可:
- 文件路径必须是
src/Command/GreetCommand.php,不能是src/Console/或src/Commands/ - 类名必须以
Command结尾,比如GreetCommand,不能是Greet或GreetConsole - 命名空间必须是
App\Command,且必须extends Command
违反任意一条,php bin/console 就不会列出这个命令——自动发现机制只认这个约定,不报错,也不提示。
configure() 里 setName() 和 addArgument() 的坑
setName() 是唯一强制要求调用的方法,其它如 setDescription()、addArgument() 都是可选的,但一旦用了 addArgument(),就必须在 execute() 中用 $input->getArgument('name') 读取,不能用 $_SERVER 或全局变量。
- 命令名允许冒号(如
app:sync:user),但禁止空格、斜杠、反斜杠 - 参数声明时若设为
InputArgument::REQUIRED,运行时不传就会直接退出并报错,不会进execute() - 选项(
addOption())默认是可选的,但若声明了InputOption::VALUE_REQUIRED却没给值,也会报错
execute() 返回值和输出方式
execute() 必须返回 int,0 表示成功,非 0(比如 1)表示失败。Shell 脚本或 CI 流程依赖这个返回值判断是否继续执行。
- 输出必须用
$output->writeln('Done!'),不能用echo或var_dump—— 否则颜色、换行、测试断言全失效 - 如果命令里要调用 Doctrine 或其他服务,直接在构造函数里类型提示即可,容器会自动注入;但别忘了加
public function __construct(YourService $service),否则会报Too few arguments - 不要在
execute()里写exit()或die(),这会让命令无法被测试或组合调用
Maker Bundle 生成后还要手动改什么
运行 php bin/console make:command app-backup-users 会生成 BackupUsersCommand.php,但它的 configure() 里默认是 $this->setName('app:backup-users')。如果你想要 app:backup:users,必须手动改成:
$this->setName('app:backup:users');
同时注意:类名还是 BackupUsersCommand,文件名也还是 BackupUsersCommand.php,命令名和类名完全解耦——这是最容易混淆的一点,也是调试时翻车最多的地方。


















