【问题标题】:Code to create ZipArchive file on PHP is not working, once downloaded file is damaged一旦下载的文件损坏,在 PHP 上创建 ZipArchive 文件的代码不起作用
【发布时间】:2021-04-06 20:04:57
【问题描述】:

我正在尝试在 Internet 上找到的这段代码,它有助于使用 PHP 上的文件创建 ZipArchive

我正在在我的服务器上尝试这个,这是一个 AWS EC2 with Linux Ubuntu,其中运行 Web 服务器。我运行以下代码:

<?php 

function createZipAndDownload($files, $filesPath, $zipFileName)
{
    // Create instance of ZipArchive. and open the zip folder.
    $zip = new ZipArchive();
    $r = $zip->open($zipFileName, ZipArchive::CREATE);
var_dump($r); echo "<br>";

    // Adding every attachments files into the ZIP.
    foreach ($files as $file) {
        $r = $zip->addFile($filesPath . $file, $file);
var_dump($r); echo "<br>";
    }
    $r = $zip->close();
var_dump($r); echo "<br>";

    // Download the created zip file
    header("Content-type: application/zip");
    header("Content-Disposition: attachment; filename = $zipFileName");
    header("Content-length: " . filesize($zipFileName));
    header("Pragma: no-cache");
    header("Expires: 0");
    readfile("$zipFileName");
    exit;
}

// Files which need to be added into zip
$files = array('twiglet-1120x720.jpg','22vwqq.jpg','fb4eb7f8aa5431b0b4e26365ebd59933-239x300.jpg');
// Directory of files
$filesPath = 'https://peakon.com/wp-content/uploads/2018/08/';
// Name of creating zip file
$zipName = 'document.zip';

echo createZipAndDownload($files, $filesPath, $zipName);

?>

然后,我有这个输出:

bool(true)
bool(false)
bool(false)
bool(false)
bool(true)

我了解 ZipArchive 已创建,但文件未在 ZipArchive 内发送。不过,文件下载完成后,当我想打开它时,写着“文件已损坏”,我无法打开它。

你能帮帮我吗?你知道为什么它不工作吗?我想在里面插入这些图片并下载吗? (图片只是示例)

提前感谢您的帮助。

【问题讨论】:

    标签: php upload ziparchive


    【解决方案1】:

    addFile 采用文件系统路径,而不是 HTTP URL。有几种方法可以修复它,但对于您的情况,使用file_get_contentsaddFromString 可能是最简单的。 file_get_contents 确实接受 URL,这很奇怪。请注意addFromString 的参数顺序与addFile 的顺序不同。

    $r = $zip->addFromString($file, file_get_contents($filesPath . $file));
    

    不过,从长远来看,我建议您下载文件、检查结果并根据需要抛出错误消息,但这至少可以帮助您入门。

    编辑

    参数ZipArchive::CREATE 只会在它不存在的情况下创建一个存档,因此它实际上可能会尝试打开一个现有文件,并且在您之前的尝试中,这可能会导致您打开一个损坏的文件。相反,我建议使用ZipArchive::OVERWRITE 重新开始,或使用ZipArchive::EXCL 来保证不触及现有文件。

    将所有这些放在一起,这段代码在我测试时完全按原样工作:

    function createZipAndDownload($files, $filesPath, $zipFileName)
    {
        // Create instance of ZipArchive. and open the zip folder.
        $zip = new ZipArchive();
        $r = $zip->open($zipFileName, ZipArchive::OVERWRITE);
        var_dump($r);
        echo "<br>";
    
        // Adding every attachments files into the ZIP.
        foreach ($files as $file) {
            $r = $zip->addFromString($file, file_get_contents($filesPath . $file));
            var_dump($r);
            echo "<br>";
        }
        $r = $zip->close();
        var_dump($r);
        echo "<br>";
    
        // Download the created zip file
        header("Content-type: application/zip");
        header("Content-Disposition: attachment; filename = $zipFileName");
        header("Content-length: " . filesize($zipFileName));
        header("Pragma: no-cache");
        header("Expires: 0");
        readfile($zipFileName);
        exit;
    }
    
    // Files which need to be added into zip
    $files = array('twiglet-1120x720.jpg', '22vwqq.jpg', 'fb4eb7f8aa5431b0b4e26365ebd59933-239x300.jpg');
    // Directory of files
    $filesPath = 'https://peakon.com/wp-content/uploads/2018/08/';
    // Name of creating zip file
    $zipName = 'document.zip';
    
    createZipAndDownload($files, $filesPath, $zipName);
    

    【讨论】:

    • 感谢您的回复。正如你所说,我已经尝试通过替换代码。现在的输出是: bool(true) bool(true) bool(true) bool(true) bool(false) 最后一个变成了假。 .zip正在下载,我还是打不开,好像文件损坏了。
    • 非常感谢您的帮助和回答 :) 我正在尝试您编写代码。但它仍然不起作用,文件已损坏。我想知道问题是否可能来自服务器、php 或 ZIP 版本等?我正在使用 18.04.1-Ubuntu、apache2 服务器和 7.2 php 版本在 AWS EC2 上工作。启用 ZIP,zip 版本为 1.15.4,libzip 版本为 1.1.2
    猜你喜欢
    • 2015-07-16
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多