PHP 即时创建和下载 ZIP

Posted

技术标签:

【中文标题】PHP 即时创建和下载 ZIP【英文标题】:PHP create and download ZIP on the fly 【发布时间】:2014-10-28 02:31:26 【问题描述】:

我正在创建一个包含多个脚本的 ZIP 文件(例如:test.phpfunctions.jsstyle.css)。

脚本运行良好,唯一的问题是 ZIP 文件被放置在我的网络服务器上。有没有办法防止这种情况?我已经阅读了多个类似的问题:this one 似乎有效,但我不知道如何使用它。

所以,我不想在放置文件后删除它(即使用户中止它)或者(甚至更好)我的脚本永远不会将文件放在网络服务器上。

download.php

$scriptId = checkNumeric($_GET['sid']);

//Check if user has access to the script
if(isLoggedIn() && hasScriptAccess($scriptId))  

    //Create ZIP
    $zip = new ZipArchive();
    $zipName = "script.zip";

    if ($zip->open($zipName, ZIPARCHIVE::CREATE)!== TRUE) 
        exit(); //Something went wrong while creating the ZIP
    

    //Get associated codes
    $query = $mysqli->query("SELECT * FROM code WHERE script_id = '$scriptId'");
    while($code = $query->fetch_assoc()) 
        $filename = $code['title'];
        $content = $code['code'];

        //Add file to ZIP
        $zip->addFromString($filename, $content);
    

    $zip->close();

    //Set headers
    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='" . $zipName . "'");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: " . filesize($zipName));

    clearstatcache(); //Make sure the file size isn't cached
    readfile($zipName); //Output the file
    $zip->deleteName($zipName);

【问题讨论】:

您是否可以在您的服务器上安排一个 cron 作业,按设定的时间间隔清除您存储文件的目录? 您的意思是 cron 作业会在一定时间后删除存储的文件吗?我认为这是可能的,但这不是最好的解决方案,对吧? 是的,这就是我的意思。 cron 可以运行脚本以按照您指定的任何时间间隔清除该目录。我了解您不想将文件保留在服务器上,但如果您提供下载,它们必须存在很短的时间。过去我遇到过类似的情况,我需要在一段时间后删除 zip 文件,但无法设置 cron 作业。我最终不得不对功能进行编程,使其偶尔作为正常网站流量的一部分运行。 【参考方案1】:

据我了解,zip 文件必须保存,不能存储在内存中。 $zip->close();是实际触发文件创建的原因。我相信比我更聪明的人会弄清楚如何将它写入内存,但现在有一个简单的解决方法。

我刚刚做了类似的事情。诀窍是使用:

// Keep script running even if user aborts
ignore_user_abort(true);

将此添加为脚本的第一行。这样做的目的是让您的下载脚本运行,即使用户中止下载。这将确保您的删除命令被调用。

我不确定您是否在说文件是否正确删除,即使用户没有中止也是如此。但是,如果您当前的删除命令没有按预期工作,您可以使用一个简单的:

unlink( $zipName);

希望这会有所帮助。

【讨论】:

以上是关于PHP 即时创建和下载 ZIP的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 中从 AWS S3 中的文件创建 zip 的最佳方法? [关闭]

ZipStream 在 PHP 中动态创建的 zip 文件不会在 OSX 中打开

无法即时生成 ZIP 文件并将其发送到用户的浏览器以供下载

在 php 中创建 zip 和下载在 Mozilla 浏览器中不起作用

PHP中的压缩流

PHP中的压缩流