简体   繁体   中英

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

  • Put it in APC with apc_store($page, 60*60*) - I feel this isn't what APC is for and will probably be doing something bad to the other parts of my site
  • Save the output to a filesystem somewhere - Then apache needs write access somewhere which might be a pain
  • Somehow setup apache to do the caching for me - Is this possible?
  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.

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.

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.

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

Another good option is to setup a Squid Cache Server .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM