Keywords: PHP File Download | HTTP Headers | Content-Type | Content-Disposition | Performance Optimization
Abstract: This article provides an in-depth analysis of HTTP header configuration in PHP file download functionality, focusing on the mechanisms of Content-Type and Content-Disposition headers. By comparing different MIME type scenarios, it details the advantages of application/octet-stream as a universal file type. Addressing download latency issues, it offers a complete code implementation including chunked file transfer, cache control, and resumable download support to ensure stable and efficient file download operations.
Core Role of HTTP Headers in File Downloads
In web development, proper configuration of HTTP response headers is crucial for ensuring browsers correctly handle file transfers. According to RFC 2046 standards, application/octet-stream is recommended as the universal MIME type for handling unknown file types. When browsers receive this type, they default to saving the data as a file rather than attempting to display it directly in the browser.
Key Configuration of Content-Disposition Header
The Content-Disposition header explicitly instructs the browser to treat the response content as an attachment for download through the attachment parameter. A complete configuration example is as follows:
Content-Disposition: attachment; filename=""example.pdf""
The filename parameter specifies the default name for the downloaded file. For filenames containing special characters, it's recommended to use quotes to ensure compatibility.
Complete PHP File Download Implementation
Below is an optimized file download function implementation that covers MIME type detection, cache control, and resumable download support:
function downloadFile($filePath, $fileName, $mimeType = '') {
// MIME type mapping table
$mimeTypes = array(
'pdf' => 'application/pdf',
'txt' => 'text/plain',
'zip' => 'application/zip',
'jpg' => 'image/jpeg',
'png' => 'image/png'
);
// Automatic MIME type detection
if (empty($mimeType)) {
$extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
$mimeType = isset($mimeTypes[$extension]) ? $mimeTypes[$extension] : 'application/octet-stream';
}
// Clear output buffers
while (ob_get_level()) ob_end_clean();
// Set HTTP headers
header('Content-Type: ' . $mimeType);
header('Content-Disposition: attachment; filename="' . rawurlencode($fileName) . '"');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');
// Handle resumable downloads
$fileSize = filesize($filePath);
if (isset($_SERVER['HTTP_RANGE'])) {
// Parse range request
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
list($start, $end) = explode('-', $range);
$start = intval($start);
$end = $end ? intval($end) : $fileSize - 1;
header('HTTP/1.1 206 Partial Content');
header('Content-Length: ' . ($end - $start + 1));
header('Content-Range: bytes ' . $start . '-' . $end . '/' . $fileSize);
// Output file content in chunks
$handle = fopen($filePath, 'rb');
fseek($handle, $start);
while (!feof($handle) && !connection_aborted() && ($pos = ftell($handle)) <= $end) {
echo fread($handle, min(8192, $end - $pos + 1));
flush();
}
fclose($handle);
} else {
// Complete file download
header('Content-Length: ' . $fileSize);
readfile($filePath);
}
exit;
}
Performance Optimization and Compatibility Considerations
To address download latency issues, the implementation employs multiple optimization measures: disabling output compression, using chunked transfer, and promptly clearing buffers. Additionally, using rawurlencode for filename processing ensures compatibility with special characters. For large file downloads, the chunked transfer mechanism effectively reduces memory usage and improves transmission stability.
Practical Application Recommendations
When deploying in production environments, it's recommended to combine with server configuration for further optimization. For instance, for static files, consider using the web server to handle download requests directly to avoid PHP script execution overhead. For dynamically generated files, ensure all processing logic is completed before output to prevent timeout issues caused by prolonged script execution.