php如何实现下载功能
PHP 实现文件下载功能
使用 header() 函数强制下载
通过设置 HTTP 头信息,强制浏览器将文件作为附件下载而非直接打开。
$file = 'path/to/your/file.pdf'; // 文件路径
$filename = 'custom_name.pdf'; // 下载时显示的文件名
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
} else {
echo "文件不存在!";
}
动态生成内容并下载
适用于需要动态生成内容(如 CSV、文本)的场景。
$content = "姓名,年龄,性别\n张三,25,男\n李四,30,女";
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="data.csv"');
echo $content;
exit;
大文件分块下载
处理大文件时避免内存溢出,使用分块读取。
$file = 'large_file.zip';
$chunk_size = 1024 * 1024; // 1MB 分块
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Content-Length: ' . filesize($file));
$handle = fopen($file, 'rb');
while (!feof($handle)) {
echo fread($handle, $chunk_size);
ob_flush();
flush();
}
fclose($handle);
exit;
}
安全注意事项
-
验证文件路径,防止目录遍历攻击:
$base_dir = '/safe/directory/'; $requested_file = $_GET['file']; $real_path = realpath($base_dir . $requested_file); if (strpos($real_path, $base_dir) === 0 && file_exists($real_path)) { // 安全下载逻辑 } -
限制文件类型(如仅允许下载
.pdf或.csv)。
进阶:断点续传
支持 HTTP 范围请求(Range),实现断点续传功能:

$file = 'large_video.mp4';
$size = filesize($file);
$fp = fopen($file, 'rb');
header('Accept-Ranges: bytes');
if (isset($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
list($start, $end) = explode('-', substr($range, 6));
$start = max(0, intval($start));
$end = min($size - 1, $end ? intval($end) : $size - 1);
header('HTTP/1.1 206 Partial Content');
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: " . ($end - $start + 1));
fseek($fp, $start);
echo fread($fp, $end - $start + 1);
} else {
header('Content-Length: ' . $size);
readfile($file);
}
fclose($fp);






