【问题标题】:Browser Caching dynamic content using PHP output buffer and ETag浏览器使用 PHP 输出缓冲区和 ETag 缓存动态内容
【发布时间】:2012-12-30 00:30:06
【问题描述】:

我一直在研究一些策略来优化我正在研究的 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');
?>

【问题讨论】:

标签: php browser caching cache-control


【解决方案1】:

使用快速创建哈希 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');
?>

尝试更快地获取内容到缓冲区

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

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

记住

用户权限可能会在文件缓存中发挥作用,就像您不希望其他人的购物车出现在结帐页面上的任何缓存一样。通常将经过身份验证的用户排除在文件缓存之外是安全的。

在文件上缓存时,必须保护缓存文件免受网络等公共读写访问。

【讨论】:

    最近更新 更多