开发者问题收集

下载 PHP ZipArchive 返回损坏的空白 zip 文件

2022-07-26
1120

我查看了有关 ZipArchive 和如何下载文件的各种帖子。但是,我在这里遇到了一些问题。 我目前有一个类似这样的表单

<form name="download-resources" method="post">
    <input type="hidden" name="download-resources" value="1" />
    <?php foreach($resources as $key => $value) { ?>
        <label for="<?php echo $value->name; ?>"><?php echo $value->name; ?> 
        <input type="checkbox" name="download-items[<?php echo $key; ?>]" download-id="<?php echo $key; ?>" /></label>
    <?php } ?>
    <input type="submit" value="Download"/>
</form>

在该表单中,有一些方面来自脚本的其余部分,这些部分在这里:

<?php

$resources = array();

// Create our items
$i = 1;
while($i <= 3) {
    ${'item-' . $i} = new stdClass();
    ${'item-' . $i}->name = 'item-' . $i;
    ${'item-' . $i}->link = 'link';
    $resources[$i] = ${'item-' . $i};
    $i++;
}

// When we post the form
if(!empty($_POST['download-resources'])) {
    $archive_file_name = 'some resources.zip';
    $zip = new ZipArchive();
    if ($zip->open($archive_file_name, ZipArchive::CREATE) === TRUE) {
        foreach($_POST['download-items'] as $key => $value) {
            $zip->addFile('https://www.w3.org/TR/PNG/iso_8859-1.txt', 'test.txt');
            //$zip->addFile(${'item-' . $key}->link . '.txt');
        }
        $zip->close();
        echo 'ok';
    } else {
        echo 'failed';
    }

    header("Content-type: application/zip"); 
    header("Content-Disposition: attachment; filename=$archive_file_name");
    header("Content-length: " . filesize($archive_file_name));
    readfile("$archive_file_name");
    exit;
}

?>

我已经测试了所有其他部分,例如对象的生成等。但目前我只是对文件无法正确下载感到困惑。每当我点击提交按钮进行下载时,在选择一两个项目后,我都会得到一个具有正确 zip 名称的 zip 文件 - 一切都很好。但是当尝试使用 WinRaR 打开文件时,会出现以下消息:

The archive is either in unknown format or damaged

我尝试使用老办法在记事本中打开 zip 文件,尝试查看是否存在任何错误。但是,返回的结果完全是空白的,这对我来说真的很奇怪。

有人知道我该如何解决这个问题吗?提前谢谢

3个回答

已解决:需要创建一个临时文件夹,并将它们存储在那里。 这是最终的解决方案:

<?php if(!empty($_POST['download-resources'])) {
    $archive_file_name = "something resources.zip";
    $rand = rand(0,999999);
    $tmp_file = 'files/tmp/'.$rand.'.zip';
    $zip = new ZipArchive;
    if ($zip->open($tmp_file, ZipArchive::CREATE) === TRUE) {
        foreach($_POST['download-items'] as $key => $value) {
            
            $zip->addFile($_SERVER['DOCUMENT_ROOT'] . '/technology/tony/files/test1.txt', 'test1.txt');
            //$zip->addFile(${'item-' . $key}->link . '.txt');

        }
        $zip->close();
        header("Content-type: application/zip"); 
        header("Content-Disposition: attachment; filename=" . $archive_file_name . "");
        header("Content-length: ".filesize($archive_file_name));
        readfile($tmp_file);
    } 
    exit; } ?>
Tony Ingall
2022-07-26

此代码对您有用。

// When we post the form
if (!empty($_POST['download-resources'])) {
    $archive_file_name = 'some resources.zip';
    $zip = new ZipArchive();
    if ($zip->open($archive_file_name, ZipArchive::CREATE) === TRUE) {
        foreach($_POST['download-items'] as $key => $value) {
            $file_url = 'https://www.w3.org/TR/PNG/iso_8859-1.txt';
            $download_file = file_get_contents($file_url);
            $zip->addFromString(basename($file_url),$download_file);
            //$zip->addFile(${'item-' . $key}->link . '.txt');
        }
        $zip->close();
        echo 'ok';
    } else {
        echo 'failed';
    }

    header("Content-type: application/zip");
    header("Content-Disposition: attachment; filename=$archive_file_name");
    header("Content-length: " . filesize($archive_file_name));
    readfile("$archive_file_name");
    exit;
}
Mehul Bukeliya
2022-07-26

您需要选择以下方法之一:

  1. 创建临时文件(例如通过 tempnam),将其保存到 ZipArchive,输出给用户并删除文件。
  2. 使用一些具有将存档创建为字符串的方法的库(例如 NeLexa-Zip outputAsString
wapmorgan
2022-08-02