Paul Tarjan
Paul Tarjan

Reputation: 50652

What is the best way to do server-side output caching in PHP?

I have a pretty complicated index.php now, and I would like to only run it once every hour. What is the best way to achieve this? Some ideas I've had

Upvotes: 7

Views: 2242

Answers (5)

Paul Tarjan
Paul Tarjan

Reputation: 50652

I went with a slight variation on Rowlf's and jamietelin's answer.

Create 3 files:

index.html

<meta http-equiv="refresh" content="0;url=/index_update.php" />

index.php

<?php // do all your normal stuff ?>

index_update.php

<?php

$file = "index.html";
$time = 60 * 10 - (time() - filemtime($file));

# this is on the first install 
if (filemtime($file) != filectime($file))
    $time = 0;

if ($time > 0) {
    die("Data was already updated in the 10 minutes. Please wait another " . ($time) . " seconds.");
}

ob_start();
require "index.php";
$data = ob_get_contents();

$fp = fopen($file, "w");
fwrite($fp, $data);
fclose($fp);

header("Location: /");

And then a cronjob:

*/15 * * * * curl http://example.com/index_update.php

So, if someone stumbles on the page after a production push, they will just transparently create a new index.html for you, otherwise, your cronjob will make it every 15 minutes.

Just make sure index.html is writable by your apache server. If that sounds scary, then just make your cronjob run php index_update.php as another user with write priviledges to index.html. You won't have access to all the apache environment though.

Hope this helps, comments are welcome.

Upvotes: 1

Rowlf
Rowlf

Reputation: 1762

  1. When a visitor hits your page, generate the content, send it to the user and save a static file somewhere on disk.
  2. When the next visitor comes, first look for the saved file, and if it exists, serve that rather than execute all the code in your index.php file. A basic example would be

    if (file_exists($cacheFileName))
    {
        require $cacheFileName;
        exit;
    }
    
    // here goes the rest of your index.php code
    //..
    
    // assuming your output is buffered and is contained in $output:
    echo $output;
    
    $cacheFileName = '/path/to/your/file.inc';
    file_put_contents($cacheFileName, $output);
    
  3. Set up a cron job that will delete your saved cache file from disk every hour or as often as you need to. Alternatively, in your index.php, on every page hit check how long ago the cached file was created and generate a new cache file if it's been around longer than you'd want it to. A cron job is easier to set up though.

To answer the deep philosophical question though, saving generated output to disk in separate files is probably the best way if you don't want to rely on third party caching solutions. APC is good for caching the code that will regenerate pages when needed, and memcached is definitely overkill if we're talking about a small(ish) application.

Upvotes: 3

Benbob
Benbob

Reputation: 14264

Save the page into a static file and use .htaccess rules to serve up the static page.

I'm not sure on the exact details, but I think codeignitor and boost for drupal do this.

Upvotes: 0

lejahmie
lejahmie

Reputation: 18253

Delivering static pages is always the most optimized way. So use for example Cron, or any other schedule service of your choice, to generate a static version of your index once every hour and have it write it to a file, example index.html. You could even have it generate it as .php if you still need some dynamic parts on the index.

I would say this is the absolute best way. Of course it's some minor pain to handle the chmod setting for the file, but it's not that big of a problem.

Upvotes: 1

cjimti
cjimti

Reputation: 156

You should really take a look at Memcached (excellent php support.)

Another good option is to setup a Squid Cache Server.

Upvotes: 0

Related Questions