egroupware_official/phpgwapi/inc/class.egw_cache_files.inc.php
Ralf Becker 91a24e0399 tests for egw_cache_provider and not using APC for cli, if apc.enable_cli is not set
Also did some benchmarking on my Macbook (with a SSD and memcached running on localhost):
Checking egw_cache_memcache:
0 checks failed, 100 iterations took 0.480 sec

Checking egw_cache_apc:
0 checks failed, 100 iterations took 0.025 sec

Checking egw_cache_files:
0 checks failed, 100 iterations took 0.826 sec
--> APC is by a factor of 20 faster then memcached, which is double as fast compared to files on a SSD
2012-04-13 10:25:53 +00:00

135 lines
3.5 KiB
PHP

<?php
/**
* EGroupware API: Caching provider storing data to files
*
* @link http://www.egroupware.org
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage cache
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright (c) 2009-12 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @version $Id$
*/
/**
* Caching provider storing data in files
*
* The provider creates subdirs under a given path
* for each values in $key
*/
class egw_cache_files extends egw_cache_provider_check implements egw_cache_provider
{
/**
* Extension of file used to store expiration > 0
*/
const EXPIRATION_EXTENSION = '.expiration';
/**
* Path of base-directory for the cache, set via parameter to the constructor or defaults to temp_dir
*
* @var string
*/
protected $base_path;
/**
* Constructor, eg. opens the connection to the backend
*
* @throws Exception if connection to backend could not be established
* @param array $params eg. array(host,port) or array(directory) depending on the provider
*/
function __construct(array $params)
{
if ($params)
{
$this->base_path = $params[0];
}
else
{
$this->base_path = egw_cache::get_system_config('temp_dir').'/egw_cache';
}
if (!isset($this->base_path) || !file_exists($this->base_path) && !mkdir($this->base_path,0700,true))
{
throw new Exception (__METHOD__."() can't create basepath $this->base_path!");
}
}
/**
* Stores some data in the cache
*
* @param array $keys eg. array($level,$app,$location)
* @param mixed $data
* @param int $expiration=0
* @return boolean true on success, false on error
*/
function set(array $keys,$data,$expiration=0)
{
if ($ret = @file_put_contents($fname=$this->filename($keys,true),serialize($data),LOCK_EX) > 0)
{
if ((int)$expiration > 0) file_put_contents($fname.self::EXPIRATION_EXTENSION,(string)$expiration);
}
return $ret;
}
/**
* Get some data from the cache
*
* @param array $keys eg. array($level,$app,$location)
* @return mixed data stored or NULL if not found in cache
*/
function get(array $keys)
{
if (!file_exists($fname = $this->filename($keys)))
{
return null;
}
if (file_exists($fname_expiration=$fname.self::EXPIRATION_EXTENSION) &&
($expiration = (int)file_get_contents($fname_expiration)) &&
filemtime($fname) < time()-$expiration)
{
unlink($fname);
unlink($fname_expiration);
return null;
}
return unserialize(file_get_contents($fname));
}
/**
* Delete some data from the cache
*
* @param array $keys eg. array($level,$app,$location)
* @return boolean true on success, false on error (eg. $key not set)
*/
function delete(array $keys)
{
if (!file_exists($fname = $this->filename($keys)))
{
//error_log(__METHOD__.'('.array2string($keys).") file_exists('$fname') == FALSE!");
return false;
}
if (file_exists($fname_expiration=$fname.self::EXPIRATION_EXTENSION))
{
unlink($fname_expiration);
}
//error_log(__METHOD__.'('.array2string($keys).") calling unlink('$fname')");
return unlink($fname);
}
/**
* Create a path from $keys and $basepath
*
* @param array $keys
* @param boolean $mkdir=false should we create the directory
* @return string
*/
function filename(array $keys,$mkdir=false)
{
$fname = $this->base_path.'/'.str_replace(array(':','*'),'-',implode('/',$keys));
if ($mkdir && !file_exists($dirname=dirname($fname)))
{
@mkdir($dirname,0700,true);
}
return $fname;
}
}