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