First version of cacheFile with associated tests
git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@1550 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
82
Tests/cacheFileTest.php
Normal file
82
Tests/cacheFileTest.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/** DomFramework - Tests
|
||||
@package domframework
|
||||
@author Dominique Fournier <dominique@fournier38.fr> */
|
||||
|
||||
/** Test the cache.php file */
|
||||
class test_cacheFile extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function __construct ()
|
||||
{
|
||||
// Removing the cache file if it previously exists
|
||||
$c = new cacheFile ();
|
||||
$res = $c->delete ("id");
|
||||
}
|
||||
|
||||
// Unknown cache file : return FALSE
|
||||
public function testRead1 ()
|
||||
{
|
||||
$c = new cacheFile ();
|
||||
$res = $c->read ("id");
|
||||
$this->assertFalse ($res);
|
||||
}
|
||||
|
||||
// Write in cache file
|
||||
public function testWrite1 ()
|
||||
{
|
||||
$c = new cacheFile ();
|
||||
$res = $c->write ("id","DATA_TO_STORE", 3);
|
||||
$this->assertTrue ($res);
|
||||
}
|
||||
|
||||
// Previous cache file : return DATA_TO_STORE
|
||||
public function testRead2 ()
|
||||
{
|
||||
$c = new cacheFile ();
|
||||
$res = $c->read ("id");
|
||||
$this->assertEquals ("DATA_TO_STORE", $res);
|
||||
}
|
||||
|
||||
// Sleep 3s to expire the cache
|
||||
public function testWait1 ()
|
||||
{
|
||||
sleep (4);
|
||||
}
|
||||
|
||||
// Previous cache file but expired : return false
|
||||
public function testRead3 ()
|
||||
{
|
||||
$c = new cacheFile ();
|
||||
$res = $c->read ("id");
|
||||
$this->assertFalse ($res);
|
||||
}
|
||||
|
||||
// Write in cache file
|
||||
public function testWrite2 ()
|
||||
{
|
||||
$c = new cacheFile ();
|
||||
$res = $c->write ("id","DATA_TO_STORE", 30);
|
||||
$this->assertTrue ($res);
|
||||
}
|
||||
|
||||
// Create stale lock
|
||||
public function testLock1 ()
|
||||
{
|
||||
touch ("cache/".sha1 ("id").".lock");
|
||||
}
|
||||
|
||||
// Previous cache in time file but lock : return content after lock timeout
|
||||
public function testRead4 ()
|
||||
{
|
||||
$c = new cacheFile ();
|
||||
$res = $c->read ("id");
|
||||
$this->assertEquals ("DATA_TO_STORE", $res);
|
||||
}
|
||||
|
||||
public function testDel1 ()
|
||||
{
|
||||
$c = new cacheFile ();
|
||||
$res = $c->delete ("id");
|
||||
}
|
||||
}
|
||||
|
||||
143
cacheFile.php
Normal file
143
cacheFile.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
class cacheFile
|
||||
{
|
||||
/** Where to store the cached informations */
|
||||
public $directory = "./cache";
|
||||
/** If TRUE : no information is cached */
|
||||
public $nocache = false;
|
||||
|
||||
/** This function check if the cachedir exists and create it if it is not the
|
||||
case.
|
||||
Check if the cache dir is writable and readable */
|
||||
public function cachedir ()
|
||||
{
|
||||
if (! isset ($this->directory) || $this->directory === "")
|
||||
throw new Exception (_("No cache directory defined"), 500);
|
||||
if (! file_exists ($this->directory))
|
||||
{
|
||||
// Need to create the cache dir
|
||||
$parent = realpath (dirname ($this->directory));
|
||||
if (! is_writeable (dirname ($this->directory)))
|
||||
throw new Exception (sprintf (_(
|
||||
"Directory %s is not writable : can not create cache directory"),
|
||||
$parent), 500);
|
||||
if (!mkdir ($this->directory))
|
||||
throw new Exception (sprintf (_("Can not create cache directory %s"),
|
||||
$this->directory), 500);
|
||||
file_put_contents ($this->directory."/.htaccess", "deny from all\n");
|
||||
}
|
||||
if (! is_writable ($this->directory))
|
||||
throw new Exception (sprintf (_("Cache directory %s is not writable"),
|
||||
$this->directory), 500);
|
||||
if (! is_readable ($this->directory))
|
||||
throw new Exception (sprintf (_("Cache directory %s is not readable"),
|
||||
$this->directory), 500);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** This function write data in cache
|
||||
The cache system can not save FALSE value
|
||||
@param string $id Cache identifier (add the authentication, the METHOD...)
|
||||
@param string $data The data to save
|
||||
@param integer|null $ttl The cache Time to Leave in seconds (3600s by
|
||||
default)*/
|
||||
public function write ($id, $data, $ttl = 3600)
|
||||
{
|
||||
if ($this->nocache !== false)
|
||||
return false;
|
||||
if ($data === false)
|
||||
throw new Exception (_("Can not store FALSE in cache"), 500);
|
||||
try
|
||||
{
|
||||
$this->cachedir ();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception ($e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
||||
$fileCache = $this->directory."/".sha1 ($id);
|
||||
touch ($fileCache.".lock");
|
||||
$datas = array ("ttl"=>$ttl,
|
||||
"createTime"=>time(),
|
||||
"data"=>$data);
|
||||
file_put_contents ($fileCache, serialize ($datas));
|
||||
unlink ($fileCache.".lock");
|
||||
return true;
|
||||
}
|
||||
|
||||
/** This function read data from cache. Return FALSE in case of empty or too
|
||||
older cache
|
||||
@param string $id Cache identifier (add the authentication, the METHOD) */
|
||||
public function read ($id)
|
||||
{
|
||||
if ($this->nocache !== false)
|
||||
return false;
|
||||
try
|
||||
{
|
||||
$this->cachedir ();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception ($e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
||||
$fileCache = $this->directory."/".sha1 ($id);
|
||||
if (!file_exists ($fileCache))
|
||||
return false;
|
||||
if (!is_readable ($fileCache))
|
||||
throw new Exception (sprintf (_("File cache %s is not readable"),
|
||||
$fileCache), 500);
|
||||
if (!is_writable ($fileCache))
|
||||
throw new Exception (sprintf (_("File cache %s is not writable"),
|
||||
$fileCache), 500);
|
||||
// Lock : waiting the reconstruction of the cache by another process
|
||||
// Waiting 10s maximum to re-create the cache file
|
||||
$startTime = time ();
|
||||
while (file_exists ($fileCache.".lock") && time () < $startTime + 10)
|
||||
{
|
||||
usleep (100000);
|
||||
}
|
||||
|
||||
// The lock is pending 10s (stale) : removing it to read the datas quicker
|
||||
// next time
|
||||
if (file_exists ($fileCache.".lock"))
|
||||
unlink ($fileCache.".lock");
|
||||
|
||||
$datas = file_get_contents ($fileCache);
|
||||
if ($datas === false)
|
||||
{
|
||||
unlink ($fileCache);
|
||||
return false;
|
||||
}
|
||||
|
||||
$datas = unserialize ($datas);
|
||||
if (! isset ($datas["ttl"]) || ! isset ($datas["data"]) ||
|
||||
! isset ($datas["createTime"]))
|
||||
{
|
||||
unlink ($fileCache);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (($datas["createTime"] + $datas["ttl"]) >= time ())
|
||||
{
|
||||
if (file_exists ($fileCache.".lock"))
|
||||
unlink ($fileCache.".lock");
|
||||
return $datas["data"];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** This function delete an id in cache
|
||||
@param string $id Cache identifier (add the authentication, the METHOD...)
|
||||
*/
|
||||
public function delete ($id)
|
||||
{
|
||||
$fileCache = $this->directory."/".sha1 ($id);
|
||||
if (!file_exists ($fileCache))
|
||||
return false;
|
||||
unlink ($fileCache);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user