file_get_contents или readfile для отображения изображения файловой системы

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

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

Короче говоря - это становится кошмаром обслуживания и отладки.

12
задан YakovL 5 June 2016 в 01:34
поделиться

4 ответа

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

26
ответ дан 2 December 2019 в 03:49
поделиться

Я должен использовать fpassthru Используя fopen, вы можете более точно обрабатывать ошибки.

PS: убедитесь, что ваш прямой вывод из файловой системы не уязвим!

0
ответ дан 2 December 2019 в 03:49
поделиться

Я бы сделайте что-нибудь вроде:

header('Content-type: image/jpeg');
readfile('something.jpg');

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

4
ответ дан 2 December 2019 в 03:49
поделиться

Обязательно примите во внимание кеширование при написании подобных сценариев!

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

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

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

Три механизма, о которых я знаю:

Истекает (HTTP / 1.0)

Самый простой. Этот заголовок сообщает клиенту, что изображение определенно будет действительным до данного момента времени. Клиент даже не будет выполнять запросы к сценарию, пока не пройдет это время, поэтому соответствующая установка этого параметра может сэкономить вам (некоторые) циклы ЦП на сервере и задержку загрузки изображения в вашем веб-приложении.

Как вы должны установить это, зависит от полностью в вашем приложении; Ваши образы меняются быстро или редко? Если изображение изменится до истечения времени Expires, которое вы отправили клиенту, клиент не увидит новое изображение.

Пример:

header("Expires: " . gmdate('D, d-M-Y H:i:s \G\M\T', time() + 60)); // Valid for a minute

(Примечание: Expires, похоже, заменен Cache-Control в HTTP / 1.1)

If-Modified-Since (HTTP / 1.1)

HTTP / 1. 1 клиент может отправить этот заголовок, если у него уже есть копия изображения, и отмечает, с какого времени датируется копия. Затем вы можете определить в своей базе данных, была ли текущая версия изображения изменена раньше или позже. Если версия клиента все еще правильная, просто отправьте ответ «304 Not Modified» и выйдите (тем самым предотвращая необходимость передачи изображения).

Пример:

$cache_time   = parse_browsers_date_time_format($_SERVER["IF-MODIFIED-SINCE"]);
$actual_time  = get_current_resource_time_from_db();

if ($actual_time <= $cache_time) {
    header("HTTP/1.1 304 Not Modified");
    die;
}

// ... Produce and output resource here

(Примечание: клиенты могут фактически отправлять только If-Modified-Since , если вы также отправите Last-Modified в исходном ответе. Я не уверен насчет этого, исследуйте сами.)

ETag / If-None -Match (HTTP / 1.1)

Этот метод аналогичен согласованию If-Modified-Since , но вместо времени он использует хэш изображения, чтобы увидеть, есть ли в содержимом изменилось. Это работает следующим образом: сервер вычисляет некоторый хэш для изображения и отправляет этот хеш при первом запросе изображения в заголовке ETag .

При последующих запросах сервер отправит хэш обратно в поле запроса If-None-Match . Если хэш клиента совпадает с текущим хешем изображения, изображение не было изменено между ними, и сценария может быть достаточно, просто отправив «304 Not Modified».

Поскольку ETags, похоже, фактически предназначены для используется для предотвращения проблем параллелизма в клиентских запросах с побочными эффектами (например, POST и PUT), и поскольку вычисление хэша - дорогостоящая операция, я думаю, что подход If-Modified-Since будет лучше подходить для большинства приложений, обслуживающих файлы.

и отправляет этот хэш в первый раз, когда изображение запрашивается в заголовке ETag .

При последующих запросах сервер отправляет хеш обратно в поле запроса If-None-Match ]. Если хэш клиента совпадает с текущим хешем изображения, изображение не было изменено между ними, и сценария может быть достаточно, просто отправив «304 Not Modified».

Поскольку ETags, похоже, фактически предназначены для используется для предотвращения проблем параллелизма в клиентских запросах с побочными эффектами (например, POST и PUT), и поскольку вычисление хэша - дорогостоящая операция, я думаю, что подход If-Modified-Since будет лучше подходить для большинства приложений, обслуживающих файлы.

и отправляет этот хэш в первый раз, когда изображение запрашивается в заголовке ETag .

При последующих запросах сервер отправляет хеш обратно в поле запроса If-None-Match ]. Если хэш клиента совпадает с текущим хешем изображения, изображение не было изменено между ними, и сценария может быть достаточно, просто отправив «304 Not Modified».

Поскольку ETags, похоже, фактически предназначены для используется для предотвращения проблем параллелизма в клиентских запросах с побочными эффектами (например, POST и PUT), и поскольку вычисление хэша - дорогостоящая операция, я думаю, что подход If-Modified-Since будет лучше подходить для большинства приложений, обслуживающих файлы.

9
ответ дан 2 December 2019 в 03:49
поделиться
Другие вопросы по тегам:

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