在PHP动态创建HTTP响应时缓存它们 [英] Caching HTTP responses when they are dynamically created by PHP

查看:93
本文介绍了在PHP动态创建HTTP响应时缓存它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为我的问题看起来很随意,但随着它变得有趣(至少对我而言:))。

I think my question seems pretty casual but bear with me as it gets interesting (at least for me :)).

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

Consider a PHP page that its purpose is to read a requested file from filesystem and echo it as the response. Now the question is how to enable cache for this page? The thing to point out is that the files can be pretty huge and enabling the cache is to save the client from downloading the same content again and again.

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

The ideal strategy would be using the "If-None-Match" request header and "ETag" response header in order to implement a reverse proxy cache system. Even though I know this far, I'm not sure if this is possible or what should I return as response in order to implement this technique!

推荐答案

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

Serving huge or many auxiliary files with PHP is not exactly what it's made for.

相反,请查看 X-accel X- Lighttpd的发送文件或Apache的 mod_xsendfile

Instead, look at X-accel for nginx, X-Sendfile for Lighttpd or mod_xsendfile for Apache.

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

The initial request gets handled by PHP, but once the download file has been determined it sets a few headers to indicate that the server should handle the file sending, after which the PHP process is freed up to serve something else.

然后,您可以使用网络服务器为您配置缓存。

You can then use the web server to configure the caching for you.

静态生成的内容

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

If your content is generated from PHP and particularly expensive to create, you could write the output to a local file and apply the above method again.

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

If you can't write to a local file or don't want to, you can use HTTP response headers to control caching:

Expires: <absolute date in the future>
Cache-Control: public, max-age=<relative time in seconds since request>

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

This will cause clients to cache the page contents until it expires or when a user forces a page reload (e.g. press F5).

动态生成的内容

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

For dynamic content you want the browser to ping you every time, but only send the page contents if there's something new. You can accomplish this by setting a few other response headers:

ETag: <hash of the contents>
Last-Modified: <absolute date of last contents change>

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

When the browser pings your script again, they will add the following request headers respectively:

If-None-Match: <hash of the contents that you sent last time>
If-Modified-Since: <absolute date of last contents change>

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

The ETag is mostly used to reduce network traffic as in some cases, to know the contents hash, you first have to calculate it.

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

The Last-Modified is the easiest to apply if you have local file caches (files have a modification date). A simple condition makes it work:

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');
}

如果你不能做文件缓存,你仍然可以使用 ETag 确定内容是否同时发生了变化。

If you can't do file caches, you can still use ETag to determine whether the contents have changed meanwhile.

这篇关于在PHP动态创建HTTP响应时缓存它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆