ThinkPHP6子目录部署时定时任务需改三处:Crontab调用路径、工作目录、URL/资源路径逻辑;必须cd到项目根目录再执行think命令,确保runtime可写,并避免命令类中硬编码Web上下文路径。

ThinkPHP6 子目录部署(比如网站根目录是 /var/www/html,而 TP6 项目实际在 /var/www/html/app)时,定时任务不能直接用默认的 Crontab 配置,因为路径、入口文件位置、运行时环境都变了。关键要改三处:Crontab 调用路径、命令行工作目录、以及可能的 URL/资源路径逻辑。
调整 Crontab 中的执行路径和入口位置
子目录部署后,think 入口文件不再位于 Web 根目录,而是落在子目录内(如 /var/www/html/app/think)。Crontab 必须明确指定完整路径,并用 cd 切换到项目根目录再执行,否则框架无法正确加载配置和 runtime 目录。
- 错误写法(路径错、没切工作目录):
* * * * * /usr/bin/php /var/www/html/app/think mytask - 正确写法(显式 cd + 完整路径 + 重定向日志):
* * * * * cd /var/www/html/app && /usr/bin/php think mytask >> /var/www/html/app/runtime/log/cron.log 2>&1 - 注意确认
/usr/bin/php是服务器真实 PHP 路径,可用which php查看
确保 runtime 和日志目录权限可写
子目录部署常导致 runtime 目录实际路径变成 /var/www/html/app/runtime,但 Web 服务用户(如 www-data 或 nginx)和 Crontab 执行用户(如 root 或 deploy)可能不同,权限容易出问题。
- 给 runtime 目录加写权限:
chmod -R 755 /var/www/html/app/runtime(或更安全的775+ 设置组属主) - 检查日志是否生成:
手动执行一次cd /var/www/html/app && php think mytask,看runtime/log/下是否有输出 - 如果用宝塔面板,注意“网站根目录”和“项目实际路径”的区别,避免误设运行目录
命令类中避免硬编码 URL 或相对路径
子目录部署后,Web 访问地址可能是 https://example.com/app/,但命令行环境没有 Request 上下文,url() 或 request()->domain() 可能返回空或错误值。若任务里涉及生成链接、访问接口、读取静态资源,需主动适配。
- 不要依赖
url('index/index')生成前端链接;改用配置项:config('app.app_host') . '/index/index',并在config/app.php中设置'app_host' => 'https://example.com/app' - 读取本地文件别用
__DIR__ . '/../public/assets/xxx.jpg';改用Env::get('root_path') . 'public/assets/xxx.jpg',确保根路径准确 - 如果任务调用了需要 HTTP 上下文的功能(如某些中间件、行为钩子),建议该任务只做纯后台逻辑,不走 Web 生命周期
可选:用 shell 脚本封装,增强健壮性
子目录路径多层嵌套时,Crontab 单行易出错。推荐写一个 run_cron.sh 放在项目根目录(/var/www/html/app/run_cron.sh),内容如下:
#!/bin/bash
APP_PATH="/var/www/html/app"
cd "$APP_PATH" || exit 1
php think mytask >> runtime/log/cron_$(date +\%Y\%m\%d).log 2>&1
- 赋予执行权限:
chmod +x /var/www/html/app/run_cron.sh - Crontab 改为调用脚本:
* * * * * /var/www/html/app/run_cron.sh - 脚本能统一处理路径、错误退出、日志分天,比裸写命令更可控
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











