【问题标题】:Zip all files in directories and force download压缩目录中的所有文件并强制下载
【发布时间】:2011-12-05 09:20:36
【问题描述】:

我的网站上运行了以下代码。我唯一遇到的问题是它在服务器上制作了一个 zip 文件,然后用户下载。

我想知道我应该怎么做才能“即时”生成 zip 文件而不先转储到服务器磁盘上。我还想让用户暂停/恢复下载。

//function for zip
function zipFilesAndDownload($file_names,$archive_file_name,$file_path)
{
  //create the object
  $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.str_replace('./','',$files),translit($files).".mp3");
  }
  $zip->close();

  //then send the headers to foce 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;
}

【问题讨论】:

标签: php zip


【解决方案1】:

你提到的三个要求:

  • zip is available for download on fly - 我认为你的意思是“zip 文件是动态创建的”。这已经在发生。确实,这就是您的脚本所做的,它是存在的理由,如果你愿意的话。
  • zip file should not be created on server - 你必须在服务器上创建一个文件,即使它只是暂时的,因为这就是 Zip 扩展的工作方式。用户下载后即可删除(只需在exit;前一行添加unlink($archive_file_name);即可)。
  • user can also resume it if paused - 此要求(大部分)与 zip file should not be created on server 不兼容。可恢复下载可以在 PHP 中实现的,但是很难做到,并且需要访问请求的 Range: 标头 - 并非每个服务器都允许您拥有。此外,即使是部分请求,您也必须生成 整个 文件,因为您已将其从服务器中删除。 Apache 有一个可恢复下载的实现,但它要求(AFAIK)文件在硬盘驱动器上是静态的,并且直接请求。这意味着在文件下载后(在 PHP 脚本末尾)删除文件会破坏可恢复性。

在字里行间,我怀疑您遇到的问题是您的服务器的硬盘空间正在被您正在创建而不是删除的所有 Zip 存档占用。对此的解决方案(同时仍然允许可恢复下载)是在服务器上实现某种形式的 TTL 检查器,并定期删除早于例如 1 天的文件。您可以通过 cron 作业执行此操作,或者在创建新存档时运行检查。

目前,您的代码没有指定 在哪里 将创建 zip 文件,这是您需要做的事情。这是一个示例,假设您的脚本位于您网站的根目录中,并且在您的网站根目录中有一个名为 zips 的目录。

基本流程是:

  • 遍历 /zips 目录,删除所有超过 1 天的文件。
  • /zips 目录中创建一个新存档
  • 重定向用户到该静态文件的路径。
function zipFilesAndDownload($file_names, $archive_file_name, $file_path) {

  // Archive directory
  $archiveDir = 'zips';
  // Time-to-live
  $archiveTTL = 86400; // 1 day
  // Files to ignore
  $ignoreFiles = array('.', '..');


  // Loop the storage directory and delete old files
  if ($dp = opendir($archiveDir)) {
    while ($file = readdir($dp)) {
      if (!in_array($file, $ignoreFiles) && filectime("$archiveDir/$file") < (time() - $archiveTTL)) {
        unlink("$archiveDir/$file");
      }
    }
  }

  // Re-format the file name
  $archive_file_name = "$archiveDir/".basename($archive_file_name);
  // Create the object
  $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 file of $file_name array to archive
  foreach($file_names as $file) {
    $zip->addFile($file_path.str_replace('./', '', $file), translit($files).".mp3");
  }
  $zip->close();

  // Then send the headers to redirect to the ZIP file
  header("HTTP/1.1 303 See Other"); // 303 is technically correct for this type of redirect
  header("Location: http://{$_SERVER['HTTP_HOST']}/$archive_file_name");
  exit;

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多