Zend Framework Source Code Snippets

NotModified Cache Controller Plugin

Bookmark and Share
1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
19
2021
22
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
4041
42
43
44
4546
47
48
49
5051
52
53
54
5556
57
58
59
6061
62
63
64
6566
67
68
69
7071
72
73
74
7576
77
78
79
8081
82
83
84
8586
87
88
89
9091
92
93
94
9596
97
98
99
100101
102
103
104
105106
107
108
109
110111
112
113
114
115116
117
118
119
120121
122
123
124
<?php
/**
 * Exposition_Controller_Plugin_NotModifiedCache class in /Exposition/Controller/Plugin
 *
 * PHP Version 5.2.11 or 5.3 *
 * @category  Exposition
 * @package   Exposition_Controller_Plugin
 * @author    Harold Thetiot <hthetiot@gmail.com>
 * @copyright 2006-2009 Netvibes. * @license   Netvibes - All rights reserved
 * @link      http://netvibes.com
 */
 
require_once 'Zend/Controller/Plugin/Abstract.php'; 
/**
 * Zend Controller Plugin to controls Etags and use browser cache
 *
 * @see Specification http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19 * @see Testing http://redbot.org/
 *
 * @category  Exposition
 * @package   Exposition_Controller_Plugin
 * @author    Harold Thetiot <hthetiot@gmail.com> * @copyright 2006-2009 Netvibes.
 * @license   Netvibes - All rights reserved
 * @link      http://netvibes.com
 */
class Exposition_Controller_Plugin_NotModifiedCache extends Zend_Controller_Plugin_Abstract{
    /**
     * Defined by Zend_Controller_Plugin_Abstract
     */
    public function dispatchLoopShutdown()    {
        $response = $this->getResponse();
 
        // no cache if error found or if response
        // is not a Zend_Controller_Response_Http instance        if (!($response instanceOf Zend_Controller_Response_Http) || $response->isException()) {
            return;
        }
 
        // Generate unique Hash-ID by using sha1        $hashID = sha1($response->getBody());
 
        // Specify the time when the page has
        // been changed. For example this date
        // can come from the database or any        // file. Here we define a fixed date value:
        $lastChangeTime = 1144055759;
 
        // Define the proxy or cache expire time
        $expireTime = 3600; // seconds (= one hour) 
        // Get request headers:
        $headers = apache_request_headers();
        // you could also use getallheaders() or $_SERVER
        // or HTTP_SERVER_VARS 
        // Set cache/proxy informations:
        $response->setHeader('Cache-Control', 'max-age=' . $expireTime); // must-revalidate
        $response->setHeader('Expires', gmdate('D, d M Y H:i:s', time() + $expireTime) . ' GMT');
         // Set last modified (this helps search engines
        // and other web tools to determine if a page has
        // been updated)
        $response->setHeader('Last-Modified', gmdate('D, d M Y H:i:s', $lastChangeTime) . ' GMT');
         // Send a "ETag" which represents the content
        // (this helps browsers to determine if the page
        // has been changed or if it can be loaded from
        // the cache - this will speed up the page loading)
        $response->setHeader('ETag', $hashID); 
        // The browser "asks" us if the requested page has
        // been changed and sends the last modified date he
        // has in it's internal cache. So now we can check
        // if the submitted time equals our internal time value.        // If yes then the page did not get updated
        $PageWasUpdated = !(isset($headers['If-Modified-Since']) && strtotime($headers['If-Modified-Since']) == $lastChangeTime);
 
        // The second possibility is that the browser sends us
        // the last Hash-ID he has. If he does we can determine        // if he has the latest version by comparing both IDs.
        // Warning: If-None-Match header can have a value like "hash0, hash1"
        $DoIDsMatch = (isset($headers['If-None-Match']) && strpos($headers['If-None-Match'], $hashID) !== false);
 
        // Does one of the two ways apply?        if (!$PageWasUpdated or $DoIDsMatch){
 
            // Okay, the browser already has the
            // latest version of our page in his
            // cache. So just tell him that            // the page was not modified and DON'T
            // send the content -> this saves bandwith and
            // speeds up the loading for the visitor
            $response->setHttpResponseCode(304);
             // That's all, now close the connection:
            $response->setHeader('Connection', 'close');
 
            // The magical part:
            // No content here ;-)            $front = Zend_Controller_Front::getInstance();
            $front->returnResponse(false);
 
            // Just the headers
            $response->sendHeaders(); 
        } else {
 
            // Okay, the browser does not have the
            // latest version or does not have any            // version cached. So we have to send him
            // the full page.
            $response->setHttpResponseCode(200);
 
            // Tell the browser which size the content            $response->setHeader('Content-Length', mb_strlen($response->getBody(), 'latin1'));
        }
    }
}

Comments

Yosh Yosh
1 year ago

Content-length does not counts the body lenght, but the response object elements. You should use $response->getBody().

Also you should not use mb_strlen(), as this counts the characters and not the bytes.
Use strlen() when mbstring.func_overload is disabled, or mb_strlen($body, 'latin1').

Kind regards,

Yosh de Vos

You must login before commenting on a snippet. If you do not have an account, please register.

Snippet description

NotModified Cache Controller Plugin for better clients browser and server bandwidth usage.

Snippet details

Created:
Harold Thétiot Harold Thétiot
2 years ago
Edited:
Harold Thétiot Harold Thétiot
4 months ago
Revision Id:
214
Edit Message:
Initial Release
ZF Version
1.10.7
Tags:
cache etag Cache-Control Expires NotModified
Comments:
1
Views:
3071
Points:
1 (1 votes)

History

r214

Initial Release

Harold Thétiot Harold Thétiot
4 months ago
diff
r213

Initial Release

Harold Thétiot Harold Thétiot
4 months ago
diff
r125

Initial Release

Harold Thétiot Harold Thétiot
2 years ago
diff
r124

Initial Release

Harold Thétiot Harold Thétiot
2 years ago