Обслуживание больших файлов с PHP

Я думаю, что лучшим способом решения вашей проблемы было бы запросить серверное время и рассчитать разницу с вашим местным временем. Вы сохраняете эту разницу и всякий раз, когда вам нужно серверное время, просто добавляете разницу к вашему местному времени.

13
задан Adam 11 January 2009 в 10:28
поделиться

7 ответов

Вы не должны читать, все это - просто вводит цикл, читая его в, скажем, блоках 32 КБ и отправке его, как произведено. Еще лучше используйте fpassthru, который делает почти такую же вещь для Вас....

$name = 'mybigfile.zip';
$fp = fopen($name, 'rb');

// send the right headers
header("Content-Type: application/zip");
header("Content-Length: " . filesize($name));

// dump the file and stop the script
fpassthru($fp);
exit;

еще меньше строк, если Вы используете readfile, которому не нужен вызов fopen...

$name = 'mybigfile.zip';

// send the right headers
header("Content-Type: application/zip");
header("Content-Length: " . filesize($name));

// dump the file and stop the script
readfile($name);
exit;

Если Вы хотите стать еще более милыми, можно поддерживать заголовок Довольного Диапазона, который позволяет клиентам запросить конкретный диапазон байта файла. Это особенно полезно для обслуживания файлов PDF к Adobe Acrobat, которая просто запрашивает блоки файла, это должно представить текущую страницу. Это немного включено, но посмотрите это для примера.

26
ответ дан 1 December 2019 в 17:51
поделиться

Лучший способ отправить большие файлы с php X-Sendfile заголовок. Это позволяет веб-серверу служить файлам намного быстрее через механизмы нулевой копии как sendfile(2). Это поддерживается lighttpd и апачем с плагином.

Пример:

$file = "/absolute/path/to/file"; // can be protected by .htaccess
header('X-Sendfile: '.$file);
header('Content-type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
// other headers ...
exit;

Сервер читает X-Sendfile заголовок и отсылает файл.

10
ответ дан 1 December 2019 в 17:51
поделиться

В то время как fpassthru() был мой предпочтительный вариант в прошлом, руководство PHP на самом деле рекомендует* использование readfile() вместо этого, если Вы просто выводите файл как есть клиенту.

* "Если Вы просто хотите вывести содержание файла к буферу вывода без первого изменения его или ищущий на конкретное смещение, можно хотеть использовать readfile (), который сохраняет Вас fopen () вызов". — Руководство PHP

6
ответ дан 1 December 2019 в 17:51
поделиться

Если Ваши файлы не доступны веб-сервером, потому что путь не находится в Вашем веб-каталоге обслуживания (htdocs) затем, можно сделать символьную ссылку (символьная ссылка) на ту папку в веб-каталоге обслуживания, чтобы не передавать всю транспортную канавку php.

Можно сделать что-то вроде этого

ln -s /home/files/big_files_folder /home/www/htdocs

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

2
ответ дан 1 December 2019 в 17:51
поделиться

Взгляните на fpassthru (). В более поздних версиях PHP это должно служить файлам, не сохраняя их в памяти, как этот комментарий указывает.

1
ответ дан 1 December 2019 в 17:51
поделиться

Одно из преимуществ fpassthru () - то, что эта функция может работать не только с файлами, но и любым допустимым дескриптором. Сокет, например.

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

Еще одна подсказка. fpassthru () содержат открытый дескриптор, пока клиент не становится довольным (который может потребовать довольно долгого времени на медленном подключении), и таким образом, необходимо использовать некоторый механизм блокировки, если параллель пишет в этот возможный файл.

0
ответ дан 1 December 2019 в 17:51
поделиться

Ответы Python являются всей пользой. Но есть ли какая-либо причина, Вы не можете сделать веб-доступный каталог, содержащий символьные ссылки на фактические файлы? Может потребоваться некоторая дополнительная конфигурация сервера, но это должно работать.

0
ответ дан 1 December 2019 в 17:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: