下载文件时总是下载不完整, Content-Length mismatch: Response Header indicated 157,065,016 bytes, but server sent 145,085,896 bytes.
问题
最近在用php做远程文件的下载,但是下载的时候总是出现下载不完整的情况,比如189M的文件,下载的130M的时候就会出现网络失败的情况,最后抓包工具的日志报错: Content-Length mismatch: Response Header indicated 157,065,016 bytes, but server sent 145,085,896 bytes.
下面记录一下错误的排查过程:
解决过程
1.可能是内存不足
开始以为是内存足导致的,后来加大内存
set_time_limit(0);
set_init(‘memory_limit’,4096);
但是发现并没有什么用,问题仍然存在
2.网络连接
查了nigix配置并没有发现什么有问题的部分,也将请求时间设长问题也一直存在
3.排到第一个问题
因为是读取的远程文件,在读取文件的时候用fliesize()来读取文件的大小,后来发现这个函数是无法读取到远程文件的大小的
后改用get_header()方法来获取文件长度:get_header[‘Content-Length’];
但是至此,问题并没有被完全解决
4.以为文件太大,没有办法一次读入内存,就改为了分行读取
但问题也没有得到解决
5.重新写了新的方法,借鉴了更多方法
至此,在测试时问题得到解决
增加缓冲区清空
完整方法为
public function download($url){
$fileSize = get_header($url)['Content-Length'];
header('Content-Description:File Transfer');
header('Content-Type:application/octet-stream');
header('Accept-Ranges:bytes');
header('Expires:0');
header('Cache-Control:must-revalidate,post-check=0,pre-chec=0');
header('Pragma:public');
header('Content-Length:'.$fileSize);
header('Content-Disposition:attachment;file=newFIleName');
ob_clean();
ob_flush();
flush();
#readfile()不占用内存,可以直接读取文件
readfile($file);
exit;
###分片读取输出
$readBuffer = 4096;
$handle = fopen($url,'rb');
$sumBuffer = 0;
while(!feof($hanle) && $sumBuffer < $fileSize){
echo fread($handle,$readBuffer);
$sumBuffer += $readBuffer;
}
flcose($handle);
exit;
}
至此,功能 测试都正常了,就是缓冲区没有清除干净的问题。
本文记录了在使用PHP下载远程文件时遇到的Content-Length不匹配问题,详细描述了从检查内存限制、网络连接、获取文件大小方法到采用缓冲区策略的整个排查和解决过程。
7873

被折叠的 条评论
为什么被折叠?



