mikerowe81 Posted January 15, 2013 Share Posted January 15, 2013 I have been researching some strategies to optimize a web application I am working on particularly related to web browser caching and dynamic data. 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. 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. 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'); ?> Quote Link to comment https://forums.phpfreaks.com/topic/273210-browser-caching-dynamic-content-using-php-output-buffer-and-etag/ Share on other sites More sharing options...
kicken Posted January 15, 2013 Share Posted January 15, 2013 Depends on what kind of content it is you're serving up on what kind of caching you might do. If you can reliably determine a last modified date, then do that. For example if you were serving up blog posts you might update the timestamp any time the blog is modified. In such a case, you can use that to generate a Last-Modified header to send with the page. When a url is requested you could check for a $_SERVER['HTTP_IF_MODIFIED_SINCE'] header and do a quick check before actually rendering the blog post out. Eg: <?php if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])){ $lastModified = queryDbForLastModifiedDateOnly(); if (strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified){ header('HTTP/1.1 304 Not Modified'); exit; } } $blogData = queryDbForBlogData(); header('Last-modified: '.$blogData['lastModifiedDate']) //Lookup the proper date format. echo $blogData['contents']; exit; For an etag approach you could do a hash of the contents of the page or some set of data that you need to know if it's changed or not. In the blog example above rather than checking a last modified time you could just hash the $blogData['contents'] and use that as an etag. The potential problems to something like this comes from if you change the sites layout but not any of the content. The cache check wouldn't recognize that since it only checks the content. You could get around that by having an indicator of the last time the layout has changed, such as maybe a layout version # or last changed date that you include in in the cache check. Eg: define('LAYOUT_VERSION', '1.0'); //In a global config file somewhere $etag = crc32(LAYOUT_VERSION.$content); //to generate the tag Changing either the content or the version would cause the etag value to change. Quote Link to comment https://forums.phpfreaks.com/topic/273210-browser-caching-dynamic-content-using-php-output-buffer-and-etag/#findComment-1405953 Share on other sites More sharing options...
mikerowe81 Posted January 16, 2013 Author Share Posted January 16, 2013 Kicken, Thanks for the response. I did consider the last-modified-date, but my content isn't as conducive to that option like your blog example. I am working on a Student Information System, so most of the content will change pretty regularly, which I know kind of defeats the effectiveness of caching, but things like a course's student lists and assignment lists should solidify as a semester progresses thus increasing its effectiveness. I could see where hashing just the content I am concerned about might save some processing, but that would also mean I would need to define what content to hash on each page. The beauty of using the output buffer was I can include the same script on every page knowing that the final output would be hashed and compared just before it is sent. The other aspect of my project I probably should have mentioned was that most of the content is AJAX driven, so that allows me to separate my layout which would be cached independently of my content. Thanks again for your insights, that has helped me thing through some other aspects of this. Quote Link to comment https://forums.phpfreaks.com/topic/273210-browser-caching-dynamic-content-using-php-output-buffer-and-etag/#findComment-1406004 Share on other sites More sharing options...
RealityRipple Posted January 17, 2013 Share Posted January 17, 2013 Just as a side note - I would not use CRC32 as it has a high rate of collision. Quote Link to comment https://forums.phpfreaks.com/topic/273210-browser-caching-dynamic-content-using-php-output-buffer-and-etag/#findComment-1406481 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.