В PHP отправка файла в браузер на скачивание осуществляется в 2 этапа:
Первый вариант с явным указанием типа файла mime:
$file = __DIR__ . '/file.avi';
header('Content-Description: File Transfer');
header('Content-Type: video/x-msvideo');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
Второй, application/octet-stream
– «двоичный файл без указания формата».
$file = __DIR__ . '/file.avi';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
Заголовок с размером файла – header('Content-Length: ' . filesize($file));
можно не указывать.
Перед отправкой файла нужно убедится что буферизация вывода отключена с помощью ob_get_level() или сбросить и отключить ее функцией ob_end_clean()
.
Непосредственно чтение и вывод файла можно сделать следующими функциями:
readfile
fread
if ($handle = fopen($file, 'rb')) {
while (!feof($handle)) {
echo fread($handle, 1024);
}
fclose($handle);
}
exit();
file_get_contents
Полный пример
ob_end_clean();
$file = __DIR__ . '/file.avi';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
readfile($file);
exit();