php下载文件实现
PHP 实现文件下载
在 PHP 中实现文件下载功能通常涉及设置正确的 HTTP 头信息并输出文件内容。以下是几种常见的实现方式:
使用 readfile() 函数
$file_path = 'path/to/your/file.pdf';
$file_name = basename($file_path);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$file_name.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
exit;
使用 fread() 逐块读取大文件
对于大文件,可以分块读取以避免内存问题:
$file_path = 'path/to/large/file.zip';
$file_name = basename($file_path);
$chunk_size = 1024 * 1024; // 1MB chunks
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$file_name.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));
$handle = fopen($file_path, 'rb');
while (!feof($handle)) {
echo fread($handle, $chunk_size);
ob_flush();
flush();
}
fclose($handle);
exit;
实现安全下载
为防止目录遍历攻击,应验证文件路径:
$base_dir = '/safe/download/directory/';
$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 {
header('HTTP/1.0 404 Not Found');
echo 'File not found';
}
exit;
强制下载特定 MIME 类型
可以强制浏览器下载而不是显示某些文件类型:
$file_path = 'path/to/file.html';
$file_name = basename($file_path);
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="'.$file_name.'"');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
exit;
注意事项
- 确保脚本在输出文件内容前没有输出任何其他内容(包括空格和换行符)
- 对于大文件下载,考虑增加 PHP 执行时间限制:
set_time_limit(0) - 在生产环境中应添加适当的权限检查和日志记录
- 考虑使用 X-Sendfile(如 Apache 的 mod_xsendfile)来提高大文件下载性能







