php 头以循环下载多个文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4993468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 16:29:23  来源:igfitidea点击:

php header to download multiple files in loop

php

提问by Novice

I am creating pdf files on the fly and I want to download multiple files using php. Can I write header like this

我正在即时创建 pdf 文件,我想使用 php 下载多个文件。我可以这样写标题吗

<?php
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="downloaded.pdf"');
readfile('original.pdf');
?>

in while loop?

在while循环中?

回答by Brad Christie

Short answer is no, you need something to tell the client where the content ends and a new header begins. You caneither use the zip utility and package them up for download, or you could look in to maybe a mime email format (which uses dividers throughout the document) but I'm not sure that would work over the HTTP protocol without explicitly calling it an "email" package.

简短的回答是否定的,您需要告诉客户端内容在哪里结束和新标题开始的地方。您可以使用 zip 实用程序并将它们打包以供下载,或者您可以查看 mime 电子邮件格式(在整个文档中使用分隔符),但我不确定它是否可以在没有明确调用的情况下通过 HTTP 协议工作一个“电子邮件”包。

I would just recommend using the zip utility. Generate the PDFs you need to, then package them up and send them off.

我只建议使用 zip 实用程序。生成您需要的 PDF,然后将它们打包并发送出去。

回答by Marc B

No. HTTP doesn't support multiple files in a single download. There was some talk about adding MIME-style semantics to HTTP messages way back when, so you could embed multiple responses in a single transfer, but that didn't go anywhere.

不可以。HTTP 不支持一次下载中的多个文件。很久以前就有人讨论过将 MIME 样式的语义添加到 HTTP 消息中,因此您可以在一次传输中嵌入多个响应,但这并没有发生。

Unless you do something like zipping the multiple files on the server and transfer that zip, there's no way to download more than one file per request.

除非您执行诸如压缩服务器上的多个文件并传输该 zip 之类的操作,否则无法为每个请求下载多个文件。

回答by Hardik

Step1: Create one index.php file and add following code.

Step1:创建一个index.php文件并添加如下代码。

<?php
$path = $_SERVER['DOCUMENT_ROOT']."/your_folder/"; 

$files = scandir($path);
$count=1;
foreach ($files as $filename)
{
    if($filename=="." || $filename==".." || $filename=="download.php" || $filename=="index.php")
    {
        //this will not display specified files
    }
    else
    {
        echo "<label >".$count.".&nbsp;</label>";
        echo "<a href="download.php/?filename=".$filename."">".$filename."</a>
";
        $count++;
    }
}
?>

Step2: Create one download.php file and add following code.

Step2:创建一个download.php文件并添加如下代码。

<?php
function output_file($file, $name, $mime_type='')
{
 /*
 This function takes a path to a file to output ($file),  the filename that the browser will see ($name) and  the MIME type of the file ($mime_type, optional).
 */

 //Check the file premission
 if(!is_readable($file)) die('File not found or inaccessible!');

 $size = filesize($file);
 $name = rawurldecode($name);

 /* Figure out the MIME type | Check in array */
 $known_mime_types=array(
  "pdf" => "application/pdf",
  "txt" => "text/plain",
  "html" => "text/html",
  "htm" => "text/html",
 "exe" => "application/octet-stream",
 "zip" => "application/zip",
 "doc" => "application/msword",
 "xls" => "application/vnd.ms-excel",
 "ppt" => "application/vnd.ms-powerpoint",
 "gif" => "image/gif",
 "png" => "image/png",
 "jpeg"=> "image/jpg",
 "jpg" =>  "image/jpg",
 "php" => "text/plain"
 );

 if($mime_type==''){
  $file_extension = strtolower(substr(strrchr($file,"."),1));
  if(array_key_exists($file_extension, $known_mime_types)){
  $mime_type=$known_mime_types[$file_extension];
  } else {
  $mime_type="application/force-download";
  };
 };

 //turn off output buffering to decrease cpu usage
 @ob_end_clean(); 

 // required for IE, otherwise Content-Disposition may be ignored
 if(ini_get('zlib.output_compression'))
  ini_set('zlib.output_compression', 'Off');

 header('Content-Type: ' . $mime_type);
 header('Content-Disposition: attachment; filename="'.$name.'"');
 header("Content-Transfer-Encoding: binary");
 header('Accept-Ranges: bytes');

 /* The three lines below basically make the 
    download non-cacheable */
 header("Cache-control: private");
 header('Pragma: private');
 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

 // multipart-download and download resuming support
 if(isset($_SERVER['HTTP_RANGE']))
 {
 list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
 list($range) = explode(",",$range,2);
 list($range, $range_end) = explode("-", $range);
 $range=intval($range);
 if(!$range_end) {
  $range_end=$size-1;
 } else {
  $range_end=intval($range_end);
 }

 $new_length = $range_end-$range+1;
 header("HTTP/1.1 206 Partial Content");
 header("Content-Length: $new_length");
 header("Content-Range: bytes $range-$range_end/$size");
 } else {
 $new_length=$size;
 header("Content-Length: ".$size);
 }

 /* Will output the file itself */
 $chunksize = 1*(1024*1024); //you may want to change this
 $bytes_send = 0;
 if ($file = fopen($file, 'r'))
 {
 if(isset($_SERVER['HTTP_RANGE']))
 fseek($file, $range);

 while(!feof($file) && 
  (!connection_aborted()) && 
  ($bytes_send<$new_length)
       )
 {
  $buffer = fread($file, $chunksize);
  print($buffer); //echo($buffer); // can also possible
  flush();
  $bytes_send += strlen($buffer);
 }
 fclose($file);
 } else
 //If no permissiion
 die('Error - can not open file.');
 //die
die();
}
//Set the time out
set_time_limit(0);

//path to the file
$file_path=$_SERVER['DOCUMENT_ROOT'].'/your_folder/'.$_REQUEST['filename'];


//Call the download function with file path,file name and file type
output_file($file_path, ''.$_REQUEST['filename'].'', 'text/plain');

?>

Change 'your_folder' with you folder name in both files.

在两个文件中使用您的文件夹名称更改“your_folder”。

回答by Nitro Chummy

Not with PHP alone. But you should be able to achieve this with some Javascript.

不能单独使用 PHP。但是您应该能够使用一些 Javascript 来实现这一点。

Make the loop from Javascript, creating new frames with the PHP pages as source.

从 Javascript 开始循环,使用 PHP 页面作为源创建新框架。

Some browsers would warn their users of multiple file downloads though, but it should work once they accept.

一些浏览器会警告用户下载多个文件,但一旦他们接受,它应该可以工作。

Hope this helps someone searching for an answer.

希望这可以帮助寻找答案的人。

回答by Chris Baker

No. The standard only allows for a single file to be downloaded per request. You could, if the ZIP method suggested above is not possible, have a base page with a javascript timeout that redirects the user to each of the files, one at a time. For instance:

不可以。标准只允许每个请求下载一个文件。如果上面建议的 ZIP 方法不可行,您可以使用带有 javascript 超时的基页,将用户重定向到每个文件,一次一个。例如:

<script type="text/javascript">
var file_list = new Array(
  'http://www.mydomain.com/filename1.file',
  'http://www.mydomain.com/filename2.file',
  'http://www.mydomain.com/filename3.file'
);
for (var i=0; i < file_list.length - 1; i++) {
  setTimeout(function () {
     document.location = file_list[i];
  }, i * 1000);
}
</script>

<h1>Please wait</h1>
<p>Your download will start in a moment.</p>