如何缓存动态创建的图像?

时间:2016-10-31 10:30:52

标签: php caching php-gd

我有一个生成* .png图片的php脚本,但将它们存储在服务器上。这些图片将重复显示给同一个用户。我正在寻找一种缓存这些图片的方法。我能够发送304状态标题,浏览器还会在第一次刷新时将网页声明为缓存(因为它在Web检查器中可见)但网页显示为空白。在第二次刷新后,即使Web检查员显示空白。

有人能帮帮我,告诉我搞砸了吗?

注意:

  • 我读过this post,但这对我没有帮助。
  • 使用MAMP(PHP版本7.0.10)
  • 我是新手,为丑陋的代码道歉。

以下是该文件的主要内容:

session_start();
header("Content-type: image/jpeg");
//A little require_once() here on some functions stored in an other file.
$originalSource = getSource($_GET['src']);
if (isset($_COOKIE[sha1($originalSource)]) && $_COOKIE[sha1($originalSource)]) {
    header("HTTP/1.1 304 Not Modified");
    die;
} else {
    setcookie (sha1($originalSource), true, time()+10);
    $offset = 10;
    $expire = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
    header($expire);
    header("Cache-Control: max-age=".$offset);
    header("Last-Modified: Wed, 25 Feb 2015 12:00:00 GMT");
}
//The entire image generation process after this

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

您的服务器决定是否认为浏览器仍然应该缓存图像。显然,这不是权威。浏览器可能将图像缓存的原因有很多,例如:如果您打开检查器工具(通常禁用缓存)。

浏览器具有一种机制,用于通知服务器其缓存状态:the HTTP headers If-None-Match用于ETagsIf-Modified-Since用于基于时间的到期。如果请求中存在这两个标头中的任何一个,这意味着浏览器仍然拥有资源缓存的副本,并且很乐意接受304响应,而不是再次下载资源。

如果您在响应中设置了ETag标头,浏览器将使用If-None-Match执行另一个请求(这实际上会更可靠地替换您的Cookie机制);如果您只设置了过期日期,浏览器将使用If-Modified-Since标头再次检查服务器。这就是您应该根据304回复的原因。

使用ETags的示例:

$hash = sha1($originalSource);

header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");

if (
    isset($_SERVER['HTTP_IF_NONE_MATCH']) &&
    trim($_SERVER['HTTP_IF_NONE_MATCH'], '"') === $hash
) {
    header("HTTP/1.1 304 Not Modified");
    exit;
}

header("Content-type: image/jpeg");
header("Cache-Control: max-age=$offset");
header("ETag: \"$hash\"");

// output image