thinkphp 8.1 的 schedule:run 命令本身不主动运行定时任务,仅检查并执行已到时间的任务,必须由系统级 cron 主动调用才能生效;若未配置或未启动 cron 服务、未用绝对路径调用 php、未在 app/config/console.php 中启用 'scheduling' => true、未设置正确环境变量(如 app_env=local 调试时)、或自定义命令未严格按路径/命名空间/注册规范配置,均会导致静默失败。

think schedule:run 不跑,90%不是框架没装好,而是根本没被触发——ThinkPHP 8.1 本身不运行定时任务,它只提供一个「检查并执行已到时间的任务」的命令,必须靠系统级 cron 主动调用才能生效。
cron 没配或没跑,schedule:run 就永远静默
cron服务状态必须是active (running):sudo systemctl status cron(Ubuntu/Debian)或sudo systemctl status crond(CentOS/RHEL)
如果是inactive (dead),立刻sudo systemctl start cron-
crontab -e里写的那行,得真正在生效:- 用
crontab -l确认内容已保存 - 用
sudo tail -f /var/log/cron观察是否出现CMD记录(比如加个测试项:<em> </em> <em> </em> * date >> /tmp/cron_test.log)
- 用
-
不要写
php think schedule:run:-
php是相对路径,cron默认 PATH 极窄(只有/usr/bin:/bin) - 必须用绝对路径,先
which php查到如/usr/local/bin/php,再写进 crontab:<em>/5 </em> <em> </em> * cd /var/www/myapp && /usr/local/bin/php think schedule:run >> /var/www/myapp/runtime/log/schedule-cron.log 2>&1
-
scheduling 配置没开,schedule:run 直接跳过所有任务
打开
app/config/console.php,确认有:'scheduling' => true
缺了这行,哪怕 cron 调用了,schedule:run也会直接返回 “No scheduled commands are ready to run”-
ThinkPHP 8.1 默认只在
APP_ENV=production下允许调度执行:- 开发调试时,必须显式传环境变量:
APP_ENV=local /usr/local/bin/php think schedule:run -v - 或临时改
.env文件里的APP_ENV=local(上线前务必改回)
- 开发调试时,必须显式传环境变量:
自定义命令没注册,schedule:run 根本看不到它
命令类必须放在
app/command/(注意是小写command,不是Console/Commands)命名空间必须是
app\command,类名与文件名严格一致(如app/command/SyncData.php→ 类SyncData)必须继承
think\console\Command,并在configure()中调用$this->setName('sync:data')-
注册不是自动的,必须手动写进
app/command.php:<?php return ['app\command\SyncData']; ?>- 文件必须存在,且返回数组(空数组也要写
return [];) - 多个命令就追加字符串,不能漏反斜杠、不能多空格、不能大小写错
- 文件必须存在,且返回数组(空数组也要写
验证是否注册成功,唯一可靠方式是本地运行:
php think list→ 看输出里有没有sync:dataphp think sync:data→ 看是否真能执行(别跳过这步)
真正容易被忽略的是:cron 的工作目录默认是 /root,PATH 不包含项目依赖,也不加载 .env。哪怕所有代码都对,只要 cd 没写、php 路径不对、runtime 目录不可写,日志就全丢在黑洞里——所以每条 crontab 必须带 cd、绝对路径、完整重定向。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











