安全删过期缓存文件应先用scandir()或glob()遍历目录,跳过.和..,再对每个文件用filemtime()比对time()与过期秒数,删除前用is_file()和is_writable()双重校验,禁用exec('find')。

PHP 脚本里怎么安全删过期缓存文件
直接用 filemtime() 判断文件修改时间是否超期,比读取内容或依赖外部元数据更轻量、更可靠。注意:不能只看文件名带不带时间戳,很多缓存文件名是哈希值,没时间信息。
- 先用
scandir()或glob()扫目录,避开.和..,别误删父级目录 - 对每个
$file调用filemtime($file),和当前时间比(time() - $expire_seconds) - 用
unlink()前加is_file($file) && is_writable($file)双重检查,避免警告或静默失败 - 别用
exec('find ... -delete')—— 权限、路径空格、符号链接都可能出问题,纯 PHP 更可控
Redis 缓存过期后还占内存?PHP 里得主动清理吗
不用。Redis 本身有惰性删除 + 定期抽样删除机制,EXPIRE 或 SETEX 设的过期时间到了,它自己会处理。PHP 脚本里再扫一遍 keys 删除,纯属多此一举,还可能触发慢日志(KEYS * 是阻塞操作)。
- 确认你用的是
setex()、set($key, $val, ['ex' => 3600])这类带原生过期参数的方法,不是手动存时间戳+每次读前判断 - 如果发现内存不降,大概率是 key 没设过期时间,或用了
hSet()等无过期能力的命令 - 真要排查,用
redis-cli --scan --pattern "cache:*" | xargs -L 1 redis-cli ttl看实际剩余 TTL,别靠 PHP 猜
opcache 清理为什么不能用 unlink 或 touch
opcache_reset() 是唯一安全方式。删 .php 文件或 touch 它,只影响文件修改时间,但 opcache 不一定立即重载 —— 它受 opcache.revalidate_freq 控制,默认 2 秒检查一次,期间仍用旧字节码。
- 开发环境可设
opcache.revalidate_freq=0,但生产环境禁用,否则性能暴跌 -
opcache_invalidate($script, true)只清单个文件,且要求$script是绝对路径,相对路径无效 - 调用
opcache_reset()后所有脚本重编译,有短暂性能抖动,别在流量高峰跑
写定时清理脚本时最容易漏掉的三件事
权限、路径、并发 —— 这三个点一错,脚本就变成“看起来在跑,其实啥也没干”。
立即学习“PHP免费学习笔记(深入)”;
- Web 用户(如 www-data)和 CLI 用户(如 root)的
getcwd()可能不同,所有路径用__DIR__或dirname(__FILE__)开头,别用相对路径 - 脚本被 cron 多次触发(比如上一次还没跑完,下一次又来了),加个简单的
flock()锁:$fp = fopen('/tmp/clear_cache.lock', 'c');+flock($fp, LOCK_EX | LOCK_NB) - 清理前没记录日志,出问题只能瞎猜。至少加一行:
file_put_contents('/var/log/cache_clear.log', date('Y-m-d H:i:s') . " deleted {$count} files\n", FILE_APPEND);
缓存路径权限不对、锁文件被删、日志目录不存在——这些事不会报错,只会让脚本沉默失效。上线前手动跑一遍,盯着日志和磁盘空间变没变。











