Подтвердить что ты не робот

Php, file загрузить

Я использую загрузку простого файла script:

if (file_exists($file)) {
    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, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
}

Он работает на моем локальном сервере до 200 мб.

Когда я пытаюсь использовать этот код на своем веб-сайте, он загружает 173 КБ вместо 200 МБ файла.

Я все проверил, написал какой-то пользовательский код (используя функции ob и fread вместо readfile), но не могу загрузить большие файлы.

Спасибо за ваши ответы.

  • Я использую Apache 2.2, PHP 5.3
  • Все настройки PHP для работы с большими файлами в порядке. (время выполнения, пределы памяти,...
4b9b3361

Ответ 1

Одна из проблем, у меня есть следующий код: вы не имеете контроля над выходным потоком, позволяя PHP обрабатывать его, не зная точно, что происходит в фоновом режиме:

Что вам нужно сделать, так это настроить систему вывода, в которой вы можете управлять и реплицировать серверы accros.

Например:

if (file_exists($file))
{
    if (FALSE!== ($handler = fopen($file, 'r')))
    {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: chunked'); //changed to chunked
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        //header('Content-Length: ' . filesize($file)); //Remove

        //Send the content in chunks
        while(false !== ($chunk = fread($handler,4096)))
        {
            echo $chunk;
        }
    }
    exit;
}
echo "<h1>Content error</h1><p>The file does not exist!</p>";

Это только базовая задача, но приготовьтесь!

Также прочитайте мой ответ здесь: file_get_contents = > PHP Неустранимая ошибка: допустимая память исчерпана

Ответ 3

Одно из решений некоторых сценариев состоит в том, что вы можете использовать PHP- script, чтобы разумно решить, какой файл загружать, но вместо отправки файла непосредственно с PHP вы можете вернуть перенаправление клиенту, который затем содержит прямая ссылка, которая обрабатывается только веб-сервером.

Это можно сделать по крайней мере двумя способами: либо PHP- script копирует файл в "зону загрузки", которая, например, может быть очищена из "старых" файлов регулярно каким-либо другим фоном/службой script или вы открываете реальное постоянное место для клиентов.

Конечно, есть недостатки, как в случае с каждым решением. В этом заключается то, что в зависимости от клиентов (завиток, wget, GUI-браузера), запрашивающих файл, они могут не поддерживать перенаправление, которое вы делаете, а в другом - файлы очень подвержены внешнему миру и могут быть прочитаны всегда без (доступ) для управления PHP script.

Ответ 5

Реальное решение состоит в том, чтобы избежать использования PHP script для просто отправки файла клиенту, он переполняется, и ваш веб-сервер лучше подходит для задачи.

Предположительно, у вас есть причина для отправки файлов через PHP, возможно, сначала пользователи должны пройти аутентификацию? Если это так, вы должны использовать X-Accel-Redirect (если вы используете nginx) или X-Sendfile (ранее X-LIGHTTPD-send-file) на lighttpd.

Если вы используете Apache, я нашел несколько ссылок на mod_xsendfile, но я никогда не использовал его лично, и я сомневайтесь, что он установлен для вас, если вы управляете хостингом.

Если эти решения несостоятельны, я извиняюсь, но мне действительно нужна дополнительная информация о реальной проблеме: почему вы отправляете эти файлы через PHP в первую очередь?