Readfile — лучшее решение для загрузки внешних файлов?

#php #proxy #download #external #readfile

#php #прокси #Скачать #внешний #readfile

Вопрос:

Мне нужно получить удаленный файл и передать его пользователю, не сохраняя его на моем серверном диске (для скрытия исходного URL), и я нашел много сообщений о загрузке внешних файлов с различными функциями, такими как file_get_contents или readfile. Я уже использую этот:

 
function startDownload($url){
        
    if($this->url_exists($url))

    {
        //get filename from url
        $name=$this->getFileName($url);
        
        //first flush clear almost output
        ob_end_flush();
        
        //final clear
        ob_clean();
        
        //set  headers
        header('Content-Type: application/octet-stream');
        header("Content-Transfer-Encoding: Binary");
        header("Content-disposition: attachment; filename="" . $name . """);
        
        //send file to client;
        readfile($url);
        
        //exit command is important 
        exit;       
    }

    else JFactory::getApplication()->enqueueMessage(JText::_('URL_NOT_FOUND'), 'error');

}
  

И это работает, но есть проблема! Для файла размером 200 МБ требуется ~ 10 секунд, чтобы начать загрузку в браузере клиента. Я думаю, это потому, что readfile сначала загружает весь файл в буфер моего сервера, а затем передает его пользователю. Это правильно?

И возможно ли сделать это быстрее? например, загрузка должна быть начата до завершения выборки или это технически невозможно?

На самом деле я не знаю, оптимизирован этот метод или нет. Любые технические рекомендации будут оценены.

Примечание :

  1. Я знаю, что эту функцию следует изменить для больших файлов, и это сейчас не моя забота.
  2. Я рассматриваю возможность покупки внешнего сервера в том же центре обработки данных, чтобы ускорить загрузку.
  3. Цель состоит в том, чтобы [Файловый сервер] был отделен от файла [интернет-магазина].

Комментарии:

1. Я думаю, это потому, что readfile сначала загружает весь файл в буфер моего сервера, а затем передает его пользователю. Это правильно? Мммм … Да .. но именно так работает PHP. Он обрабатывает весь код перед передачей чего-либо клиенту, поэтому технически вы правы, но это не имеет ничего общего с readfile(), file_get_contents и file будут делать то же самое

2. Как часто обновляется этот файл?

3. @Andreas Я сомневаюсь, что файлы вообще обновляются, но предполагаю, что раз в месяц.

4. Ну, тогда почему бы не сохранить локальную копию и обновлять ее, скажем, раз в день. Почему вы не хотите сохранять его на свой сервер?

5. @Andreas Потому что мой сервер магазина использует диск NVME и его размер ограничен. Но есть файловые серверы с диском sata, который дешевле (с большей емкостью). Другая причина в том, что если один диск заполнен, я могу купить / арендовать второй сервер без необходимости переноса предыдущих файлов. Облачное решение, такое как amazon AWS, тоже доступно, но я не хочу использовать его прямо сейчас.

Ответ №1:

Я протестировал метод curl, упомянутый @LawrenceCherone. Он работал хорошо, но когда я перенес его в мой проект, результат был таким же, как readfile (белый экран в течение нескольких секунд).

Поэтому подозреваю функцию readfile(). Разделите мой предыдущий код на один файл PHP, и результат был потрясающим! Загрузка начнется немедленно.

Итак, я думаю, что мое предположение было неверным, и проблема не была связана с функцией readfile.

После небольшого поиска найдено незначительное изменение. Я добавил строку ниже :

 while (ob_get_level()) ob_end_clean();

  

перед :

 readfile($url);
  

И теперь загрузка начинается до того, как весь файл будет извлечен на моем сервере.