在PHPdynamic创build时cachingHTTP响应

我觉得我的问题似乎很随意,但忍受着我,因为它变得有趣(至less对我来说:))。

考虑一个PHP页面,其目的是从文件系统读取所请求的文件,并将其作为响应进行回显。 现在的问题是如何启用caching这个页面? 要指出的是,文件可以是非常巨大的,并启用caching是保存客户端一次又一次下载相同的内容。

理想的策略是使用“If-None-Match”请求头和“ETag”响应头来实现反向代理caching系统。 即使我知道这一点,我不知道这是可能的,或者我应该返回作为回应,以实施这种技术!

使用PHP来提供大量或许多辅助文件并不完全是它所做的。

相反,请查看nginx的X-accel ,Lighttpd的X-Sendfile或Apache的mod_xsendfile 。

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

然后,您可以使用Web服务器为您configurationcaching。

静态生成的内容

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

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

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

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

dynamic生成的内容

对于dynamic内容,您希望浏览器每次都能ping通,但如果有新内容,则只发送页面内容。 你可以通过设置一些其他的响应头来完成这个任务:

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

当浏览器重新编写脚本时,它们将分别添加以下请求标头:

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

ETag主要用于减lessnetworkingstream量,因为在某些情况下,要知道内容散列,您首先必须计算它。

如果您有本地文件caching(文件具有修改date), 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'); } 

如果你不能做文件caching,你仍然可以使用ETag来确定内容是否已经改变。