apcu缓存解析后配置比每次解析快一个数量级,因opcache仅缓存字节码不缓存运行时解析结果;需用apcu_exists检查键存在性、合理设ttl、注意fpm与cli缓存隔离。

直接用 APCu 缓存解析后的配置数组,比每次 require 或 file_get_contents + parse_ini_file 快一个数量级,且无锁、无进程通信开销。
为什么不能只靠 OPcache 缓存配置文件?
OPcache 只缓存 PHP 脚本的字节码(比如 config.php),不缓存 parse_ini_file()、json_decode(file_get_contents(...)) 这类运行时解析结果。即使配置文件本身被 OPcache 加载得很快,每次请求仍要重复打开文件、读磁盘、解析结构——IO 和 CPU 开销都在。
- INI/JSON/YAML 文件每次读取都触发一次系统调用和磁盘寻道(尤其机械盘)
-
parse_ini_file(..., true)内部会做多次字符串扫描和数组构建,不可忽略 - 多个 worker 进程各自解析,内存中存多份相同配置,浪费 RAM
用 apcu_fetch + apcu_store 实现单次解析、全局复用
核心逻辑:首次读取时解析并存入 APCu;后续请求直接从共享内存取,跳过所有文件操作。
- 缓存键建议用配置文件路径的
md5或硬编码唯一字符串(如'app_config_v1'),避免键冲突 - 必须检查
apcu_exists($key)再读,否则apcu_fetch失败会返回false,容易误判为“空配置” - 若配置需热更新,不要设永久 TTL;可用
apcu_store($key, $data, 300)控制 5 分钟自动失效 - PHP 7.4 默认启用 APCu,但需确认
extension=apcu.so已加载,且apc.enabled=1
示例代码片段:
function loadCachedConfig($path) {
$key = 'config_' . md5($path);
if (apcu_exists($key)) {
return apcu_fetch($key);
}
$content = file_get_contents($path);
$data = json_decode($content, true); // 或 parse_ini_file($path, true)
apcu_store($key, $data, 600); // 缓存 10 分钟
return $data;
}
注意 APCu 在 CLI 和 FPM 下的行为差异
APCu 的共享内存是 per-process-group 的:FPM worker 之间共享,但 CLI 脚本每次启动都是独立进程,不共享缓存。这意味着:
- Web 请求走 FPM 时,
apcu_store写入后所有 worker 都能读到 - Artisan 命令或 cron 脚本跑在 CLI 模式下,
apcu_fetch永远为空(除非你显式开启apc.enable_cli=1并接受其隔离性) - 不要在 CLI 中写入关键配置缓存,否则 Web 端读不到;反之亦然
- 调试时用
apcu_cache_info()查看当前缓存项,确认是否命中
真正容易被忽略的是缓存键的设计和失效策略——很多人用时间戳或随机数当键,导致永远不命中;或者设了永不过期,改完配置却要等所有 worker 重启才生效。缓存不是加了就完事,它必须和你的部署流程对齐。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











