浏览器使用PHP输出缓冲区和ETag缓存动态内容

时间:2013-01-15 19:47:48

标签: php browser caching cache-control

我一直在研究一些优化我正在开发的Web应用程序的策略,特别是与Web浏览器缓存和动态数据相关。由于可能会在会话中多次加载相同的动态内容,因此我使用PHP的输出缓冲区并使用内容的哈希作为ETag来提出以下方法。

我意识到我真正用这种方法保存的唯一事情是将数据传输回用户,因为PHP脚本仍然需要完全运行,但我很好奇是否有人做过类似的事情并且有任何想法或者我应该注意的问题或者其他方法可能更好。

以下是我在每页顶部包含的代码:

<?php
function hash_buffer($content) {
    $buffer_hash = crc32($content);
    if ($_SERVER['HTTP_IF_NONE_MATCH'] == $buffer_hash) {
        header('HTTP/1.1 304 Not Modified');
        header("ETag: $buffer_hash");
        return '';
    }
    header('Cache-Control: private, no-cache');
    header("ETag: $buffer_hash");
    return $content;
}

ob_start('hash_buffer');
?>

1 个答案:

答案 0 :(得分:0)

使用快速创建哈希crc32的速度很快,但可能会比md5更多地发生冲突(尽管文件名可以解决一些问题)。

<?php
function hash_buffer($content) {
    $buffer_hash = crc32($content);

    // You could add expire time so the check is not made every time.
    // Or force it to happen always
    header('Expires:');//.date('r',strtotime('+1 hour')));

    // Add vary header so client knows to usee ETag
    // Without overwriting existing vary headers
    header('Vary: If-None-Match',false);

    if ($_SERVER['HTTP_IF_NONE_MATCH'] == $buffer_hash) {
        header('HTTP/1.1 304 Not Modified');
        header("ETag: $buffer_hash");
        return '';
    }
    header('Cache-Control: private, no-cache');
    header("ETag: $buffer_hash");
    return $content;
}

ob_start('hash_buffer');
?>

尝试更快地将内容添加到缓冲区

要更快地生成要缓冲的内容,您可以使用文件缓存。例如,如果filemtime在缓存生存期内(10分钟 - 1小时等),则将生成的导航/ blogroll / newslist写入文件并从那里读取,否则将其写入文件并照常处理。

您需要写入锁以防止冲突等。请参阅https://github.com/zendframework/zf2/blob/master/library/Zend/Cache/Storage/Adapter/Filesystem.php#L1489上的ZendFramework实现

记住

用户权限可能会在文件缓存方面发挥作用,就像任何缓存一样,您不希望其他人的购物车出现在您的结帐页面等。一般情况下,将经过身份验证的用户从文件缓存中释放出来是安全的。

当缓存文件时,必须保护缓存文件不受Web上的公共读写访问的影响。