我的下载脚本有一个非常奇怪的问题
它基本上是
1.使用“GET”方法
确定文件ID2.从数据库中确定该文件的名称和位置
3.使用headers和readfile
将其发送到客户端
但奇怪的是,该文件总是以损坏或损坏的形式出现
就像它是zip或rar文件一样 文件大小正确,它打开确定
但是我无法在其中打开压缩文件,那就是我收到文件损坏的错误
这是奇怪的因为如果代码有问题我甚至不能打开zip文件(或者至少我认为我不应该)
另一件事是我在发送标题之前用它的路径打印出文件,以确保一切正常
我已将文件地址放在网址上并下载文件,文件没问题
所以在发送标题之前一切正常
这是我的代码
$file_id = isset($_GET['id']) && (int)$_GET['id'] != 0 ? (int)$_GET['id'] : exit;
//////// finging file info
$file = comon::get_all_by_condition('files' , 'id' , $file_id );
if(!$file) exit;
foreach($file as $file){
$location = $file['location'];
$filename = $file['file_name'];
}
/////////////
$site = comon::get_site_domian();
$ext = trim(end(explode('.' , $filename )));
$abslout_path = 'http://'.$site.'/'.$location.'/'.$filename;
$relative = $location.'/'.$filename;
////////////////// content type
switch($ext) {
case 'txt':
$cType = 'text/plain';
break;
case 'pdf':
$cType = 'application/pdf';
break;
case 'zip':
$cType = 'application/zip';
break;
case 'doc':
$cType = 'application/msword';
break;
case 'xls':
$cType = 'application/vnd.ms-excel';
break;
case 'ppt':
$cType = 'application/vnd.ms-powerpoint';
break;
case 'gif':
$cType = 'image/gif';
break;
case 'png':
$cType = 'image/png';
break;
case 'jpeg':
case 'jpg':
$cType = 'image/jpg';
break;
default:
$cType = 'application/force-download';
break;
}
//////////////// just checking
if(!file_exists($relative)){
echo $relative;
echo '<br />';
exit;
}
if( !is_readable( $relative ) )
exit('its not redable');
if( headers_sent() )
exit('headers ? already sent !! ');
header( 'Pragma: public' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
header( 'Cache-Control: private', false ); // required for certain browsers
header( 'Content-Description:File Transfer' );
header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
header( 'Content-Type:'.$cType);
header( 'Content-Disposition: attachment; filename="'. basename($filename) . '";' );
header( 'Content-Transfer-Encoding: binary' );
header( 'Content-Length: ' . filesize($relative) );
readfile($abslout_path);
exit;
我已经多次检查了标题并且它们很好(我认为),我还添加了人类已知的每个标题以确保!
我开始认为这可能不是脚本 像char编码或文件夹权限!或类似的东西!!
我错过了什么吗?答案 0 :(得分:7)
这似乎是强制下载的很多代码,这是我一直使用的一个很好的功能。它也将处理超过2GB的文件。
<?php
$file_id = (isset($_GET['id']) && (int)$_GET['id'] != 0) ? (int)$_GET['id'] : exit;
/*finding file info*/
$file = comon::get_all_by_condition('files', 'id', $file_id);
$path = $file['location'] . '/' . $file['file_name'];
if (!is_file($path)) {
echo 'File not found.('.$path.')';
} elseif (is_dir($path)) {
echo 'Cannot download folder.';
} else {
send_download($path);
}
return;
//The function with example headers
function send_download($file) {
$basename = basename($file);
$length = sprintf("%u", filesize($file));
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $basename . '"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $length);
set_time_limit(0);
readfile($file);
}
?>
答案 1 :(得分:3)
非常好,也很有帮助......
但您的代码存在问题 -
header('Content-Disposition: attachment;
filename="'.basename($file).'"';
请用以下内容进行更改 -
header('Content-Disposition: attachment;
filename="'.basename($file).'"');
你忘了关闭它。
答案 2 :(得分:3)
if (file_exists($file)) {
set_time_limit(0);
header('Connection: Keep-Alive');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
}
答案 3 :(得分:2)
您的脚本可能包含“通知”或“警告”,请尝试在脚本之上禁用错误报告:
error_reporting(0);
答案 4 :(得分:0)
确保在最后一行readfile(FILE_NAME)
我必须添加die();
或exit();
作为最后一行,因为MVC框架继续在readfile
之后呈现视图