问题
I have a .zip file which is generated on the server using php. The file generated is valid and I checked it by downloading it via ftp etc.
I need to create a way for a user to download this file after it is generated and then the file is deleted. Here are the headers that I am sending.
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/zip');
header("Content-Transfer-Encoding: Binary");
header('Content-Disposition: attachment; filename="'.basename($archive_file_name).'"');
header("Content-Length: " . filesize($this->dirPath."/".$archive_file_name) );
ob_clean();
//echo is_file($this->dirPath."/".$archive_file_name);
readfile($this->dirPath."/".$archive_file_name);
unlink($this->dirPath."/".$archive_file_name);
exit;
The code above works when I try to download the first few times but after few turns it starts downloading as .php file instead of .zip
The file download is triggered by going to a specific link which starts the creation of zip file. Once it is done, it sends out the headers to begin the download
回答1:
your code looks proper. However you need to ensure the preceding and succeeding spaces for your code.
while adding headers in your code, the space will disrupt and will not load the zip file.
Check once again and remove the spaces on top and bottom of page.
And a line which says
readfile($this->dirPath."/".$archive_file_name);
can be removed from code
回答2:
try this header available you to download with resume i suggest use database or log file for understand the file downloaded or not because this header available downloader to download part-part
get Request range from downloader you can use fseek to read range of file
$Range=@$_SERVER['HTTP_RANGE'];//Range: bytes=843530240-
$Cach="";
if($Range!=""){
$Range=explode("=",$Range);
$Cach=(int)trim($Range[1]," -");
}
caching controller
function caching_include($file) {
$headers = $_SERVER;
// Get the modification timestamp
if(!(list(,,,,,,,,,$lastModified) = @stat($file))){
echo Error;
exit();
}
// Build our entity tag
$eTag = "ci-".dechex(crc32($file.$lastModified));
if (false and (strpos(@$headers['If-None-Match'], "$eTag")) &&(gmstrftime("%a, %d %b %Y %T %Z", $lastModified) == @$headers['If-Modified-Since'])) {
// They already have an up to date copy so tell them
header('HTTP/1.1 304 Not Modified');
header('Cache-Control: private');
header("Pragma: ");
header('Expires: ');
header('Content-Type: ');
header('ETag: "'.$eTag.'"');
exit;
} else {
// We have to send them the whole page
header('Cache-Control: private');
header('Pragma: ');
header('Expires: ');
header('Last-Modified: '.gmstrftime("%a, %d %b %Y %T %Z",$lastModified));
header('ETag: "'.$eTag.'"');
}
}
header for download
header("Server: SepidarSoft/ir-system");//server name
header("Date: ".date("a,d b Y H:M:S GMT",time()));
header("X-Powered-By: SepidarSoft");
header("Cache-Control: public");
header("Content-disposition:filename=\"".$BaseName."\"");//file name
caching_include($FPatch);//caching controller
header("Accept-Ranges:bytes");
header("Content-Transfer-Encoding: binary\n");
header("Connection: Keep-Alive");
header("Content-Type: $Type");//file type like application/zip
header("Content-Length: ".($FSize-$Cach)); //length of download it is for resume
header("Content-Range: bytes ".$Cach."-".($FSize-1)."/".$FSize); //download range it is for resume
header("HTTP/1.1 206 Partial Content",true);
set_time_limit(0);
if use set_time_limit(0);
in code if user connection become disconnect php continue until finish work for that your file will be remove you download or not after one request you can use connection_status()==0
for check connection like below
$Speed=102400;
fseek($Handle,$From);//if use resume it is useful
while(!@feof($Handle) and (connection_status()==0)){
print(fread($Handle,$Speed));
flush();
ob_flush();
}
if(connection_status()==0){//with this condition you can understand download is down by user
unlink($this->dirPath."/".$archive_file_name);
}
来源:https://stackoverflow.com/questions/15893738/zip-file-downloading-as-php