Обязательно учитывайте кэширование при написании таких скриптов!
Веб-сервер, обслуживающий статическое изображение, выполнит согласование с клиентом, когда изображение будет повторно запрошено при следующем посещении страницы, и если сервер определит, что кэшированная копия изображения на стороне клиента все еще действительна, изображение не будет передано повторно.
Поскольку наивный сценарий не выполняет это согласование, изображение будет повторно передаваться клиенту при каждом запросе страницы, что обойдется вам гораздо большей пропускной способностью, чем необходимо.
Для этого есть три механизма. Я не могу сказать вам точно, как написать оптимальный сценарий, поскольку мне никогда не приходилось делать это раньше, и я не уверен, как взаимодействуют различные заголовки кэширования и на какой версии HTTP, но я призываю вас изучить эту проблему. в дальнейшем.
Три механизма, которые я знаю:
Истекает (HTTP / 1.0)
Самый простой. Этот заголовок сообщает клиенту, что изображение обязательно будет действительным до определенного момента времени. Клиент даже не выполнит запрос к сценарию, пока не пройдет это время, поэтому, установив его соответствующим образом, вы сможете сэкономить (некоторые) циклы ЦП на сервере и задержку загрузки изображения в вашем веб-приложении.
То, как вы должны установить это, полностью зависит от вашего приложения; Ваши изображения меняются быстро или редко? Если изображение изменяется до истечения времени, которое вы отправили клиенту, клиент не увидит новое изображение.
Пример:
header("Expires: " . gmdate('D, d-M-Y H:i:s \G\M\T', time() + 60)); // Valid for a minute
(Примечание: срок действия, похоже, был заменен Cache-Control в HTTP / 1.1)
If-Modified-Since (HTTP / 1.1)
Клиент HTTP / 1.1 может отправить этот заголовок, если у него уже есть копия изображения, и отмечает, с какого времени копия копируется. Затем вы можете определить в своей базе данных, была ли текущая версия изображения изменена ранее или позже. Если версия клиента по-прежнему правильная, просто отправьте ответ «304 Not Modified» и выйдите из системы (тем самым, исключив необходимость переноса изображения).
Пример: * 1 034 *
$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».
Поскольку ETag, похоже, фактически предназначен для предотвращения проблем параллелизма в клиентских запросах с побочными эффектами (т. Е. POST и PUT), а также потому, что вычисление хэша является дорогостоящей операцией, я думаю, что подход If-Modified-Since будет лучше подходить для большинства файловых приложений.