Code: Select all
<?php
/**
* A very basic web page caching system
* Stores pages in a cache, checks expiry times
* and dumps the cache contents back.
* @author Chris Corbyn
* @license Lesser GNU Public License
*/
class PageCache
{
/**
* The directory where the cache resides
* @var string path
*/
protected $cacheDirectory = '/tmp';
/**
* The name of the current page as specified by the developer
* @var string page name
*/
protected $page;
/**
* Open file handle
* @var resource file
*/
protected $handle;
/**
* The cache timeout in seconds
* @var int timeout
*/
protected $timeout;
/**
* Constructor
* @param string page name
*/
public function __construct($pagename)
{
$this->page = $pagename;
}
/**
* Specify a maximum age in seconds for cached pages
* @param int seconds
*/
public function setTimeout($seconds)
{
$this->timeout = (int) $seconds;
}
/**
* Set the directory to use to cache pages
* @var string path
*/
public function setCacheDirectory($path)
{
$this->cacheDirectory = $path;
}
/**
* Check if the cache is writable
* @return boolean
*/
public function isWritable()
{
return is_writable($this->cacheDirectory);
}
/**
* Start output buffering to catch the page contents
* Open the file ready for writing
*/
public function startCaching()
{
if ($this->isWritable())
{
ob_start();
$this->handle = fopen($this->getCachedFilePath(), 'w+');
}
}
/**
* Commit the contents of the buffer to the cache
*/
public function write()
{
if ($this->handle)
{
$buffer = ob_get_clean();
fwrite($this->handle, $buffer);
}
}
/**
* Check if the page we have open is already cached
* @return boolean
*/
public function isCached()
{
return file_exists($this->getCachedFilePath());
}
/**
* Get the contents of the already cached page
* @return string page data
*/
public function getContents()
{
if ($this->isCached())
{
return file_get_contents($this->getCachedFilePath());
}
}
/**
* Print the contents of the cached page to the screen
*/
public function dump()
{
echo $this->getContents();
}
/**
* Get the path the file which we're working with
* @access private
* @return string path
*/
private function getCachedFilePath()
{
return $this->cacheDirectory.'/'.$this->page;
}
/**
* Get the age in seconds of the already cached file
* @return int age
*/
public function getAge()
{
if ($this->isCached())
{
return time() - filemtime($this->getCachedFilePath());
}
else return 0;
}
/**
* Check if the currently cached file is out of date
* @return boolean
*/
public function isExpired()
{
return ($this->timeout <= $this->getAge());
}
/**
* Remove old cache data for this page
*/
public function cleanUp()
{
if ($this->isCached() && $this->isWritable())
{
unlink($this->getCachedFilePath());
}
}
}
?>Code: Select all
Mock::GeneratePartial('PageCache', 'PartialPageCache', array('getAge'));
class TestOfPageCache extends UnitTestCase
{
public function testCacheIsWritable()
{
$cache = new PageCache('mypage');
$cache->setCacheDirectory('./cache');
$this->assertTrue($cache->isWritable());
@fopen('./cache/test.txt', 'w+');
$this->assertTrue(file_exists('./cache/test.txt'));
@unlink('./cache/test.txt');
$this->assertFalse(file_exists('./cache/test.txt'));
}
public function testPageCacheFileIsCreated()
{
$cache = new PageCache('mypage');
$cache->setCacheDirectory('./cache');
$this->assertTrue($cache->isWritable());
$cache->startCaching();
$this->assertTrue(file_exists('./cache/mypage'));
@unlink('./cache/mypage');
$this->assertFalse(file_exists('./cache/mypage'));
}
public function testCacheContent()
{
$cache = new PageCache('mypage');
$cache->setCacheDirectory('./cache');
$cache->startCaching();
$this->assertTrue(file_exists('./cache/mypage'));
$test_output = "Some <strong>test</strong> output";
echo $test_output;
$cache->write();
$this->assertEqual($test_output, $cache->getContents());
@unlink('./cache/mypage');
$this->assertFalse(file_exists('./cache/mypage'));
}
public function testCacheTimeout()
{
$cache = new PartialPageCache($this);
$cache->__construct('mypage');
$cache->setCacheDirectory('./cache');
$cache->setTimeout(60 * 60); //1 hour in seconds
$cache->startCaching();
$this->assertTrue(file_exists('./cache/mypage'));
$test_output = "Dummy";
echo $test_output;
$cache->write();
$cache->setReturnValue('getAge', 60 * 60 + 10); //10 seconds expired
$this->assertTrue($cache->isExpired());
@unlink('./cache/mypage');
$this->assertFalse(file_exists('./cache/mypage'));
unset($cache);
$cache = new PartialPageCache($this);
$cache->__construct('mypage');
$cache->setCacheDirectory('./cache');
$cache->setTimeout(60 * 60); //1 hour in seconds
$cache->startCaching();
$this->assertTrue(file_exists('./cache/mypage'));
$test_output = "Dummy";
echo $test_output;
$cache->write();
$cache->setReturnValue('getAge', 60 * 60 - 10); //10 seconds remaining
$this->assertFalse($cache->isExpired());
@unlink('./cache/mypage');
$this->assertFalse(file_exists('./cache/mypage'));
$cache = new PageCache('mypage');
$cache->setCacheDirectory('./cache');
$cache->setTimeout(60 * 60); //1 hour in seconds
$cache->startCaching();
$this->assertTrue(file_exists('./cache/mypage'));
$test_output = "Dummy";
echo $test_output;
$cache->write();
$this->assertFalse($cache->isExpired());
@unlink('./cache/mypage');
$this->assertFalse(file_exists('./cache/mypage'));
}
public function testDumpOfCacheData()
{
$cache = new PageCache('mypage');
$cache->setCacheDirectory('./cache');
$cache->setTimeout(60 * 60); //1 hour in seconds
$cache->startCaching();
$this->assertTrue(file_exists('./cache/mypage'));
$test_output = "Dummy";
echo $test_output;
$cache->write();
$this->assertFalse($cache->isExpired());
ob_start();
if (!$cache->isExpired())
{
$cache->dump();
}
$cache_data = ob_get_clean();
$this->assertEqual($cache_data, $test_output);
@unlink('./cache/mypage');
$this->assertFalse(file_exists('./cache/mypage'));
}
public function testOfCleaning()
{
$cache = new PartialPageCache($this);
$cache->__construct('mypage');
$cache->setCacheDirectory('./cache');
$cache->setTimeout(60 * 60); //1 hour in seconds
$cache->startCaching();
$this->assertTrue(file_exists('./cache/mypage'));
$test_output = "Dummy";
echo $test_output;
$cache->write();
$cache->setReturnValue('getAge', 60 * 60 + 10); //10 seconds expired
$this->assertTrue($cache->isExpired());
if ($cache->isExpired())
{
$cache->cleanUp();
}
$this->assertFalse(file_exists('./cache/mypage'));
}
}Code: Select all
$cache = new PageCache($this->page);
$cache->setTimeout($this->cacheTimeout);
if ($cache->isCached() && !$cache->isExpired())
{
$cache->dump();
}
else
{
$cache->startCaching();
$this->pseudoSendYourPageOutput();
$cache->write();
}(Ok, I really need some sleep