需立即修正runtime/cache目录属主与权限:先用ps aux确认web用户(如www-data),再sudo chown -r www-data:www-data runtime/,接着sudo chmod -r 755 runtime/,并规范后台任务以同用户执行,防止root创建子目录导致权限污染。

ThinkPHP项目运行时突然报错 file_put_contents(): Permission denied,且错误路径指向 runtime/cache/xxx.php,说明缓存驱动因目录权限不足无法写入文件,必须立即修正属主与权限层级关系,否则所有依赖缓存的功能(如模板渲染、配置加载、会话存储)将陆续失效。
确认Web进程实际运行用户
先别急着改权限,得知道该把目录交给谁。在终端执行:ps aux | grep -E '(apache|httpd|php-fpm|nginx)' | grep -v grep | head -1,看输出行第2列的用户名(常见为 www-data、apache、www 或 nginx);若用宝塔面板,默认是 www;Docker 环境则需检查容器内 PHP 进程 UID,运行 id -u 和 id -g 获取数字 ID。
这一步漏掉会导致后续 chown 目标错误——把目录改给 root 或 deploy 用户,问题反而更顽固。
逐级检查 runtime 目录权限链
进入项目根目录,执行:ls -ld runtime runtime/cache,观察两行输出中第三列(Owner)和第四列(Group)是否与上一步确认的 Web 用户一致;再执行:ls -ld runtime/cache/* 2>/dev/null | head -3,抽查几个二级子目录(如 fa/、b2/),确认它们的属主是否也被污染成 root 或其他非 Web 用户。
【关键点】 ThinkPHP 动态创建子目录(如 runtime/cache/fa/)时,若父目录属主不是 Web 用户,新建子目录大概率继承错误属主,导致后续写入失败——这就是为什么只改 cache 目录权限没用。
递归重置属主并设置合理权限
第一步:以 root 或 sudo 权限执行属主修正(根据上一步确认的用户替换命令中的 www):sudo chown -R www:www runtime/。
第二步:设置目录权限为 755,确保 Web 用户可读可执行可进入,组和其他人仅可读可执行:sudo chmod -R 755 runtime/。
第三步:验证缓存文件能否生成,访问一个触发缓存写入的接口(如首页),然后检查 runtime/cache/ 下是否有新生成的 .php 文件,且其属主为 www;若仍有 Permission denied,说明某层目录被 SELinux 或 Docker 挂载参数锁定,需单独处理。
预防后台任务污染缓存目录
方法一:Crontab 中禁止 root 直接执行 php think 命令。把原定时任务:* * * * * /usr/bin/php /var/www/think clear 改为:* * * * * sudo -u www /usr/bin/php /var/www/think clear。
方法二:Supervisor 配置里显式指定 user 参数:user=www,避免守护进程以 root 启动后创建的子目录归属错误。
方法三:在 public/index.php 开头添加 umask(0002);,强制新建文件权限为 644、目录为 755,避免系统默认 umask 0022 导致组权限缺失——但这只是补丁,不能替代属主修正。
这一步不做,下次你手动清缓存或跑队列任务,fa/、b2/ 等子目录又会被 root 创建,问题重现。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











