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.

, ,

  1. #1 by Mary Nicole Hicks on October 9, 2008 - 1:59 pm

    I think the first bit of code is wrong. It should be:

    Header set Cache-Control “max-age=3601, public”

  2. #2 by Mary Nicole Hicks on October 9, 2008 - 2:01 pm

    Woops, last comment got stripped of tags…
    Second try:

    I think the first bit of code is wrong. It should be:
    IfModule mod_headers.c NOT IfModule mod_expires.c

  3. #3 by umpirsky on July 21, 2009 - 1:39 am

    Thanks, this helped.

  4. #4 by jkulak on December 15, 2010 - 4:28 am

    And usually it’s best to set up those rules in boostrap of your application. Works best together with Zend Cache Frontend

  5. #5 by tarun on March 3, 2015 - 12:55 am

    Thanks for writing this article.

    Can you please help me to know how do i cache media files like .mp4 or .webm that gets loaded on the page (i want to do this for the CDN)

(will not be published)