ThinkPHP6.x 本身不内置守护进程式定时调度器,实现可靠周期性任务必须借助系统级 Crontab,再通过框架提供的命令行能力执行业务逻辑:先编写继承 think\console\Command 的命令类并注册,再用 crontab 定期调用 php think 命令,注意指定 PHP 绝对路径、项目根目录及日志重定向。

ThinkPHP6.x 本身不内置守护进程式定时调度器,实现可靠周期性任务必须借助系统级 Crontab,再通过框架提供的命令行能力来执行业务逻辑。核心思路是:把业务封装成可调用的 console 命令,再由 Crontab 定期触发该命令。
一、编写可被调用的 ThinkPHP 命令类
在 app/command/ 目录下新建一个 PHP 类,例如 SyncUserStats.php:
- 命名空间必须为 app\command,且继承 think\console\Command
- 在 configure() 方法中调用
$this->setName('cron:sync-user-stats')设定命令名,后续 Crontab 就靠它调用 - execute() 方法里写真实业务,比如查询数据库、调用模型、写缓存、发通知等——TP6 的容器、配置、Db、Model 全部可用
- 不要用
exit()或die(),统一用return 0;表示成功,非零值表示异常 - 日志建议用
trace('start', 'cron')或写入runtime/log/cron/下专用文件,比 echo 更可控
二、确保命令能在终端正常运行
先手动测试,避免直接上 Crontab 后失败无感知:
- 进入项目根目录,执行:
php think cron:sync-user-stats - 确认输出符合预期,且没有报错(如 Class not found、Undefined index: HTTP_HOST)
- 若报错“HTTP_HOST”,说明某处误用了 Request 实例——命令行环境无 HTTP 上下文,应移除或加判断
- 若报错自动加载失败,检查
think文件头部是否已引入vendor/autoload.php
三、配置 Crontab 并注意运行环境
Crontab 不读取用户 shell 环境变量,默认工作目录是 /root,所以路径和环境必须显式声明:
立即学习“PHP免费学习笔记(深入)”;
- 执行
crontab -e编辑当前用户的定时任务 - 推荐写法(以每小时整点执行为例):
0 * * * * cd /var/www/myproject && /usr/bin/php think cron:sync-user-stats >> runtime/log/cron/sync.log 2>&1 - 务必使用 PHP 绝对路径(用
which php查看),避免 crontab 找不到解释器 - cd 切到项目根目录 很关键,否则 think 命令无法正确加载 config/ 和 runtime/
-
>> xxx.log 2>&1把标准输出和错误都重定向到日志,这是排查静默失败的第一依据
四、线上部署常见避坑点
多个 ThinkPHP 应用共存或权限受限时,容易出问题:
- 别用
sudo crontab -e统一管理所有项目——不同应用应切换到对应部署用户(如 www-data)再执行crontab -e,隔离路径与权限 - runtime/ 和 log/ 目录需保证该用户有读写权限,否则日志写不进、缓存清不了
- 不要在 execute() 里写死相对路径(如
../config/db.php),一律用 TP6 提供的Env::get()或Config::get() - 如需防并发重复执行,可在命令开头加文件锁或数据库锁,TP6 自带的
think-lock可配合使用



















