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

命令类必须继承 think\console\Command 才能被识别
不继承这个基类,php think xxx 就完全找不到你的命令——框架启动时只扫描继承自 think\console\Command 的类,并调用其 configure() 和 execute() 方法。
常见错误包括:
- 写了个普通类,没继承任何东西
- 误继承了已废弃的
think\command\Command(TP5 路径,TP6 不再支持) - 类名写了
SendEmailCommand,但文件名是SendEmail.php,命名不一致导致自动发现失败
实操建议:
- 确认使用的是 TP6+,命名空间必须是
think\console\Command - 类名末尾不强制加
Command后缀,但文件名必须与类名完全一致 -
configure()中必须调用$this->setName('send:email'),否则命令注册静默失败,不会报错
configure() 里必须显式声明所有参数和选项
ThinkPHP 不支持运行时动态解析未声明的参数。比如执行 php think send:email --to=admin@example.com,但没在 configure() 中调用 $this->addOption('to'),那取出来永远是 null,且无提示。
参数和选项要分开声明:
- 位置参数(如
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、print_r——这些在 CLI SAPI 下可能被缓冲、截断,CI 环境中甚至触发异常
命令注册后不生效?先查 app/command.php 和缓存
现象:类写对了、继承对了、setName() 也写了,但 php think list 就是看不到你的命令。
最常见原因是手动改过 app/command.php,关掉了自动发现。TP6 默认启用自动发现(扫描 app/command/ 目录),但一旦你返回空数组或覆盖默认结构,就会失效。
实操建议:
- 最简安全写法是让
app/command.php直接return [];,交由框架自动扫描 - 如果手动注册,格式必须是
['send:email' => \app\common\command\SendEmail::class],键是命令名,值是完整类名字符串(不是对象实例) - 每次修改命令类或配置后,必须运行
php think clear清缓存,否则旧命令列表可能被缓存住
参数声明和输出方式这两个点,最容易被当成“小细节”跳过,结果卡半天才意识到是 getOption() 拿不到值,或是 echo 导致 CI 流水线挂掉。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











