PHP不直接处理视频播放卡顿,关键在于绕过其短板:分块读取+Range支持+Nginx/Apache静态服务+前端分片上传。

PHP本身不播放视频,也不决定卡不卡——卡顿来自传输中断、缓冲失败或服务器扛不住请求。处理大视频文件不超时、不卡死,关键不是“让PHP更快”,而是绕过它的短板,用对机制。
别让PHP读完整个视频文件
用 readfile() 或 file_get_contents() 加载几GB视频,内存瞬间爆掉,脚本超时是必然的。PHP进程会卡死、崩溃,浏览器收不到响应。
- 改用 fopen() + fread() 分块读取,每次只读 8KB–64KB,边读边输出
- 配合 flush() 和 ob_flush(),确保数据实时发到浏览器
- 开头加 set_time_limit(0),禁用脚本执行时间限制
必须支持 HTTP Range 请求
浏览器拖动进度条、快进、暂停续播,全靠 Range 头(如 bytes=1024-5120)。不支持,就只能从头加载,一卡到底。
- 检查
$_SERVER['HTTP_RANGE']是否存在 - 手动解析起始/结束字节,用 fseek() 定位文件指针
- 返回状态码 206 Partial Content,并带上
Content-Range和Accept-Ranges: bytes - 不要用 readfile() 响应 Range 请求——它无法控制读取范围
让 Nginx 或 Apache 直接服务视频文件
这是最有效、最省资源的做法。PHP 只管权限校验,真正的文件传输交给 Web 服务器。
立即学习“PHP免费学习笔记(深入)”;
- 把视频放在 Web 根目录外(如
/data/videos/xxx.mp4) - PHP 鉴权通过后,用 X-Accel-Redirect(Nginx)或 X-Sendfile(Apache)触发静态文件下发
- 这样既保留业务逻辑控制,又享受 Web 服务器的缓存、Range 支持、连接复用等优化
上传阶段也要分片,别指望一次传完
用户上传大视频时,同样会因超时、断网失败。整传失败就得重来,体验极差。
- 前端用 JavaScript 的
File.slice()按 2–10MB 切片 - 每块带唯一标识(如文件 hash + chunk index),支持断点续传
- PHP 后端只接收单块、存临时文件,最后合并;不加载整块进内存
- 合并时用 fopen('wb') + fwrite() 流式写入,避免 file_get_contents 内存溢出



















