压缩目录中的所有文件并强制下载

Abd*_*sit 6 php zip

我在我的网站上运行以下代码.我遇到的唯一问题是它在服务器上创建一个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;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*dom 6

您提到三个要求:

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

在线之间阅读,我怀疑你遇到的问题是你的服务器的硬盘空间正在被你正在创建的所有Zip档案用尽而不是删除.对此的解决方案(虽然仍然允许可恢复的下载)是在服务器上实现某种形式的TTL检查器,并定期删除比例如1天更早的文件.您可以使用cron作业执行此操作,或者在创建新的arhive时运行检查.

目前,您的代码不指定其中的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;

}
Run Code Online (Sandbox Code Playgroud)