2016-11-22 69 views
4

我想在PHP中编写一个脚本来下载一个大的zip文件(2,663,439,370字节),然后我遇到了一个有趣但令人沮丧的问题:脚本首先下载了2.147.483.647字节,然后继续下载文件,而不是附加到字节数2.147.483.648,2.1447.483.649等等,它继续追加字节到从字节号1开始的文件。如何在PHP中下载大于2Gb的文件?

因此,下载的文件是由:字节1,字节2, ...字节2.147.483.647,字节1,字节2 ...等等。

我注意到2.147.483.647是32字节系统可以存储的最大整数值。但是,我的服务器是一个64字节的系统,可以存储大于此值的值。为了证明它,var_dump((int)2147483648)返回正确的整数。尽可能(从php.net通过复制粘贴拍摄)

header('Content-Description: File Transfer'); 
header('Content-Type: application/octet-stream'); 
header('Content-Disposition: attachment; filename="Certificat.zip"'); 
header('Expires: 0'); 
header('Cache-Control: must-revalidate'); 
header('Pragma: public'); 
header('Content-Length: ' . filesize($zipname));  

readfile($zipname); 

有没有人遇到了这个问题

我的下载脚本是正确的?

+0

看起来像PHP有一些软限制设置? –

+1

你的系统可能是64位的,但它听起来像你的PHP当然不是。一个64位int在['9223372036854775807''](https://en.wikipedia.org/wiki/9223372036854775807) – MonkeyZeus

+1

不管怎样,如果你有完整的服务器访问权限,并且它是Apache,那么请查看[mod_xsendfile]( http://www.apachelounge.com/download/) – MonkeyZeus

回答

0

我最终解决了这个问题,通过删除readfile()函数并使用fopen()fread()自己输出文件的内容。

但是,处理这样的大文件时,readfile()'失败的原因仍然是一个开放的主题(我已阅读php.net上的文档,我找不到有关此问题的任何注释)。所以我还在等那位经验丰富的程序员给我启迪:)。

0

我不知道这是否会是你的情况有所帮助,但你应该删除 header('Content-Length: ' . filesize($zipname)); 我没有当我是从前进流加载此几次后,浏览器将继续加载,直到脚本停止与content.I响应我不确定它是否适用于这个大文件,它可能是php的限制。

+1

通过这样做,它只能从浏览器隐藏文件大小,并且无法估计下载时间,但结果相同。 –

1

读取5.6源代码,readfile返回​​。 Here's the source reference

挖掘更多一些,它出现与长整型的定义是通常 4个字节,给我们的整数您的功能停止在签署最大值这个宏的交易。我没有深入挖掘这一点,这是我的假设,并且鉴于你所经历的行为,这对我来说已经足够了(但对于那些更迂腐的人来说)。另一方面,我个人从来没有使用过readfile,fopen/fread组合,在性能和内存使用方面总是被证明是更好的。由于您可以读取块,而不是吞噬2GB的庞然大物,所以在服务器资源上更简单。