Тема: Як реалізувати відвантаження файлу великого розміру з сервера до брауз

Вітаю!
Маю невелике завдання, а саме організувати невеличкий файлообмінник, але з підтримкою завантаження і відвантаження файлів великого розміру(до 10ГБ включно)
Якщо завантажити файл на сервер не проблем, то віддати його користувачу поки для мене проблема. І проблема полягає саме у тому, що користувачу не можна просто дати пряме посилання на файл на сервері.
Завантаження має відбувати лише з спеціальної сторінки на самому обміннику. Тобто користувач заходить на спеціальну сторінку, там є кнопка "Завантажити" і після натискання на цю кнопку має почати завантажуватися файл.

Стандартна ідея - зробити завантаження через читання файлу за допомогою fopen чи file і віддавання потоку байтів користувачу.
Це хороша ідея коли файли дуже малі. Але коли файли мають 10ГБ - це просто покладе сервер.
Є ще спосіб через nginx, але він не можливий бо сервер на apache :(

Підкажіть будь ласка якісь ідеї, як реалізувати відвантаження файлів великих розмірів?

Подякували: leofun011

2

Re: Як реалізувати відвантаження файлу великого розміру з сервера до брауз

Колись давно цікавився цим питання, але на практиці не довелось застосовувати, тож все забулося.
Ось знайшов таке посилання, може буде в нагоді...
stackoverflow.com/questions/432713/serving-large-files-with-php

Re: Як реалізувати відвантаження файлу великого розміру з сервера до брауз

Загалом дійшов до схожого рішення - читати файл малими частинами і в потоці віддавати ці частини браузеру.
По суті з очевидних переваг - немає перевантаження пам'яті. З мінусів - якщо є обмеження на час виконання скрипта - можемо впертися в ліміт.

<?php
// Ім'я файлу, яке буде завантажуватися користувачем
$filename = 'example_file.txt';

// Шлях до файлу на сервері
$file_path = '/шлях/до/файлу/на/сервері/' . $filename;

// Перевірка чи файл існує
if (!file_exists($file_path)) {
    die("Файл не знайдено.");
}

// Встановлення заголовків для завантаження файлу
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));

// Відкриття файлу для читання
$handle = fopen($file_path, 'rb');

// Поки не досягнуто кінця файлу
while (!feof($handle)) {
    // Зчитування частини файлу
    $chunk = fread($handle, 1024 * 1024); // 1MB частини

    // Вивід частини на вихід
    echo $chunk;

    // Примусове виведення буферу на вихід
    ob_flush();

    // Відправка виводу браузеру
    flush();
}

// Закриття файлу
fclose($handle);
exit;
?>
Подякували: leofun01, flatliner2

4

Re: Як реалізувати відвантаження файлу великого розміру з сервера до брауз

Це мало б бути краще

  $file = '/path/to/file';
  
  if (file_exists($file)) {
    if (ob_get_level()) {
      ob_end_clean();
    }
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
  }