Cache-Control with Zend Framework

Today I was optimizing a site that uses heavy PHP and Ajax. I wanted to reduce the amount of data that was being sent from the server. To put this in perspective, if there were no cache hits in a page load there would be a total of 755 KB pulled down over 123 requests.

The first step was throwing a .htaccess into the dojo folder that sets the Cache-Control header on the library files being pulled down.

<IfModule mod_expires.c>
     Header set Cache-Control "max-age=3600, public"
</IfModule>

The above checks to ensure the mod_expires module is loaded in apache, and if it is the Cache is set to expire 3600 seconds from now: 1 hour. Furthermore, the page can be cached in a publicly accessible (shared) cache.

Getting caching working with Zend was a little more challenging. By default Zend (or PHP) writes caching information to headers disabling caching. However, the code snippit below (to be placed inside an Action Controller) blanks out the expires header, sets the cache-control header so that the page expires in one hour, and blanks out the Pragma header.

The expires header allows the server to specify a date when the cache expires (Rather than setting the max-age offset) and the Pragma indicates if the page can be cached in a proxy. I found, with Firefox 3, if Expires and Pragma weren’t blanked out, they would take preference over the Cache-Control header, disabling caching of the page.

$this->getResponse()->setHeader('Expires', '', true);
$this->getResponse()->setHeader('Cache-Control', 'public', true);
$this->getResponse()->setHeader('Cache-Control', 'max-age=3800');
$this->getResponse()->setHeader('Pragma', '', true);

After the addition of caching, the page load was reduced to 8Kb of data pulled down over 9 requests: about a 90% optimization.