使用 PHP headers,ZIP 下载文件的大小比在外部服务器上的实际大小要大

ZIP downloads are bigger in size than they actually are on external server using PHP headers

我们托管了一些大型文件,这些文件在我们的一个网站上标榜为免费下载。这些文件在另一台服务器上,因此为了生成下载,我们执行以下代码:

header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type:application/octet-stream");
header("Content-Transfer-Encoding: binary"); 
header("Content-Disposition:attachment;filename='$fileName'");
readfile("http://mysiste.com/downloads/$fileName");

其中 $fileName 是 zip 文件的名称。示例:myfile.zip 一切正常,除了如果 myfile.zip 在服务器上为 8Mb,它将下载为 16Mb!最疯狂的是文件工作正常,解压缩文件时,里面的所有文件都是完整的,没有损坏。

我想这与 headers 和传输编码有关,好像 zip 文件失去了压缩。

有什么想法吗?

I think you are missing out an important header header("Content-length: $size") here. You can use int filesize (string $filename) to find the file size. Here is the API doc

<?php
$fileName = "downloaded.pdf"
$size = filesize($file);
header('Content-type: application/pdf');
header("Content-length: $size");
header("Content-Disposition: attachment; filename='$fileName'");
readfile($file);
?>

如果文件位于远程服务器上,您可以通过设置 Curl 轻松获取 Content-length 而无需实际下载它。 这些 Whosebug 线程应该可以帮助您:

参考信用:Content-length and other HTTP headers?

这是结合 curl 和 PHP headers:

的代码
$url="http://mysite/downloads/$fileName";
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_HEADER, true); 
curl_setopt($ch, CURLOPT_NOBODY, true); // make it a HEAD request
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
$head = curl_exec($ch);

$mimeType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
$path = parse_url($url, PHP_URL_PATH);
$filename = substr($url, strrpos($path, '/') + 1);

curl_close($ch); 

header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type:$mimeType");
header("Content-Disposition:attachment;filename='$fileName'");
header('Content-Length: '.$size);
readfile($url);

希望对您有所帮助!