php怎么实现下载文件
使用 header() 函数强制下载
设置合适的 HTTP 头部信息,指定内容类型为下载文件,并设置文件名:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="example.pdf"');
header('Content-Length: ' . filesize('path/to/file.pdf'));
readfile('path/to/file.pdf');
exit;
通过文件流输出
适用于大文件或动态生成的文件内容,分块读取文件减少内存占用:
$file = 'path/to/large_file.zip';
$chunkSize = 1024 * 1024; // 1MB per chunk
if ($handle = fopen($file, 'rb')) {
while (!feof($handle)) {
echo fread($handle, $chunkSize);
ob_flush();
flush();
}
fclose($handle);
}
处理动态生成的文件
例如将数据库内容导出为 CSV 并下载:
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="data.csv"');
$output = fopen('php://output', 'w');
fputcsv($output, ['ID', 'Name', 'Email']); // 写入表头
// 假设从数据库获取数据
foreach ($dataRows as $row) {
fputcsv($output, $row);
}
fclose($output);
安全注意事项
验证文件路径防止目录遍历攻击:
$requestedFile = basename($_GET['file']); // 过滤非法字符
$filePath = '/safe/directory/' . $requestedFile;
if (!file_exists($filePath)) {
die('File not found');
}
断点续传支持
通过 HTTP_RANGE 处理部分下载请求:
if (isset($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
// 解析范围并处理分片输出
// 需设置 HTTP/1.1 206 Partial Content 状态码
}
以上方法覆盖了从简单文件下载到大文件分块处理的常见场景,需根据实际需求选择合适方案。注意始终对用户输入的文件名做安全校验,避免路径穿越漏洞。







