ThinkPHP 6+ 自定义命令需同时满足四个条件才能被 php think 识别:继承 think\console\Command、置于 app/command/ 目录、实现 configure() 和 execute() 方法、类名与文件名严格一致;任一缺失均导致 php think list 不显示或静默失败。

ThinkPHP 6+ 的自定义命令能被 php think 正确识别,前提是它满足四个硬性条件:继承 think\console\Command、放在 app/command/ 目录下、实现 configure() 和 execute() 方法、且类名与文件名完全一致。缺一不可,漏一个就静默失败——php think list 不显示,运行时报 Class not found for command 或直接空白输出。
为什么 php think list 不显示你的命令
最常见原因是框架压根没加载到这个类,而不是“注册失败”。ThinkPHP 只扫描 app/command/ 下继承 think\console\Command 的类,不看其他路径,也不认旧版命名空间(比如 think\command\Command)。
- 检查文件是否真在
app/command/Hello.php,不是app/command/hello.php(Linux 下大小写敏感) - 确认类定义是
class Hello extends \think\console\Command,不是extends \think\command\Command - 运行
composer dump-autoload强制刷新自动加载,尤其改过命名空间或移动过文件后 - 如果用了
app/command.php手动注册,确保返回数组里包含'hello' => app\command\Hello::class,键名就是命令名
configure() 里 setName() 和 addArgument() 必须写全
configure() 不只是“配个名字”,它是命令的元信息契约。框架靠它决定参数怎么解析、命令怎么展示,漏掉任何一项都会导致后续逻辑失效。
-
$this->setName('clear:log')必须调用,且只能是小写字母+冒号,不能有空格或大写 - 所有要用的参数都得提前声明:
$this->addArgument('table', \think\console\Input::ARG_REQUIRED, '表名'),否则$input->getArgument('table')永远返回null - 选项同理:
$this->addOption('force', 'f', \think\console\Input::OPTION_NONE, '强制执行'),短选项字母必须小写单字符 - 别在
configure()里 throw 异常,哪怕只是调试用的throw new \Exception('test'),会导致命令实例化中断,后续execute()调用时对象为null
execute() 是唯一入口,别碰 handle()
TP6 命令类没有 handle() 方法。如果你看到示例写了它,基本是 Laravel 或 TP5 的写法混进来了。写错成 handle() 不会报错,但命令运行时什么也不做,输出完全空白——这是最隐蔽的“没反应”问题。
立即学习“PHP免费学习笔记(深入)”;
- 所有业务逻辑必须写在
execute(Input $input, Output $output)里 - 参数取值严格按声明名来:
$input->getArgument('name'),不是$this->argument('name')(那是 Laravel 风格) - 输出统一用
$output->writeln('done'),避免echo或var_dump,否则在 CI 环境或管道中可能破坏格式 - 如果命令需要完整应用上下文(比如调用模型、Db、Cache),开头加一句
$this->app->initialize(),否则某些 Facade 可能未初始化
crontab 调用时 pwd 和环境变量容易被忽略
计划任务里直接写 php think clear:log 会失败,因为系统找不到 think 文件,也读不到项目根目录下的 .env 和自动加载配置。
- crontab 必须先
cd /path/to/your/project,再执行php think clear:log - 推荐写成绝对路径:
/usr/bin/php /data/wwwroot/myapp/php think clear:log - 如果依赖
.env中的配置(比如数据库密码),确保 crontab 执行用户有读取权限,或显式指定环境:APP_ENV=production php think clear:log - 防重复执行不能只靠逻辑判断,建议加
flock锁或临时 lock 文件,否则高频率定时任务可能并发冲突
真正卡住人的地方往往不是逻辑写错,而是 configure() 少了一行 addArgument(),或是文件名和类名差了一个大小写,又或者 crontab 没切对目录——这些细节不报错,只让命令“消失”。



















