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

Как заставить браузер кэшировать изображения с помощью php?

Я совершенно не знаком с тем, как кэшировать изображения.

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

при вызове изображения мне нравится:

<img src="showImage.php?id=601">

и showImage.php -file:

$resultat = mysql_query("
    SELECT filename, id
    FROM Media 
    WHERE id = '".$_GET['id']."'
");
$data = mysql_fetch_assoc($resultat);

...

//Only if the user are logged in
if(isset($_SESSION['user'])){
    header("Content-Type: image/jpeg");

    //$data['filename'] can be = dsSGKLMsgKkD3325J.jpg
    echo(file_get_contents("images/".$data['filename']."")); 
}
4b9b3361

Ответ 1

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

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

Ответ 2

Прежде всего, если вы используете сеансы, вы должны отключить 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();
}

Ответ 3

Вот код, который я использую для поддержки заголовка 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 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;
  }

Ответ 4

Вы можете хранить сгенерированные изображения в каталоге с именем "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/


Имейте в виду, что ваш запрос уязвим для SQL-инъекций, потому что вы не дезинфицируете/не запускаете $_GET ['id']: http://php.net/mysql_real_escape_string

Ответ 5

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

Другой аккуратный способ работы с изображениями - писать, искать. Это экономит много полосы пропускания, а также запросы.

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