应禁用视频相关路由的请求缓存并关闭模板缓存,优先改用静态路径直连视频文件;若必须php代理,需确保正确处理range请求、关闭输出缓冲并校验响应头。

ThinkPHP 5.1 开启静态缓存(如请求缓存或模板缓存)后视频无法播放,问题通常不在于视频本身,而在于缓存机制干扰了视频资源的动态响应逻辑——尤其是当视频路径由 PHP 动态生成、代理输出,或依赖实时头信息(如 Accept-Ranges、Content-Range)时,缓存会固化错误响应或截断流式传输。
检查是否误缓存了视频代理脚本
如果你用 /video.php?id=123 这类 PHP 脚本中转视频,TP5.1 的请求缓存(runtime/request_cache/)可能把整个 PHP 响应(含二进制内容和错误头)当成 HTML 页面缓存下来。后续请求直接返回旧缓存,导致:
- 状态码固定为 200,但实际是空内容或乱码;
- 缺失
Accept-Ranges: bytes,浏览器无法拖动; - 未处理
HTTP_RANGE头,快进失败、黑屏或加载卡死。
✅ 解决方法:在路由或控制器中显式排除视频相关 URL 不走请求缓存:
- 在
route/route.php中,对视频路由禁用缓存:Route::get('video/:id', 'index/Video/play')->cache(false); - 或在控制器方法顶部加注释:
/** @cache off */
确认静态资源路径未被模板缓存污染
若视频是通过模板变量(如 {:video_url()} 或 {__VIDEO__}/demo.mp4)插入的,而你又开启了模板缓存('tpl_cache' => true),那么一旦 video_url() 返回值变化或替换字符串配置更新,旧缓存文件不会自动重建,导致链接指向 404 或过期地址。
✅ 解决方法:
- 临时关闭模板缓存:
在config/app.php中设'tpl_cache' => false; - 手动清空模板编译缓存:
php think clear:template或删掉runtime/template/全部文件; - 确保
view_replace_str(新版为tpl_replace_str)配置写在config/template.php,且路径真实可访问。
避免缓存干扰 Range 请求处理逻辑
PHP 视频代理脚本必须原生支持 HTTP 分段请求。一旦被 TP 缓存或 PHP 输出缓冲干扰,就无法动态响应 Range。常见陷阱包括:
- 开启
opcache后未设opcache.enable_cli=0,导致命令行清理缓存失败; - PHP 输出缓冲未关闭(
ob_end_clean()缺失),头部被截断; - 缓存中间件(如 Nginx 的
proxy_cache)也命中了视频 PHP 路由。
✅ 必做检查项:
- 在
video.php开头强制关缓冲:if (ob_get_level()) ob_end_clean(); - 用
curl -I -H "Range: bytes=0-999" https://yoursite.com/video.php?id=123验证是否返回206 Partial Content和Content-Range; - 检查 Nginx 配置,确保视频 PHP 路由不被
location ~ \.php$的通用缓存规则覆盖。
更推荐:绕过 PHP,直连静态视频文件
绝大多数情况下,视频不该经 PHP 中转。TP5.1 的缓存问题本质是“不该缓存的被缓存了”。最彻底的解法是剥离 PHP 层:
- 把视频文件放到 Web 服务器可直访目录(如
/public/videos/); - HTML 中用绝对静态路径:
<source src="/videos/demo.mp4" type="video/mp4"></source>; - 确认 Nginx/Apache 已启用
Accept-Ranges(Nginx 默认开启;Apache 需加载mod_headers并配置Header set Accept-Ranges "bytes")。
这样既规避所有框架级缓存干扰,又释放 PHP 进程,提升并发能力与播放稳定性。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











