In development, when dealing with large file downloads, using PHP's readfile() function may seem simple, but for extremely large files, directly reading and outputting the entire file can lead to high memory usage or even memory overflow. Therefore, a more efficient download solution is needed to ensure stability and a better user experience.
Resumable download allows users to resume a download from the point where it was interrupted without having to re-download the entire file. This saves bandwidth, improves reliability, and provides a better user experience, especially in unstable network conditions.
First, retrieve the file path parameter passed by the client via $_GET, and use the basename() function to extract the file name, avoiding security risks such as directory traversal.
$file = $_GET['file'];
$filename = basename($file);
Set Content-Type to application/octet-stream to indicate that the file is being downloaded as binary stream. Also, set the Content-Disposition header to specify attachment download and file name.
Parse the HTTP_RANGE from the request headers to determine the starting position of the download and use fseek() to adjust the file pointer for resumable download support.
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);
}
Use a loop to read the file in chunks (e.g., 4096 bytes at a time) and output the content to the browser. Flush the output buffer to ensure data is sent immediately to the client.
$buffer_size = 4096;
while (!feof($file)) {
echo fread($file, $buffer_size);
ob_flush();
flush();
}
By following these steps, PHP can efficiently support large file downloads with resumable download functionality, overcoming the limitations of the traditional readfile() function. Developers can further enhance this implementation by adding features like download progress display, speed control, etc., for an improved user experience.
By making good use of HTTP Range headers and PHP file handling functions, the download service becomes more stable and flexible, making it suitable for a variety of real-world use cases.