PHP无法直接清理浏览器视频缓存,只能通过设置HTTP响应头(如Cache-Control: no-store)强制禁用缓存,并需配合Accept-Ranges支持断点续传,同时须在Nginx/CDN层同步禁用缓存以防穿透。

PHP 本身不直接管理浏览器或播放器的视频缓存,所谓“PHP 清理视频缓存”实际是通过 HTTP 响应头控制客户端(浏览器、H5 video 标签、移动端 WebView)是否缓存视频资源。关键不在 PHP 删除文件,而在告诉客户端“别存这个视频”或“存了也别用”。
如何用 PHP 强制禁用视频资源缓存
对 video 标签加载的 MP4/WebM 等静态资源,PHP 脚本可作为代理输出(如 /video.php?id=123),在输出前设置严格缓存禁止头:
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Expires: Mon, 01 Jan 1990 00:00:00 GMT');
header('Pragma: no-cache');
// 必须设置 Content-Type,否则部分浏览器拒绝播放
header('Content-Type: video/mp4');
// 若从文件读取,记得加 Content-Length 和 Accept-Ranges 支持快进
header('Accept-Ranges: bytes');
readfile('/path/to/video.mp4');注意:no-store 比 no-cache 更彻底,禁止任何磁盘/内存缓存;但会牺牲加载性能,每次播放都重新下载。
为什么 header('Cache-Control: private') 不够用
很多开发者误以为 private 就能防止共享缓存,但它仍允许浏览器本地缓存。视频类资源一旦被缓存,用户拖动进度条、刷新页面、甚至切后台再回来,都可能复用旧缓存——导致修改视频后前端看不到更新。
立即学习“PHP免费学习笔记(深入)”;
-
private:仅禁止 CDN/代理缓存,浏览器仍可存 -
no-cache:允许缓存,但每次用前必须向服务器验证(ETag或Last-Modified) -
no-store:真正禁止一切存储,强制重载原始字节流
PHP 输出视频时如何支持断点续传(避免缓存干扰)
禁用缓存后,若不支持 Range 请求,H5 video 标签将无法拖动进度条,且部分安卓 WebView 会直接报错黑屏。PHP 代理脚本需手动解析 HTTP_RANGE 并返回分段响应:
$file = '/path/to/video.mp4'; $fp = fopen($file, 'rb'); $size = filesize($file); $length = $size; $start = 0; $end = $size - 1;if (isset($_SERVER['HTTP_RANGE'])) { preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches); $start = intval($matches[1]); $end = isset($matches[2]) ? intval($matches[2]) : $size - 1; $length = $end - $start + 1;
header('HTTP/1.1 206 Partial Content'); header("Content-Range: bytes $start-$end/$size");}
header('Content-Type: video/mp4'); header("Accept-Ranges: bytes"); header("Content-Length: $length"); header('Cache-Control: no-store');
fseek($fp, $start); while ($length > 0 && !feof($fp)) { $read = min(8192, $length); echo fread($fp, $read); $length -= $read; } fclose($fp);
漏掉
Accept-Ranges或错误实现206响应,会导致 iOS Safari 拒绝播放、Chrome 控制台报ERR_FAILED。CDN 和 Nginx 层缓存比 PHP 更优先,必须协同处理
即使 PHP 设置了
no-store,如果上层 Nginx 配置了expires 1h,或 CDN(如 Cloudflare)对.mp4后缀默认缓存 4 小时,PHP 的响应头会被覆盖或忽略。
- Nginx 中需显式关闭视频路径缓存:
location ~ \.mp4$ { expires -1; add_header Cache-Control "no-store"; } - Cloudflare 需在缓存规则中匹配
/video.php*或对应路径,设置「Cache Level」为「Bypass」 - 验证是否生效:用
curl -I https://yoursite.com/video.php?id=1查看返回的Cache-Control值
最易忽略的是 CDN 缓存穿透——你以为 PHP 控制了,其实流量根本没到 PHP,全被 CDN 拦截返回了旧缓存。











