在开发过程中,遇到大文件下载需求时,使用PHP的readfile()函数虽然简单,但对于超大文件,直接读取整个文件输出会导致内存占用过高甚至溢出。因此,需要采用更高效的下载方案来保证程序稳定性和用户体验。
断点续传允许用户在下载中断后,可以从中断位置继续下载,无需重复下载已完成的部分。这不仅节省了带宽,也提升了下载的可靠性和用户满意度,尤其在网络环境不稳定时尤为重要。
首先,通过$_GET获取客户端传入的文件路径参数,并利用basename()函数提取文件名,避免目录穿越等安全风险。
$file = $_GET['file'];
$filename = basename($file);
通过设置Content-Type为application/octet-stream,告诉浏览器这是一个二进制文件流。同时设置Content-Disposition头,指明附件下载和文件名。
根据请求头中的HTTP_RANGE,解析出下载起始位置,并使用fseek()调整文件指针,实现断点续传。
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
if (isset($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
preg_match('/bytes=(\d+)-/', $range, $matches);
$start = intval($matches[1]);
fseek($file, $start);
}
通过循环读取文件内容,每次读取一定大小的缓冲区(例如4096字节),逐步输出给浏览器,并刷新输出缓冲,保证数据及时传输。
$buffer_size = 4096;
while (!feof($file)) {
echo fread($file, $buffer_size);
ob_flush();
flush();
}
通过上述方法,PHP可以高效支持超大文件的断点续传下载,解决了传统readfile()函数在大文件处理上的不足。开发者还可以基于此实现下载进度显示、限速控制等功能,进一步提升用户体验。
合理利用HTTP协议的Range头和PHP文件操作函数,可以让下载服务更加稳定与灵活,适合各种实际业务场景。