如何在PHP中下载大于2Gb的文件?

时间:2016-11-22 14:36:17

标签: php

我正在尝试用PHP编写一个下载大型zip文件(2,663,439,370字节)的脚本,我遇到了一个有趣但令人沮丧的问题:脚本下载了第一个2.147.483.647字节,然后继续下载文件,而是附加字节编号为2.147.483.648,2.147.483.649等等,它继续从字节编号1开始向文件追加字节。

因此,下载的文件来自:字节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);

有没有人遇到过这个问题?

3 个答案:

答案 0 :(得分:1)

阅读5.6源代码,<my-item *ngFor="let item of items" [item]="item"></my-item> 返回readfileHere's the source reference

再挖掘一下,出现这个宏处理long int定义,通常是 4个字节,给我们带符号的最大值整数,你的函数停在。我没有深入挖掘这个,这是我的假设,考虑到你所经历的行为,这对我来说已经足够了(但不适合那些更迂腐的人)。

另一方面,我个人从未使用RETURN_LONG(size)readfile / fopen组合在性能和使用的内存方面总是被证明更好。既然你可以阅读块,而不是吞噬2GB的猛犸象,那么它在服务器资源上就更容易了。

答案 1 :(得分:0)

我不确定它对你的情况是否有帮助,但你应该删除 header('Content-Length: ' . filesize($zipname)); 当我从正在进行的流加载时,我做了几次,浏览器继续加载,直到脚本停止响应内容。我不确定它是否适用于这个大文件,它可能是php限制。

答案 2 :(得分:0)

我最后通过删除readfile()函数并使用fopen()fread()自行输出文件内容来解决问题。

然而readfile()&#39;处理这些大文件时失败仍然是一个开放的主题(我已经阅读了php.net上的文档,我无法找到关于此类问题的任何注释)。所以我还在等那位经验丰富的程序员开导我:)。