命令类必须继承think\console\Command,否则php think无法识别;框架仅扫描该基类子类并调用configure()和execute()方法,常见错误包括未继承、误继承废弃类、文件名与类名不一致、configure()未设命令名或未声明参数选项。

命令类必须继承 think\console\Command
不继承这个基类,php think 就完全找不到你的命令——框架只扫描继承自 think\console\Command 的类,并调用其 configure() 和 execute() 方法。
常见错误包括:
- 写了个普通类,没继承任何东西
- 误继承了已废弃的
think\command\Command(TP5 路径,TP6 不再支持) - 类名是
SendEmailCommand,但文件名是SendEmail.php,命名不一致导致自动发现失败
实操建议:
- 确认使用的是 TP6+,命名空间必须是
think\console\Command - 类名末尾不强制加
Command后缀,但文件名必须与类名完全一致(如SendEmail.php里定义class SendEmail extends Command) - 如果手动注册命令,类必须放在
app/command/目录下,且命名空间为app\command
configure() 里必须显式声明所有参数和选项
ThinkPHP 不支持运行时动态解析未声明的参数。比如执行 php think send:email --to=admin@example.com,但没在 configure() 中调用 $this->addOption('to'),那取出来永远是 null,且无提示。
立即学习“PHP免费学习笔记(深入)”;
参数和选项要分开声明:
- 位置参数(如
php think make:controller User中的User)用$this->addArgument('name', Argument::REQUIRED, '控制器名称') - 选项参数(如
--force或--limit=100)用$this->addOption('force', 'f', Option::VALUE_NONE, '强制覆盖') - 短选项字母必须小写、单字符;长选项名用中划线(
dry-run),不能用下划线 - 布尔选项(
--force)默认值是null,判断时直接写if ($input->getOption('force')),别写=== true - 带值选项必须设
Option::VALUE_REQUIRED或Option::VALUE_OPTIONAL,否则即使传了值也拿不到
execute() 是唯一入口,别写 handle()
TP6 命令类没有 handle() 方法。如果你看到文档或示例里写了它,基本是混淆了 Laravel 或 TP5 的写法。真正被框架调用的只有 execute(Input $input, Output $output)。
写错成 handle() 不会报错,但命令运行时什么也不做,输出空白——这是最隐蔽的“没反应”问题来源之一。
获取参数只能用:
-
$input->getArgument('name')(不是$this->argument(),那是 Laravel 风格) $input->getOption('force')
输出必须用 $output 实例:
- 用
$output->writeln('done')或$output->success('ok') - 禁用
echo、var_dump,尤其在管道或 CI 环境中可能引发异常
命令注册后不生效?先检查 app/command.php 和缓存
TP6 默认启用命令自动发现(扫描 app/command 目录),但一旦你手动改过 app/command.php,就可能关掉它。现象是:类写对了、继承对了、命名也规范,可 php think list 就是看不到你的命令。
实操建议:
- 确认
app/command.php返回的是数组,且没清空或覆盖默认配置;最简安全写法是直接return [];,让框架走自动发现 - 如果手动注册,格式必须是
['send:email' => app\common\command\SendEmail::class],键是命令名,值是完整类名字符串,不能是对象实例 - 修改后记得清缓存:
php think clear,否则旧的命令列表可能被缓存住 - 运行
php think list,确认你的命令出现在输出里——这是唯一可信的验证方式
真正容易被忽略的是:命令类里 configure() 没调用 $this->setName('send:email'),会导致注册静默失败,没有任何报错提示。



















