php怎么实现下载文件
PHP实现文件下载的方法
使用PHP实现文件下载功能可以通过设置HTTP头信息强制浏览器下载文件而不是直接打开。以下是几种常见方法:
使用header()函数实现基本下载
$file_path = '/path/to/your/file.pdf';
$file_name = 'document.pdf';
if(file_exists($file_path)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file_name).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));
flush();
readfile($file_path);
exit;
} else {
die('文件不存在');
}
处理大文件下载
对于大文件,可以分块读取避免内存问题:
$file_path = '/path/to/large_file.zip';
$chunk_size = 1024 * 1024; // 1MB chunks
if(file_exists($file_path)) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file_path).'"');
$file = fopen($file_path, 'rb');
while(!feof($file)) {
print fread($file, $chunk_size);
flush();
}
fclose($file);
} else {
http_response_code(404);
die('文件不存在');
}
安全下载实现
增加安全检查防止目录遍历攻击:
$base_dir = '/secure/downloads/';
$requested_file = $_GET['file'] ?? '';
$file_path = realpath($base_dir . $requested_file);
// 检查文件是否在允许目录内
if($file_path && strpos($file_path, realpath($base_dir)) === 0 && is_file($file_path)) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file_path).'"');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
} else {
http_response_code(403);
die('禁止访问');
}
强制下载特定MIME类型
针对特定文件类型强制下载:

$file_path = '/path/to/image.png';
$mime_types = [
'png' => 'image/png',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'gif' => 'image/gif'
];
$ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
if(isset($mime_types[$ext])) {
header('Content-Type: '.$mime_types[$ext]);
header('Content-Disposition: attachment; filename="'.basename($file_path).'"');
readfile($file_path);
}
注意事项
- 确保脚本有权限读取目标文件
- 对大文件使用分块读取方式
- 验证用户输入防止路径遍历攻击
- 考虑添加下载限速功能防止服务器过载
- 可以记录下载日志用于统计
这些方法可以根据实际需求组合使用,实现安全可靠的文件下载功能。






