php无内置文件访问次数统计,需自行实现外部计数机制:可用加锁的计数文件(flock+file_get_contents/file_put_contents)、数据库(INSERT…ON DUPLICATE KEY UPDATE)或redis(INCR),禁用atime替代计数。

PHP里没有内置的“文件访问次数”属性
操作系统本身不记录单个文件被 fopen() 或 file_get_contents() 了多少次,PHP 更不会自动维护这个计数。所谓“修改文件访问次数”,实际是**你自己设计一个外部计数机制**,比如用单独的计数文件、数据库或 redis 存储并更新数值。
用独立计数文件最简单(但要注意并发)
典型做法:为每个目标文件 /path/to/data.txt 配一个 /path/to/data.txt.hits,每次访问前读取、+1、再写回。
- 必须用
flock()加锁,否则多请求同时写会导致计数丢失 - 推荐用
file_get_contents()+file_put_contents()配合LOCK_EX - 不要用
file_put_contents($f, $n)直接覆盖,要先读再加再写
$hitfile = '/path/to/data.txt.hits'; $hits = (int)@file_get_contents($hitfile); file_put_contents($hitfile, (string)($hits + 1), LOCK_EX);
用数据库或 Redis 更可靠(适合高并发)
当站点有较多并发访问时,文件锁可能成为瓶颈,此时应把计数移到外部服务:
- mysql:建一张
file_hits表,filename(唯一索引)+hits,用INSERT ... ON DUPLICATE KEY UPDATE原子更新 - Redis:用
INCR指令,天然原子,key 可设为file:hits:/path/to/data.txt - 注意:Redis 的 key 要做路径标准化(如把
../清除),避免被恶意构造绕过
别混淆“访问次数”和“atime”时间戳
linux 的 stat() 返回的 atime 是“最后访问时间”,不是次数,且默认可能被挂载选项(如 noatime)禁用,不能依赖它做计数。
立即学习“PHP免费学习笔记(深入)”;
-
touch()或file_get_contents()不一定触发atime更新 -
stat($f)['atime']返回的是 unix 时间戳,不是整数计数 - 想查系统级访问痕迹?得用 auditd 或 inotifywait,不属于 PHP 应用层控制范畴
实际落地时,最容易被忽略的是并发安全——哪怕只是小流量站点,两个 ajax 请求几乎同时到达,没加锁的文件计数就大概率少算一次。