PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Zend Framework 101: Zend_Cache

Caching Entire Pages

As discussed earlier, one of the front-ends available for Zend_Cache is the Zend_Cache_Frontend_Page class. This front-end will automatically save all output from a PHP script to its cache then serve it in future when the page is re-requested.

Using this front-end is extremely simple. All you need to do is call the start() method on the page. If the current page is found in cache it will be returned and the script will exit, otherwise it will continue to process the script normally.

In fact, you don't even need to tell the cache to save. It detects when the entire script finishes and handle all of the cleanup and saving to cache automatically. You do not need to specify the cache ID when you call start(). You can if you like, but otherwise it will generate the cache ID automatically based on the front-end settings.

When configuring this front-end, you need to specify which pages it is allowed to cache (based upon the page URI). This is achieved using a series of regular expressions, stored in the regexps parameter.The regular expression serves as the array key, while its value is an array of options. You must enable the cache for the given regular expression (or you can disable it if it's a subset of another regular expression).

You must also indicate how cache IDs should be generated. For each of get, post, session, files and cookies you must indicate if the values are used when generating the ID, and if an ID can be generated when values are present.

For example, if a page can be cached when there are values in $_COOKIE, specify cache_with_cookie_variables. If the actual values in $_COOKIE are to be used when generating the ID, specify make_id_with_cookie_variables.

Note: Getting these settings right can take some tweaking initially, but once you figure it out they shouldn't need to be changed.

The following code demonstrates basic usage of Zend_Cache_Frontend_Page. Typically your pages will do a lot more than this one, but this should serve to demonstrate how it works. In this code we specify just one regular expression, which will include every page in the site.

When writing this code, I had cookies set on the domain I was testing. To allow caching with these set, I enabled cache_with_cookie_variables.

Listing 5 Caching an entire page (listing-5.php)
<?php
    require_once('Zend/Cache.php');
 
    $frontendOptions = array(
        'debug_header' => true,
        'regexps' => array(
            '^/' => array(
                'cache' => true,
                'cache_with_cookie_variables' => true,
            )
        )
    );
 
    $backendOptions = array(
        'cache_dir' => './cache'
    );
 
    $cache = Zend_Cache::factory(
        'Page',
        'File',
        $frontendOptions,
        $backendOptions
    );
 
    $cache->start();
?>
<html>
    <head>
        <title>My Cached Page</title>
    </head>
    <body>
        <div>
            This page is running through Zend_Cache_Frontend_Page!
        </div>
    </body>
</html>

One other aspect of this code to be aware of is the debug_header parameter. Setting this to true means a short message is displayed (but not saved in cache) at the top of a page when a cached version is served.

This is useful for debugging when making changes to your web site. My web applications typically have some kind of flag to indicate if the site is in development mode. This allows me to do something like 'debug_header' => IN_DEVELOPMENT.

Saving Headers

There's no rule that states pages must be in HTML format. You can use this front-end to serve dynamic JavaScript or CSS (or even images) if you really wanted to. Note however that doing so may require custom HTTP headers.

If the page being cached uses any custom headers (such as Content-Encoding for gzipped pages, or Content-Type if you're not serving HTML), you need to tell the cache to store these headers.

This is achieved by specifying the memorize_headers parameter. If you do not specify these headers to remember, cached pages will be returned and the headers won't all be set. This may cause the page to not be rendered correctly.

The following listing demonstrates specifying headers to be remembered.

Listing 6 Memorizing HTTP header (listing-6.php)
<?php
    $frontendOptions = array(
        'memorize_headers' => array(
            'Content-type',
            'Content-encoding'
        )
    );
?>

Cancelling the Cache

In some cirumstances you might get half way through processing a script then realize that it shouldn't be cached. This might occur if you have a blanket page cache on every single script (and every URI) but some scripts mustn't be cached.

To prevent the page from being saved to cache you can call the cancel() method on the cache object.

In This Article