在PHP动态创建HTTP响应时缓存它们

Meh*_*ran 14 php caching http-headers

我认为我的问题似乎很随意,但随着它变得有趣(至少对我来说:)).

考虑一个PHP页面,其目的是从文件系统读取请求的文件并将其作为响应回显.现在的问题是如何为此页面启用缓存?需要指出的是,文件可能非常庞大,启用缓存是为了避免客户端一次又一次地下载相同的内容.

理想的策略是使用"If-None-Match"请求头和"ETag"响应头来实现反向代理缓存系统.尽管我知道这一点,但我不确定这是否可行,或者我应该将其作为响应返回以实现此技术!

Ja͢*_*͢ck 25

使用PHP提供大量或许多辅助文件并不完全是它的用途.

相反,查看X-accel表示nginx,X-Sendfile表示Lighttpd或mod_xsendfile表示Apache.

初始请求由PHP处理,但是一旦确定了下载文件,它就会设置一些标题来指示服务器应该处理文件发送,之后PHP进程被释放以提供其他服务.

然后,您可以使用Web服务器为您配置缓存.

静态生成的内容

如果您的内容是从PHP生成的并且创建起来特别昂贵,则可以将输出写入本地文件并再次应用上述方法.

如果您无法写入本地文件或不想写入,则可以使用HTTP响应标头来控制缓存:

Expires: <absolute date in the future>
Cache-Control: public, max-age=<relative time in seconds since request>
Run Code Online (Sandbox Code Playgroud)

这将导致客户端缓存页面内容,直到它过期或用户强制页面重新加载(例如按F5).

动态生成的内容

对于动态内容,您希望浏览器每次都ping您,但只有在有新内容的情况下才会发送页面内容.您可以通过设置一些其他响应标头来完成此操作:

ETag: <hash of the contents>
Last-Modified: <absolute date of last contents change>
Run Code Online (Sandbox Code Playgroud)

当浏览器再次ping您的脚本时,它们将分别添加以下请求标头:

If-None-Match: <hash of the contents that you sent last time>
If-Modified-Since: <absolute date of last contents change>
Run Code Online (Sandbox Code Playgroud)

ETag主要用于降低网络流量在某些情况下,知道的内容哈希,你首先要计算它.

Last-Modified如果您有本地文件缓存(文件具有修改日期),则最容易应用.一个简单的条件使它工作:

if (!file_exists('cache.txt') || 
    filemtime('cache.txt') > strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
    // update cache file and send back contents as usual (+ cache headers)
} else {
    header('HTTP/1.0 304 Not modified');
}
Run Code Online (Sandbox Code Playgroud)

如果您无法执行文件缓存,您仍可以使用它ETag来确定内容是否同时更改.