简体   繁体   English

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

[英]Browser Caching dynamic content using PHP output buffer and ETag

I have been researching some strategies to optimize a web application I am working on particularly related to web browser caching and dynamic data. 我一直在研究一些优化我正在开发的Web应用程序的策略,特别是与Web浏览器缓存和动态数据相关。 Since potentially the same dynamic content may be loaded multiple times in a session, I came up with the following method using PHP's output buffer and using a hash of the content as an ETag. 由于可能会在会话中多次加载相同的动态内容,因此我使用PHP的输出缓冲区并使用内容的哈希作为ETag来提出以下方法。

I realize that the only thing I really save with this method is the transfer of data back to the user since the PHP script still has to completely run, but I was curious if anyone has done something similar and if there are any thoughts or concerns I should be aware of or what other methods may be better. 我意识到,我真正用这种方法保存的唯一事情是将数据传输回用户,因为PHP脚本仍然需要完全运行,但我很好奇是否有人做了类似的事情,如果有任何想法或顾虑我应该知道或其他方法可能更好。

Here is the code I am including at the top of each page: 以下是我在每页顶部包含的代码:

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

Use something fast to create the hash crc32 is fast but might give you more collisions than md5 (although filename takes care of some). 快速使用一些东西创建哈希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');
?>

Try to get content faster to the buffer 尝试更快地将内容添加到缓冲区

To get content to be buffered generated faster you could use file caching. 为了更快地生成要缓冲的内容,您可以使用文件缓存。 For example writing generated navigation/blogroll/newslist into a file and reading it from there if filemtime is within cache lifetime ( 10min - 1h etc.) otherwise write it down on file and handle as usual. 例如,如果filemtime在缓存生存期内(10分钟 - 1小时等),则将生成的导航/ blogroll / newslist写入文件并从那里读取,否则将其写入文件并照常处理。

You need write locks to prevent collisions etc. see ZendFramework implementation on that https://github.com/zendframework/zf2/blob/master/library/Zend/Cache/Storage/Adapter/Filesystem.php#L1489 您需要写锁以防止冲突等。请参阅https://github.com/zendframework/zf2/blob/master/library/Zend/Cache/Storage/Adapter/Filesystem.php#L1489上的ZendFramework实现。

Remember 记得

User rights might play a part on filecaching like with any cache you don't want someone else's shopping cart appear on you checkout page etc. Generally leaving authenticated users out of filecache is playing it safe. 用户权限可能在文件缓存中发挥作用,就像任何缓存一样,您不希望其他人的购物车出现在您的结帐页面等。通常将经过身份验证的用户从文件缓存中释放出来是安全的。

When caching on files cache files must be safeguarded from public read and write access over the web and otherwise. 当缓存文件时,必须保护文件缓存文件不受Web上的公共读写访问,否则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM