ASPit - Totally ASP JSit - Totally JavaScript
Search PHPit

Use this textbox to search for articles on PHPit. Seperate keywords with a space.

Advertisements

How to build a simple caching system, with PHP

(Page 1 out of 2)

Introduction

When you run a popular website that uses PHP and MySQL you will most likely notice that your website becomes slow when your website is at its busiest. If you've really optimized your PHP script and MySQL server, you'll probably be able squeeze some additional performance out of your website, but there comes a time when it's just too much to handle. That's where caching comes in.

If you cache frequently visited data, and this usually includes your homepage, you can drasticly reduce your website's response time. By caching data to the file system, you completely cut MySQL out of the picture, and that is usually the biggest bottleneck. Another added benefit is that it will decrease the load on your MySQL server, making it faster for data that hasn't been cached yet.

In this tutorial, I'm going to show you how to create a bare-bones caching system. Our system will be able to cache a complete page, by using the output buffer to save its HTML.

Using an output buffer callback

The easiest way to cache something is to simply turn output buffering on at the top of your page, and then get the contents of the page by using ob_get_contents(), but that would mean we'd have to add a line of code to the bottom of each PHP file we want to cache.

The best way for our caching system is if we could just include one file at the top of each page, and that handles everything for us. And that's exactly what we're going to do, by setting an output buffer callback.

An output buffer callback can be used to do something with the content when the buffer has ended, and this is usually at the end of the page. Consider the following code:

function my_callback ($content) {
        $content .= "We added a new line!";
        return $content;
}

ob_start ('my_callback');

?>
This is a test

(View Live Demo)

When you run this code, you will notice that it adds a new line, and that's exactly how our caching system is going to save the contents of the page.

Time of the cache

Another thing we must consider when creating our caching system is how long cached data should be valid, and this really depends on your website. For example, PHPit only gets updated every 2-3 days, so if I were to implement a caching system on PHPit, I could let the cached data be valid for 2 days. But if you add updates every day, you will probably want to set a shorter cache time.

Our caching system must somehow mark the data with a timestamp. The easiest way of doing this is to simply include the timestamp with the data, and separate it from the data, like so:

4832029394|rest of data goes here...

When getting the data, our caching system will then extract the timestamp, and check if the data is still valid.

Next: Bringing it all together »



9 Responses to “How to build a simple caching system, with PHP”

  1. Ramy Says:

    Dear Sir/Madam,

    this is really good but I am having problem accesing to the next page.
    Thank you.

    Regards,

    Ramy Tran.

  2. Duncan Crombie Says:

    I haven’t actually run the script, but can see some problems with this script:

    - use time() instead of mktime() to get the current timestamp
    - the logic in get_url() seems to be reversed: if (!isset($_SERVER[’REQUEST_URI’])) $url = $_SERVER[’REQUEST_URI’];
    - why load the entire cache file into memory just to check the date? I would use filemtime instead…

    ;)

  3. Duncan Crombie Says:

    Forgot the most imporant:

    - NEVER chmod to 777!!!

  4. Dennis Pallett Says:

    I fixed the get_url() logic, it was a small mistake that comes from my testing.

    Does it really matter if you use time() instead of mktime()? Both return the same thing anyway.

    I like your idea of using filemtime instead of using my method. It’s probably a bit faster, and easier.

    I understand that chmod’ing to 777 is a bad thing, but at least it works in all cases. Better of course would be something like 776 or 664.

    Thanks for your comments!

  5. Laszlo Baranyai Says:

    File lock could improve this cache system. What will happen if concurrent visitors are reading the page? The first will truncate the cache file to zero length and starts writing; the second could receive partial content or corrupt the cache data by writing simultaneously. I recently ran into a long discussion about this situation on a mailing list. :)
    Thanks for the article.
    Best regards, Laszlo.

  6. Hutch Says:

    The cache system can be modified to work with personal/secure pages as such:

    For regular non user/secure pages:
    Change the cached pages to .php not .html.
    Change the data for the cache file to $data = ‘’;

    When getting the cached pages use mktime (as previously suggested) and simply include the file ie:
    // Cache too old
    if (mktime()-(cache_time*60*60) > filemtime($file)){
    return false;
    }
    include($file);
    die();

    NOTE: I haven’t done this as my site is trivial but I believe it should work
    For personalized pages I suggest a shorter cache time so define a second variable secure_cache_time. At the top of any pages that are secure create a flag to identify as such define(’secure’,'1′) to the “cache engine”.
    For the filename use a combination of the url and a unique user identifier (username, userid, ip) or some combination.
    For the data $data = ‘’;
    IMPORTANT: where correct_user is the logic you would regularly check for user credentials. Finally for added security setup an htaccess file on the directory or put the user cached pages outside the root directory all together.

    Hacking in a method to define a per page cache_time would be a good idea since we generally know how often certain pages update and I also added a refresh_cache function. At the moment it can’t determine which files it needs updating so it just removes all of them (more of a refresh_all function).

  7. Dennis Pallett Says:

    Guess it ain’t working. Let me know what you want to post at dennis [AT] phpit [DOT] net, and I’ll add it to the article it self.

  8. Johanna Nordin Says:

    Santana Juelz What The Game’s Been Missing

    PHPit - Totally PHP &r…

  9. keitai Says:

    hi there,

    Trying to follow and implement your caching functions, but

    One question how about $content how is this one set??

Leave a Reply

About the author
Dennis Pallett is the main contributor to PHPit. He owns several websites, including ASPit and Chill2Music. He is currently still studying.
Article Index
  1. Output Callback & Time
  2. Bringing it all together
Bookmark Article
Download Article
PDF
Download this article as a PDF file