I read many interesting articles on caching that all do the job. The problem I have with most of the techniques is that they do not show you how to implement caching for High Traffic sites. Let look at what caching is first
What is Caching?
Most web sites generate dynamically created content. To generate this content the web service usually has to query some data source(Database, XML, etc.) and output HTML to your web browser. Problem is that when you have thousands of users hitting your site, these dynamic request can cause serious overhead on your web server as it has to process many request which will cause you site to run slowly. See image:

Enter Caching
How can this problem be avoided? Consider this: Most web pages are updated periodically and perhaps need to be refreshed every half an hour or so. As in the dynamic content of the site really does not need to execute per every web request, but every X amounts of minutes. Lets say you run a News site and you receive a average new article every 10 minutes. So it would make sense to only allow the site to update every 10 minutes. This will really increase your performance and keep the site fresh.
How Caching Works
The concept of caching is simple. A user request your web page. The php code checks to see if the page needs to be updated. If yes then run the dynamic queries and refresh the content. If no then return the cached page. (see Image below):

Implementing Simple caching
Caching is fairly simple to implement lets look at a overview of what we want our script to do

Sounds easy enough lets look at some code:
$cfile = "cache/cachedpage.HTML";
if (file_exists($cfile))
{
// the page has been cached from an earlier request
//include and output the cached page
include($cfile);
// exit the script, so that the rest isn't executed
exit;
}
?>
<HTML>
.
. Your HTML here
.
</HTML>
<?php
// open the cache file for writing
$fp = fopen($cfile, 'w');
// save the contents of output buffer to the file
fwrite($fp, ob_get_contents());
// close the file fclose($fp);
// Send the output to the browser ob_end_flush();
?>
A Fundamental Flaw
While the above code will work for most of the sites out there, what will happen if we implement this on a high traffic site? Let consider the following scenario: You have a high traffic site that averages two users a second. Your dynamic content take around 3 seconds to regenerate and your cache page just expired.

We can see that image that you allows 5 more request then needed. On a high traffic site you would site extremely slow downs during this moment. For even higher traffic sites(Digg.com, Fark.com, etc) where they average 10 users per second this could be exponentially a even bigger problem.
Better Php caching
In order to over come this issue, we are going to lock the file when the first request for a new cache file comes in. Then, if another users makes the request before the first cache file is written, it will attempt to lock a file that is already locked. If this then we simply return the cache until the first user has unlocked the file
<?php
$cfile = "cache/cachedpage.HTML";
$cfile ="cache/".$reqfilename.".html";
$cachetime = 30*60; // 30 minutes
// Serve from the cache if it is younger than $cachetime
if (file_exists($cfile ) && (time() - $cachetime< filemtime($cfile )))
{
//if cache is not expired return cache files
include($cfile );
exit;
}
else
{
//open file and attempt to lock
$fp = fopen($cfile , 'w');
if( flock($fp, LOCK_EX))
{
ob_start(); // start the output buffer
}
else
{
//if cant lock then return the previously generated cache
include($cachefile);
exit;
}
}
?>
<HTML>
.
. Your HTML here
.
</HTML>
<?php
// open the cache file for writing
flock($fp, LOCK_UN); // unlock the file
// save the contents of output buffer to the file
fwrite($fp, ob_get_contents());
// close the file
fclose($fp);
// Send the output to the browser
ob_end_flush();
?>
Going over the code we see that we are now locking the file before we write to it. Any other users whom preform the cache request will attempt to lock a lock file and it will fail and they will return the old cache file. This ensures that only one cache file request is preformed in spite of how many users.
Special thanks to Alex Gonzales(www.branchint.com) for some help on this. Please leave a comments/questions or improvements.