php实现文件下载
实现文件下载的基本方法
使用PHP实现文件下载可以通过设置HTTP头信息,强制浏览器下载文件而不是直接打开。
$file_path = 'path/to/your/file.pdf';
$file_name = 'downloaded_file.pdf';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file_name . '"');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
exit;
处理大文件下载
对于大文件下载,可以使用分块读取的方式避免内存问题。

$file_path = 'path/to/large_file.zip';
$file_name = 'large_file.zip';
$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('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/directory/';
$requested_file = $_GET['file'];
$file_path = realpath($base_dir . $requested_file);
if ($file_path === false || strpos($file_path, $base_dir) !== 0) {
die('Invalid 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);
exit;
实现断点续传
支持HTTP Range请求,实现断点续传功能。
$file_path = 'path/to/file.mp4';
$file_size = filesize($file_path);
$file = fopen($file_path, 'rb');
header('Content-Type: video/mp4');
header('Accept-Ranges: bytes');
if (isset($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
$range = str_replace('bytes=', '', $range);
list($start, $end) = explode('-', $range, 2);
$start = max(0, intval($start));
$end = min($file_size - 1, empty($end) ? ($file_size - 1) : intval($end));
header('HTTP/1.1 206 Partial Content');
header('Content-Length: ' . ($end - $start + 1));
header('Content-Range: bytes ' . $start . '-' . $end . '/' . $file_size);
fseek($file, $start);
$remaining = $end - $start + 1;
while ($remaining > 0) {
echo fread($file, min(8192, $remaining));
$remaining -= 8192;
flush();
}
} else {
header('Content-Length: ' . $file_size);
header('Content-Disposition: attachment; filename="' . basename($file_path) . '"');
echo fread($file, $file_size);
}
fclose($file);
exit;
添加下载统计功能
记录文件下载次数到数据库。
$file_id = $_GET['id'];
$file_path = get_file_path_from_db($file_id);
// 更新下载计数
update_download_count($file_id);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file_path) . '"');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
exit;
这些方法涵盖了从基本文件下载到高级功能的实现,可以根据具体需求选择适合的方案。






