40

我正在尝试通过在本地服务器上创建 zip 文件来下载 2 个文件。文件以 zip 格式下载,但是当我尝试提取它时。它给出错误: 找不到中央目录结尾签名。此文件不是 zip 文件,或者它构成多部分存档的一个磁盘。在后一种情况下,中央目录和 zip 文件注释将在此存档的最后一个磁盘上找到。

我为此使用的以下代码:

 <?php
$file_names = array('iMUST Operating Manual V1.3a.pdf','iMUST Product Information Sheet.pdf');

//Archive name
$archive_file_name=$name.'iMUST_Products.zip';

//Download Files path
$file_path=$_SERVER['DOCUMENT_ROOT'].'/Harshal/files/';


zipFilesAndDownload($file_names,$archive_file_name,$file_path);

function zipFilesAndDownload($file_names,$archive_file_name,$file_path)
{
        //echo $file_path;die;
    $zip = new ZipArchive();
    //create the file and throw the error if unsuccessful
    if ($zip->open($archive_file_name, ZIPARCHIVE::CREATE )!==TRUE) {
        exit("cannot open <$archive_file_name>\n");
    }
    //add each files of $file_name array to archive
    foreach($file_names as $files)
    {
        $zip->addFile($file_path.$files,$files);
        //echo $file_path.$files,$files."

    }
    $zip->close();
    //then send the headers to force download the zip file
    header("Content-type: application/zip"); 
    header("Content-Disposition: attachment; filename=$archive_file_name"); 
    header("Pragma: no-cache"); 
    header("Expires: 0"); 
    readfile("$archive_file_name");
    exit;
}




?>

我检查了传递给函数的所有变量的值,一切都很好。所以请看一下。提前致谢。

4

7 回答 7

54

添加Content-length描述 zip 文件大小的标题(以字节为单位)。

header("Content-type: application/zip"); 
header("Content-Disposition: attachment; filename=$archive_file_name");
header("Content-length: " . filesize($archive_file_name));
header("Pragma: no-cache"); 
header("Expires: 0"); 
readfile("$archive_file_name");

还要确保之前<?和之后绝对没有空格?>。我在这里看到一个空格:

↓</p>

 <?php
$file_names = array('iMUST Operating Manual V1.3a.pdf','iMUST Product Information Sheet.pdf');
于 2012-09-01T08:06:44.503 回答
10
$zip = new ZipArchive;
$tmp_file = 'assets/myzip.zip';
    if ($zip->open($tmp_file,  ZipArchive::CREATE)) {
        $zip->addFile('folder/bootstrap.js', 'bootstrap.js');
        $zip->addFile('folder/bootstrap.min.js', 'bootstrap.min.js');
        $zip->close();
        echo 'Archive created!';
        header('Content-disposition: attachment; filename=files.zip');
        header('Content-type: application/zip');
        readfile($tmp_file);
   } else {
       echo 'Failed!';
   }
于 2016-01-12T06:47:10.773 回答
6
// http headers for zip downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filepath.$filename));
ob_end_flush();
@readfile($filepath.$filename);

我在这里找到了这个解决方案,它对我有用

于 2015-06-13T22:40:24.973 回答
5

错误之一可能是文件未读取为“存档”格式。查看ZipArchive 未打开文件 - 错误代码:19。在文本编辑器中打开下载的文件,如果您在开始时有任何html标签或调试语句,请在读取文件之前清除缓冲区。

ob_clean();
flush();
readfile("$archive_file_name");
于 2015-06-24T01:06:22.670 回答
3

我刚刚遇到了这个问题。对我来说,问题在于:

readfile("$archive_file_name");

这导致内存不足错误。

Allowed memory size of 134217728 bytes exhausted (tried to allocate 292982784 bytes)

我能够通过将 readfile() 替换为以下内容来解决问题:

    $handle = fopen($zipPath, "rb");
    while (!feof($handle)){
        echo fread($handle, 8192);
    }
    fclose($handle);

不确定这是否是您的相同问题或没有看到您的文件只有 1.2 MB。也许这会帮助其他有类似问题的人。

于 2014-10-09T02:02:19.670 回答
1

我遇到了完全相同的问题。就我而言,它的来源是我想在其中创建所有设置为只读的 zip 文件的文件夹的权限。我将其更改为读写,并且有效。

如果您在运行脚本时未在本地服务器上创建文件,那么您很可能遇到与我相同的问题。

于 2013-09-16T03:04:41.183 回答
0

但是我下载后从服务器获取的文件大小为 226 字节

这是 ZIP 标头的大小。显然,下载的 ZIP 文件中没有数据。那么,您能否验证要添加到 ZIP 文件中的文件确实存在(相对于下载 PHP 脚本的路径)?

考虑添加一个检查addFile

foreach($file_names as $file)
{
    $inputFile = $file_path . $file;
    if (!file_exists($inputFile))
        trigger_error("The input file $inputFile does not exist", E_USER_ERROR);
    if (!is_readable($inputFile))
        trigger_error("The input file $inputFile exists, but has wrong permissions or ownership", E_USER_ERROR);
    if (!$zip->addFile($inputFile, $file))
        trigger_error("Could not add $inputFile to ZIP file", E_USER_ERROR);
}

观察到的行为与阻止将文件添加到 ZIP 文件的某些问题(路径错误、权限问题等)一致。在接收到“空”ZIP 文件时,客户端会发出一个错误,指出 ZIP 中央目录丢失(实际错误是没有目录,也没有文件)。

于 2012-09-01T10:48:03.247 回答