Caching Dynamic PHP pages easily

17 February 2009| 29 Comments| Print

I’ve been looking for a solution to cache heavy pages and just serve a static html version for a little while now, and I’ve found a solution in output buffering.

Things to think about

It’s not a good idea to go away and cache your entire site, you need to think about which pages receive high traffic, and which pages make a number of database requests. Static HTML pages aren’t going to see a benefit from caching and may in fact be served slower due to PHP invoking the request to the cached version. as an example I’m using caching on dotdashcreate.com homepage as there are a number of database requests that could easily be cached, the cached version of the page is stored here.

If you run a big site or blog I would certainly recommend caching your homepage as this will usually be your visitors first point of contact thus generating more traffic. Its probably not a good idea to cache individual posts that allow comments etc, unless you are willing to write a script to re-cache the page.

You need to allow write access to the cache directory, in the code example this is /cache/. There’s quite a bit going on in the script, the first two lines set the path to the cached directory and the time frame to refresh the cache, we then do a check to see if the cached file is older than the cache time, if it is then it refreshes the cached version (which is the block of code at the bottom), if not it just serves the cached version.

The Code:


$cachefile = 'cache.html';
$cachetime = 4 * 60;
// Serve from the cache if it is younger than $cachetime
if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
    include($cachefile);
    echo "<!-- Cached copy, generated ".date('H:i', filemtime($cachefile))." -->\n";
    exit;
}
ob_start(); // Start the output buffer

/* Heres where you put your page content */

// Cache the contents to a file
$cached = fopen($cacheFile, 'w');
fwrite($cached, ob_get_contents());
fclose($cached);
ob_end_flush(); // Send the output to the browser

demo

29 Comments

  • Patternhead

    If you’re using using Wordpress then the wp-supercache plugin works pretty well!

  • Ashley (author)

    That’s a great point, I should have mentioned that in my post! I’m currently using the wp-supercache plugin, well worth installing if you anticipate spikes in blog traffic.

  • Daily Links | AndySowards.com :: Professional Web Design, Development, Programming, Hacks, Downloads, Math and being a Web 2.0 Hipster?

    [...] Caching Dynamic PHP pages easily | Ashley Ford – PaperMashup.com Quick and easy tutorial for caching Dynamic PHP Pages! (tags: webdev work cache easy caching pages) [...]

  • 20 Useful PHP Components & Tutorials for Everyday Project | Noupe

    [...] 9. Caching Dynamic PHP pages easily [...]

  • Wordpress Blog Services - 20 Useful PHP Components &amp; Tutorials for Everyday Project

    [...] 9. Caching Dynamic PHP pages easily [...]

  • Traducciones

    nice post! i will use it

  • Andrew Gill

    Great article. My homepage (index.php) is also calling the database many times. So i’ve used your approach slightly differently by creating an index.html page in the root so there is no need for the include.

  • AzeriFire

    Hi. Thank you for this little, but powerful code. I use SEF URL on my sites. There are problem with “/” (slash). If site URI ll be for sample – /nokia/n97/comments/page/1.html this cache script will look for cache folder, then nokia folder, then inside of nokia folder for n97 subfolder and etc… There are will be PHP errors on site (Not found page and etc.). I improved it little more.And use global variable to define is the caching this page indeed. For sample, I don’t need caching login page and etc. I use $useCache variable ($useCache=0 to disable, =1 to enable caching currently viewing page.)
    And finally improved script:
    http://paste.org/5665
    OR
    http://www.pastethat.com/use_cache_with_p

    Thanks again!
    P.S. Sorry for my poor English.

  • Ashley (author)

    AzeriFire,

    Thanks for the comments and code update! Glad to hear you found it useful and adapted the code in your own way.

    Ashley

  • AzeriFire

    Thank you admin :)
    There are some new correction too:
    Replace this one:
    [code]if (isset($_SERVER['REQUEST_URI'])) // Is there any URI to cache
    [/code]

    with this one:

    [code]if (isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI']!="/") [/code]

    to escape problems when site URL ends with slash (http://site.com/)

    Latest version is here:
    http://paste.org/5666

    P.S. Sorry for spam

  • Jurriën Dokter

    Used it, in my “freshly” created cms. Works like a charm!

  • jebaird

    First off I have gota say that this caching idea kicks ass.
    I have created a class based on the original code and user comments code. Also i fixed a couple of bugs:

    here is the link:
    http://www.jebaird.com/blog.php?year=2009&month=03&cat=3&id=32

  • Ashley (author)

    Hey Jebaird,

    Great response and thanks for the comment ;)

    Ashley

  • 20 Useful PHP Components & Tutorials for Everyday Project « Hdeya team blog

    [...] 9. Caching Dynamic PHP pages easily [...]

  • Easy PHP Caching: Speed-Up Dynamic Content

    [...] has a short article on how to apply a basic cache to your scripts. It’s not a good idea to go away and cache your entire site, you need to think about which pages [...]

  • Dynamic page caching with PHP and output buffering | Spoonfed Project

    [...] that I needed a way to cache these files. A few Google searches later led me to an article over at PaperMashup. Basically, the way it works is by utilizing PHP’s output buffering. It checks to see if the [...]

  • Angels Picks » Blog Archive » 20 Useful PHP Components & Tutorials for Everyday Project

    [...] 9. Caching Dynamic PHP pages easily [...]

  • 40+ Invaluable PHP Tutorials and Resources | Ouech.net

    [...] Visit Article [...]

  • Steve Clay

    You might as well send HTTP cache headers as well: header(‘Cache-Control: public, max-age=’ . $cacheTime);

    Also, you might get a slight perf boost using readfile() over include, since the cache file will have no PHP blocks.

  • Ashley (author)

    @steve good point with the cache header, never used readfile() will have to look into that. Thanks for the feedback :)

  • Marc

    Idea is good, but filemtime is innacurate to give the last time the file was modified for that case. If you try it you will see.. you can modify the file and unix will tell php that the file was modified on the date it was created. Use filectime to get the last time the inode of the file was changed, since you overwrite the file each X seconds, the inode meta data will change, giving you valid informations about the file.

  • 40+ Invaluable PHP Tutorials and Resources | rapid-DEV.net

    [...] Visit Article [...]

  • Tommy M

    @Marc, @Steve, @ Ashley.

    filectime is more accurate, so I implemented that with Marc’s advice.

    Additionally, Steve is correct to use readfile. It ran considerably faster!

    Thanks for this great technique!

  • Davinder

    Hello.
    I love this tutorial but there is a problem
    Why not use PHP strip slashes e.g. if i type in (with out the spaces) i could easily cross refrence……. your site

  • 25 New & Useful PHP Techniques & Tutorials

    [...] 3. Caching Dynamic PHP pages easily [...]

  • Daniel

    Thanks…

    Just installed the code, works really well ! !

    Nice and easy is how I like it…

  • links for 2009-11-09 | Yostivanich

    [...] Caching Dynamic PHP pages eas­ily | Papermashup.com “I’ve been look­ing for a solu­tion to cache heavy pages and just serve a sta­tic html ver­sion for a lit­tle while now, and I’ve found a solu­tion in out­put buffering.” (tags: php html web­de­vel­op­ment pro­gram­ming opti­miza­tion cache) [...]

  • CodesTips

    Caching is very usefull on website with big databases. I wrote a post about cache on my blog:cache file in php

  • Useful PHP Components & Tutorials for Everyday Project « UR-Technology

    [...] 9. Caching Dynamic PHP pages easily [...]

Leave a comment...

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled site. To get your own globally-recognized-avatar, register at Gravatar.