FrankenPHP独立二进制不控制缓存目录,所有缓存(OPcache、上传临时文件、应用层缓存)均由PHP配置或应用代码决定:OPcache为内存型,需调优memory_consumption与max_accelerated_files;upload_tmp_dir须显式配置并赋权;应用缓存目录如Laravel的storage/framework/cache需手动建目录并设www-data权限。

FrankenPHP 独立二进制运行时,缓存目录由 PHP 自身机制决定,不是 FrankenPHP 直接控制
FrankenPHP 作为 PHP SAPI(embed 或 cli 模式)运行,它本身不提供“缓存目录”配置项;所有缓存行为(OPcache、上传临时文件、Composer 缓存、应用层文件缓存)都依赖底层 PHP 配置或应用代码显式指定路径。你看到的“缓存目录”其实是多个不同层级缓存的集合,必须分清楚谁在用、谁在管。
OPcache 缓存不需要设“目录”,但必须配对 memory_consumption 和 max_accelerated_files
OPcache 是内存型缓存,不写磁盘目录。但它需要足够大的共享内存块来存放编译后的 opcode,否则会频繁 OOM(oom_count > 0)。常见误操作是以为改个路径就能扩容——实际无效。
-
opcache.memory_consumption=256:单位 MB,建议 Laravel/Symfony 类项目设为384~512 -
opcache.max_accelerated_files=20000:必须 ≥ 项目实际 PHP 文件数(Composer autoload 后常超 15000) -
opcache.revalidate_freq=60:生产环境别设为 0,否则每次请求都 stat 所有文件,IO 暴涨 - 验证是否生效:
php -r "print_r(opcache_get_status()['opcache_statistics']);",重点看oom_count和cached_scripts
上传临时文件目录(upload_tmp_dir)必须显式配置并赋权
FrankenPHP 独立运行时,默认用系统 /tmp,但进程用户(如 www-data)可能无写权限,导致 “Failed to write to temporary directory” 错误。不能靠 chmod 777 /tmp 解决,要隔离路径。
- 创建专用目录:
sudo mkdir -p /var/tmp/frankenphp-upload - 赋权:
sudo chown www-data:www-data /var/tmp/frankenphp-upload && sudo chmod 755 /var/tmp/frankenphp-upload - 在 php.ini 中设置:
upload_tmp_dir = "/var/tmp/frankenphp-upload" - 重启 FrankenPHP(
frankenphp run或systemctl restart frankenphp) - 验证:
php -r "echo ini_get('upload_tmp_dir');",再用sudo -u www-data touch /var/tmp/frankenphp-upload/test测试写入
应用层缓存(如 Laravel 的 storage/framework/cache、TP6 的 HTML_PATH)必须手动建目录 + 设权限
这些路径由框架自己定义,FrankenPHP 不干涉。但若权限不对,缓存写入失败不会报错,只会静默降级——比如 Laravel 返回未缓存响应,TP6 生成空 HTML 文件。
立即学习“PHP免费学习笔记(深入)”;
- Laravel:确保
storage/framework/cache和storage/framework/views属主为www-data,权限755(目录)/644(文件) - ThinkPHP 6:静态缓存默认写
public/html/,不是runtime/;需sudo chown -R deploy:www-data public/html+chmod -R 750 public/html - 自定义缓存目录(如
define('CACHE_DIR', __DIR__ . '/cache')):必须提前mkdir -p cache && chmod 755 cache,且确保运行用户可写 - 永远别信 “目录存在就 OK” —— 要用
sudo -u www-data php -r "file_put_contents('cache/test', 'ok');"实测写入
opcache_reset() 只清当前 worker,而上传临时目录权限错误会导致 multipart 解析直接失败,但错误日志里只显示 “no file uploaded”。这两处不验证,线上缓存问题基本无法定位。



















