PHP如何用
开启断点续传支持
断点续传不是靠PHP自己“记住进度”,而是靠HTTP协议配合客户端(比如浏览器、wget、curl)重新发起带
头的请求。PHP要做的是正确响应这个头,并返回对应字节段——核心就是设置
和处理
请求头。
常见错误是只加了
但没设
,导致客户端压根不发
请求;或者忽略
校验,让过期缓存继续续传出错数据。
必须在输出文件内容前调用
检查
是否存在,格式是否为
,否则按完整文件响应
用
打开文件后,用
跳转到起始位置,再用
读取指定长度,别用
全载入内存
响应状态码要分情况:
(有Range),
(无Range),不能一律用200
为什么
+
比
更安全
会把整个文件一次性刷进输出缓冲区,对大文件(比如2GB视频)极易触发内存溢出或超时;而
+
可以按块读取、边读边输出,内存占用稳定在几KB。
另外
无法精确控制起始偏移和长度,没法适配
请求;哪怕你手动截断输出,HTTP头里的
也容易算错,导致客户端解析失败。
立即学习
“
PHP免费学习笔记(深入)
”;
用
以二进制模式打开,避免Windows下换行符干扰
计算
时,用
,不是
读取循环中每次
不超过8192字节,防止阻塞太久被Nginx/Apache切断连接
记得
清空已有输出缓冲,否则
会失败
Apache/Nginx下
或
能替代PHP逻辑吗
能,而且更推荐。PHP只负责校验权限、生成重定向头,真实文件传输交给Web服务器,既省PHP资源,又天然支持断点续传、gzip压缩、缓存协商。
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
但要注意:启用后PHP不能再输出任何内容(包括空格、BOM),否则重定向失效;且路径需映射到Web服务器可访问的内部位置,不能暴露真实磁盘路径。
Apache需启用
,并配置
和
Nginx用
时,需在location里配置
,并确保响应头中的路径匹配内部别名
PHP中只需
(Apache)或
(Nginx)
别忘了仍要设置
——Web服务器会自动处理Range,但前提是这个头存在
客户端不发
请求?检查这几个地方
即使PHP代码完全正确,客户端也可能因为缓存策略、HTTP版本或工具限制,始终发完整请求。这不是PHP的问题,但排查时容易误判。
典型表现:用
下载失败,Chrome开发者工具Network面板里看不到
请求头,
返回200而非206。
确认客户端HTTP版本≥1.1(HTTP/1.0不支持Range)
检查响应头是否有
或
——某些旧客户端遇到强禁止缓存时,会放弃续传
用
直连测试,排除CDN或反向代理拦截Range头
部分CDN(如Cloudflare免费版)默认剥离
头,需在页面规则里显式开启“Partial Request”支持
断点续传真正难的不是PHP怎么写,而是理清谁在哪个环节控制哪段字节——客户端决定要哪块,Web服务器决定能不能给,PHP只是中间那个校验权限、拼好头、不搞错偏移量的角色。漏掉
头、用错读取方式、或者被CDN静默过滤Range,都会让整套逻辑失效。
header()RangeAccept-Ranges: bytesRangeContent-RangeAccept-RangesRangeIf-Rangeheader('Accept-Ranges: bytes')$_SERVER['HTTP_RANGE']bytes=N-Mfopen()fseek()fread()file_get_contents()206 Partial Content200 OKfseek()fread()readfile()readfile()fseek()fread()readfile()RangeContent-Lengthfopen($file, 'rb')Content-Length$end - $start + 1$end - $startfread()ob_end_clean()header()mod_xsendfileX-Accel-Redirectmod_xsendfileXSendFile OnXSendFilePath /path/to/filesX-Accel-Redirectinternalheader('X-Sendfile: /real/path/to/file.zip')header('X-Accel-Redirect: /nginx-alias/file.zip')Accept-Ranges: bytesRangewget -cRangecurl -H "Range: bytes=0-1023" -ICache-Control: no-storePragma: no-cachecurl -v -H "Range: bytes=0-1023" http://yoursite/file.zipRangeAccept-Ranges