PHP 文件缓存机制全解析:Stat Cache 与 Realpath Cache 的本质区别
2026-03-02
问:
1)stat cache
缓存 file_exists、filesize、filemtime 等结果
2)realpath cache
缓存路径解析结果(比如 ../a/../b 这种路径转换)
这俩啥区别?
答:
这个问题问得非常到位。
很多人知道有缓存,但不知道这两层缓存“缓存的根本不是同一种东西”。
我给你用工程视角讲清楚。
一、核心区别一句话版
stat cache 缓存的是:
“这个文件现在是什么状态?”
realpath cache 缓存的是:
“这个路径最终指向哪里?”
一个缓存“文件属性”
一个缓存“路径解析结果”
完全不同层级。
二、我们从文件访问的完整流程讲
当你写:
file_exists('../a/../b/test.txt');
PHP 内部其实分两步:
第一步:路径解析
把 ../a/../b/test.txt
转换成真正的绝对路径,比如:
/var/www/project/b/test.txt
这一步用到 realpath cache。
第二步:文件状态查询
去问系统:
这个文件存在吗?
大小多少?
修改时间多少?
这一步用到 stat cache。
所以完整链路是:
你的代码
↓
realpath 解析
↓
stat 查询
↓
操作系统
↓
磁盘
三、realpath cache 具体干什么?
它缓存的是:
路径字符串 → 绝对路径
例如:
"../a/../b/test.txt"
→ "/var/www/project/b/test.txt"
以及符号链接解析结果。
它不关心文件大小
不关心是否存在
不关心修改时间
它只管:
“这条路径最后指向哪里?”
存在于:
realpath_cache_size
realpath_cache_ttl
这是 php.ini 可配置的。
四、stat cache 具体干什么?
它缓存的是:
某个路径的文件元数据
比如:
file_exists
filesize
filemtime
is_dir
is_file
这些函数的结果。
它缓存的是“文件状态结果”。
而且是当前请求生命周期内缓存。
五、举个清晰对比案例
场景一:文件被删除
unlink('a.txt');
如果之前调用过:
file_exists('a.txt');
那么 stat cache 里记着它存在。
你必须:
clearstatcache();
否则 file_exists 可能还返回 true。
这里和 realpath 没关系。
场景二:符号链接被修改
假设:
/data/link → /data/old
你把 link 改成指向:
/data/new
如果 realpath cache 还记着旧指向:
那么路径解析可能还是 old。
这时候你要:
clearstatcache(true);
注意 true
因为要清 realpath cache。
六、再从内存层级看区别
realpath cache
缓存的是“字符串映射关系”
stat cache
缓存的是“文件元数据结构”
一个更像:
路径映射字典
一个更像:
文件属性快照
七、性能层面差异
realpath cache
是为了减少路径解析开销
尤其是大量 include 文件时
stat cache
是为了减少频繁的文件系统调用
两者优化目标不同。
八、什么时候必须清哪个?
普通 rename、copy 后判断
清 stat cache 就够
如果涉及:
符号链接
动态目录挂载
chroot 切换
路径结构变化
才需要清 realpath cache
也就是:
clearstatcache(true);
九、工程级理解总结
realpath cache
解决“我是谁?”
stat cache
解决“我现在什么状态?”
一个是身份解析
一个是状态记忆
十、给你一个终极记忆口诀
路径变了 → 清 realpath
状态变了 → 清 stat
不确定 → true 一起清
如果你愿意,我可以再讲一个更深的:
为什么 realpath cache 是跨函数有效,而 stat cache 只在请求内有效。
发表评论: