音频文件无自动过期机制,需用filemtime()比对当前时间判断是否超24小时,或存元数据/Redis记录上传时间,配合定时清理;session和cookie过期不触发文件删除。

上传后的音频文件本身没有“过期时间”,得自己加逻辑判断
PHP 的 $_FILES 只负责接收临时文件,tmp_name 默认在脚本结束时自动清理,但一旦你用 move_uploaded_file() 保存到正式目录,它就变成普通文件——操作系统不会管它“该不该过期”。所谓“过期”,必须靠你主动检查文件修改时间(filemtime())或创建时间(filectime()),再和当前时间比对。
怎么用 filemtime() 判断音频是否过期
这是最常用、最轻量的方式,适合文件缓存、临时上传暂存等场景:
- 假设你把音频存到
uploads/audio/目录下,文件名带时间戳或 UUID,比如audio_202608171320.mp3 - 过期规则设为“上传后 24 小时失效”,代码逻辑类似:
$filePath = 'uploads/audio/audio_202608171320.mp3';
$expireAfter = 86400; // 24 小时,单位秒
if (file_exists($filePath) && (time() - filemtime($filePath) > $expireAfter)) {
unlink($filePath); // 过期,直接删
echo "音频已过期并清除";
} else {
echo "音频仍在有效期内";
}注意:filemtime() 是最后修改时间,如果你后续会重写该文件(比如转码覆盖),那这个时间会被更新,导致“过期”被重置;若要严格按上传时刻算,建议上传时写入一个独立的元数据文件(如 audio_202608171320.json),里面存 "uploaded_at": 1755437200。
为什么不能只依赖 session 或 cookie 的过期机制
有人想把音频路径塞进 $_SESSION,然后指望 session.gc_maxlifetime 帮你清理对应文件——这行不通:
立即学习“PHP免费学习笔记(深入)”;
-
session.gc_maxlifetime只管 session 数据文件的垃圾回收,不触发任何自定义清理逻辑 - 即使 session 过期销毁了,
uploads/audio/xxx.mp3仍躺在磁盘上,占空间、有安全风险 - 浏览器 cookie 的
expires时间(通过setcookie()设置)和服务器端文件生命周期完全无关
真正要联动清理,得在 session_destroy() 后手动 unlink() 对应音频,或者更稳妥地:上传时记录文件与 session_id 的映射,另起定时任务扫描过期 session 并批量清理关联文件。
大流量场景下别只靠轮询 filemtime()
如果每请求都 file_exists() + filemtime(),I/O 开销会明显上升。这时建议:
- 把过期时间存进数据库或 Redis,用键如
audio:abc123:expires_at,值为时间戳,查起来快且可原子操作 - 上传成功后,用
redis->setex('audio:abc123', 86400, $filePath)直接设置 24 小时 TTL,Redis 到点自动删键(但注意:它不删磁盘文件,你仍需在读取前校验键是否存在,存在才读文件) - 配合 HTTP 缓存头(如
Cache-Control: max-age=3600)减少重复请求,间接降低过期检查频次
真正难的不是“怎么设过期”,而是“谁来保证过期后资源真被清理”——文件系统没自动 GC,得你亲手写逻辑,还得考虑并发、失败回滚、日志追踪这些细节。



















