Как заставить браузер кэшировать изображения с PHP?

Думайте об интерфейсе как Контракт. Это - способ сказать, "Эти классы должны следовать за ними ряд правил".

Так в примере IAnimal, это - способ сказать, "Я ДОЛЖЕН быть в состоянии назвать Выполнение, Обход, и т.д. на классах, которые реализуют IAnimal".

, Почему это полезно? Можно хотеть создать функцию, которая полагается на то, что необходимо быть в состоянии назвать Выполнение и Обход, например, на объекте. У Вас могло быть следующее:

public void RunThenWalk(Monkey m) {
    m.Run();
    m.Walk();
}

public void RunThenWalk(Dog d) {
    d.Run();
    d.Walk();
}

... и повторение, которое для всех объектов, которые Вы знаете, может работать и идти. Однако с Вашим интерфейсом IAnimal, можно определить функцию однажды следующим образом:

public void RunThenWalk(IAnimal a) {
    a.Run();
    a.Walk();
}

Путем программирования против интерфейса, Вы по существу доверяете классы для реализации намерения интерфейса. Таким образом в нашем примере, мысль, "Я не забочусь как они Выполнение и Обход, пока они Выполнение и Обход. Мой RunThenWalk будет допустим, пока они выполняют то соглашение. Это функционирует отлично, не зная ничто больше о классе".

существует также хорошее обсуждение в этот связанный вопрос .

24
задан halfer 15 August 2018 в 18:47
поделиться

5 ответов

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

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

5
ответ дан 28 November 2019 в 22:36
поделиться

Прежде всего, если вы используете сеансы, вы должны отключить session_cache_limiter (установив для него значение none или public ]). Заголовки, которые он отправляет, очень плохи для кешей.

session_cache_limiter('none');

Затем отправьте Cache-Control: max-age = number_of_seconds и, возможно, эквивалентный заголовок Expires: .

header('Cache-control: max-age='.(60*60*24*365));
header('Expires: '.gmdate(DATE_RFC1123,time()+60*60*24*365));

Для наилучшая кэшируемость, отправьте заголовок Last-Modified и ответьте со статусом 304 и пустым телом, если браузер отправит соответствующий заголовок If-Modified-Since .

header('Last-Modified: '.gmdate(DATE_RFC1123,filemtime($path_to_image)));

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

if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
   header('HTTP/1.1 304 Not Modified');
   die();
}
49
ответ дан 28 November 2019 в 22:36
поделиться

Вот код, который я использую для поддержки заголовков 304:

  /**
   * @return false if not cached or modified, true otherwise.
   * @param bool check_request set this to true if you want to check the client's request headers and "return" 304 if it makes sense. will only output the cache response headers otherwise.
   **/     
  protected function sendHTTPCacheHeaders($cache_file_name, $check_request = false)
  {
    $mtime = @filemtime($cache_file_name);

    if($mtime > 0)
    {
      $gmt_mtime = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
      $etag = sprintf('%08x-%08x', crc32($cache_file_name), $mtime);

      header('ETag: "' . $etag . '"');
      header('Last-Modified: ' . $gmt_mtime);
      header('Cache-Control: private');
      // we don't send an "Expires:" header to make clients/browsers use if-modified-since and/or if-none-match

      if($check_request)
      {
        if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && !empty($_SERVER['HTTP_IF_NONE_MATCH']))
        {
          $tmp = explode(';', $_SERVER['HTTP_IF_NONE_MATCH']); // IE fix!
          if(!empty($tmp[0]) && strtotime($tmp[0]) == strtotime($gmt_mtime))
          {
            header('HTTP/1.1 304 Not Modified');
            return false;
          }
        }

        if(isset($_SERVER['HTTP_IF_NONE_MATCH']))
        {
          if(str_replace(array('\"', '"'), '', $_SERVER['HTTP_IF_NONE_MATCH']) == $etag)
          {
            header('HTTP/1.1 304 Not Modified');
            return false;
          }
        }
      }
    }

    return true;
  }
7
ответ дан 28 November 2019 в 22:36
поделиться

Вы можете сохранить сгенерированные изображения в каталоге "showImage" чтобы вы могли встроить их вот так

<img src="showimage/601.jpg" />

Затем вы помещаете файл .htaccess в тот же каталог, который будет вызывать showImage.php? id = в случае, если файл не существует, например:

<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)\.jpg$ showImage.php?id=$1 [QSA,L]
</IfModule>

Просто прочтите в своем комментарии, что вы хотите выполнить кэширование на стороне клиента: просто установите связанные с кешированием HTTP-заголовки в соответствии с http://www.mnot.net/cache_docs/

4
ответ дан 28 November 2019 в 22:36
поделиться

Пожалуйста, не адресуйте изображения как некоторый ресурс с идентификатором. используйте абсолютные URL-адреса для изображений, желательно в субдомене, желательно без файлов cookie. Браузер выполнит кеширование изображений. Изящный трюк для более быстрой загрузки изображений на веб-сайты - разместить их на каком-либо CDN или другом сайте. Это связано с тем, что браузеры ограничивают количество потоков параллельных запросов одним доменом.

Еще один изящный способ работы с изображениями - спрайт, посмотрите его. Это экономит много трафика, а также запросов.

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

1
ответ дан 28 November 2019 в 22:36
поделиться