php 实现下载
实现文件下载的基本方法
在PHP中实现文件下载通常涉及设置正确的HTTP头信息,以便浏览器将响应视为文件下载而非页面显示。以下是几种常见方法:
直接输出文件内容
$file_path = '/path/to/file.pdf';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file_path).'"');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
exit;
从数据库读取二进制数据
// 假设$file_content包含二进制数据,$file_name是下载文件名
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$file_name.'"');
echo $file_content;
exit;
处理大文件下载
对于大文件下载,可以使用分块读取方式减少内存消耗:
$file = @fopen($file_path, 'rb');
if ($file) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file_path).'"');
while (!feof($file)) {
print fread($file, 1024*8);
ob_flush();
flush();
}
fclose($file);
}
exit;
安全注意事项
验证用户权限和文件路径非常重要,防止目录遍历攻击:
$base_dir = '/secure/download/directory/';
$requested_file = $_GET['file'];
$real_path = realpath($base_dir . $requested_file);
// 检查文件是否在允许的目录中
if (strpos($real_path, $base_dir) === 0 && file_exists($real_path)) {
// 安全下载代码
} else {
die('Invalid file request');
}
常见问题解决
中文文件名乱码问题
$file_name = '中文文件.txt';
header('Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode($file_name));
强制下载而非浏览器打开
即使文件类型可以被浏览器直接显示(如PDF),强制下载:
header('Content-Type: application/force-download');
进度显示实现
通过输出缓冲可以实现简单的下载进度显示:
ob_start();
$file_size = filesize($file_path);
$chunk_size = 1024*1024;
$bytes_sent = 0;
while ($bytes_sent < $file_size) {
echo file_get_contents($file_path, false, null, $bytes_sent, $chunk_size);
$bytes_sent += $chunk_size;
ob_flush();
flush();
}






