Added new (clean) yii boilerplate
This commit is contained in:
108
framework/caching/CApcCache.php
Normal file
108
framework/caching/CApcCache.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* CApcCache class file
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CApcCache provides APC caching in terms of an application component.
|
||||
*
|
||||
* The caching is based on {@link http://www.php.net/apc APC}.
|
||||
* To use this application component, the APC PHP extension must be loaded.
|
||||
*
|
||||
* See {@link CCache} manual for common cache operations that are supported by CApcCache.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching
|
||||
* @since 1.0
|
||||
*/
|
||||
class CApcCache extends CCache
|
||||
{
|
||||
/**
|
||||
* Initializes this application component.
|
||||
* This method is required by the {@link IApplicationComponent} interface.
|
||||
* It checks the availability of APC.
|
||||
* @throws CException if APC cache extension is not loaded or is disabled.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if(!extension_loaded('apc'))
|
||||
throw new CException(Yii::t('yii','CApcCache requires PHP apc extension to be loaded.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
return apc_fetch($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple values from cache with the specified keys.
|
||||
* @param array $keys a list of keys identifying the cached values
|
||||
* @return array a list of cached values indexed by the keys
|
||||
*/
|
||||
protected function getValues($keys)
|
||||
{
|
||||
return apc_fetch($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function setValue($key,$value,$expire)
|
||||
{
|
||||
return apc_store($key,$value,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function addValue($key,$value,$expire)
|
||||
{
|
||||
return apc_add($key,$value,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
protected function deleteValue($key)
|
||||
{
|
||||
return apc_delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
* @since 1.1.5
|
||||
*/
|
||||
protected function flushValues()
|
||||
{
|
||||
return apc_clear_cache('user');
|
||||
}
|
||||
}
|
||||
376
framework/caching/CCache.php
Normal file
376
framework/caching/CCache.php
Normal file
@@ -0,0 +1,376 @@
|
||||
<?php
|
||||
/**
|
||||
* CCache class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CCache is the base class for cache classes with different cache storage implementation.
|
||||
*
|
||||
* A data item can be stored in cache by calling {@link set} and be retrieved back
|
||||
* later by {@link get}. In both operations, a key identifying the data item is required.
|
||||
* An expiration time and/or a dependency can also be specified when calling {@link set}.
|
||||
* If the data item expires or the dependency changes, calling {@link get} will not
|
||||
* return back the data item.
|
||||
*
|
||||
* Note, by definition, cache does not ensure the existence of a value
|
||||
* even if it does not expire. Cache is not meant to be a persistent storage.
|
||||
*
|
||||
* CCache implements the interface {@link ICache} with the following methods:
|
||||
* <ul>
|
||||
* <li>{@link get} : retrieve the value with a key (if any) from cache</li>
|
||||
* <li>{@link set} : store the value with a key into cache</li>
|
||||
* <li>{@link add} : store the value only if cache does not have this key</li>
|
||||
* <li>{@link delete} : delete the value with the specified key from cache</li>
|
||||
* <li>{@link flush} : delete all values from cache</li>
|
||||
* </ul>
|
||||
*
|
||||
* Child classes must implement the following methods:
|
||||
* <ul>
|
||||
* <li>{@link getValue}</li>
|
||||
* <li>{@link setValue}</li>
|
||||
* <li>{@link addValue}</li>
|
||||
* <li>{@link deleteValue}</li>
|
||||
* <li>{@link getValues} (optional)</li>
|
||||
* <li>{@link flushValues} (optional)</li>
|
||||
* <li>{@link serializer} (optional)</li>
|
||||
* </ul>
|
||||
*
|
||||
* CCache also implements ArrayAccess so that it can be used like an array.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching
|
||||
* @since 1.0
|
||||
*/
|
||||
abstract class CCache extends CApplicationComponent implements ICache, ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @var string a string prefixed to every cache key so that it is unique. Defaults to null which means
|
||||
* to use the {@link CApplication::getId() application ID}. If different applications need to access the same
|
||||
* pool of cached data, the same prefix should be set for each of the applications explicitly.
|
||||
*/
|
||||
public $keyPrefix;
|
||||
/**
|
||||
* @var boolean whether to md5-hash the cache key for normalization purposes. Defaults to true. Setting this property to false makes sure the cache
|
||||
* key will not be tampered when calling the relevant methods {@link get()}, {@link set()}, {@link add()} and {@link delete()}. This is useful if a Yii
|
||||
* application as well as an external application need to access the same cache pool (also see description of {@link keyPrefix} regarding this use case).
|
||||
* However, without normalization you should make sure the affected cache backend does support the structure (charset, length, etc.) of all the provided
|
||||
* cache keys, otherwise there might be unexpected behavior.
|
||||
* @since 1.1.11
|
||||
**/
|
||||
public $hashKey=true;
|
||||
/**
|
||||
* @var array|boolean the functions used to serialize and unserialize cached data. Defaults to null, meaning
|
||||
* using the default PHP `serialize()` and `unserialize()` functions. If you want to use some more efficient
|
||||
* serializer (e.g. {@link http://pecl.php.net/package/igbinary igbinary}), you may configure this property with
|
||||
* a two-element array. The first element specifies the serialization function, and the second the deserialization
|
||||
* function. If this property is set false, data will be directly sent to and retrieved from the underlying
|
||||
* cache component without any serialization or deserialization. You should not turn off serialization if
|
||||
* you are using {@link CCacheDependency cache dependency}, because it relies on data serialization.
|
||||
*/
|
||||
public $serializer;
|
||||
|
||||
/**
|
||||
* Initializes the application component.
|
||||
* This method overrides the parent implementation by setting default cache key prefix.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if($this->keyPrefix===null)
|
||||
$this->keyPrefix=Yii::app()->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key a key identifying a value to be cached
|
||||
* @return string a key generated from the provided key which ensures the uniqueness across applications
|
||||
*/
|
||||
protected function generateUniqueKey($key)
|
||||
{
|
||||
return $this->hashKey ? md5($this->keyPrefix.$key) : $this->keyPrefix.$key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* @param string $id a key identifying the cached value
|
||||
* @return mixed the value stored in cache, false if the value is not in the cache, expired or the dependency has changed.
|
||||
*/
|
||||
public function get($id)
|
||||
{
|
||||
$value = $this->getValue($this->generateUniqueKey($id));
|
||||
if($value===false || $this->serializer===false)
|
||||
return $value;
|
||||
if($this->serializer===null)
|
||||
$value=unserialize($value);
|
||||
else
|
||||
$value=call_user_func($this->serializer[1], $value);
|
||||
if(is_array($value) && (!$value[1] instanceof ICacheDependency || !$value[1]->getHasChanged()))
|
||||
{
|
||||
Yii::trace('Serving "'.$id.'" from cache','system.caching.'.get_class($this));
|
||||
return $value[0];
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple values from cache with the specified keys.
|
||||
* Some caches (such as memcache, apc) allow retrieving multiple cached values at one time,
|
||||
* which may improve the performance since it reduces the communication cost.
|
||||
* In case a cache does not support this feature natively, it will be simulated by this method.
|
||||
* @param array $ids list of keys identifying the cached values
|
||||
* @return array list of cached values corresponding to the specified keys. The array
|
||||
* is returned in terms of (key,value) pairs.
|
||||
* If a value is not cached or expired, the corresponding array value will be false.
|
||||
*/
|
||||
public function mget($ids)
|
||||
{
|
||||
$uids = array();
|
||||
foreach ($ids as $id)
|
||||
$uids[$id] = $this->generateUniqueKey($id);
|
||||
|
||||
$values = $this->getValues($uids);
|
||||
$results = array();
|
||||
if($this->serializer === false)
|
||||
{
|
||||
foreach ($uids as $id => $uid)
|
||||
$results[$id] = isset($values[$uid]) ? $values[$uid] : false;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($uids as $id => $uid)
|
||||
{
|
||||
$results[$id] = false;
|
||||
if(isset($values[$uid]))
|
||||
{
|
||||
$value = $this->serializer === null ? unserialize($values[$uid]) : call_user_func($this->serializer[1], $values[$uid]);
|
||||
if(is_array($value) && (!$value[1] instanceof ICacheDependency || !$value[1]->getHasChanged()))
|
||||
{
|
||||
Yii::trace('Serving "'.$id.'" from cache','system.caching.'.get_class($this));
|
||||
$results[$id] = $value[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache.
|
||||
* If the cache already contains such a key, the existing value and
|
||||
* expiration time will be replaced with the new ones.
|
||||
*
|
||||
* @param string $id the key identifying the value to be cached
|
||||
* @param mixed $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
public function set($id,$value,$expire=0,$dependency=null)
|
||||
{
|
||||
Yii::trace('Saving "'.$id.'" to cache','system.caching.'.get_class($this));
|
||||
|
||||
if ($dependency !== null && $this->serializer !== false)
|
||||
$dependency->evaluateDependency();
|
||||
|
||||
if ($this->serializer === null)
|
||||
$value = serialize(array($value,$dependency));
|
||||
elseif ($this->serializer !== false)
|
||||
$value = call_user_func($this->serializer[0], array($value,$dependency));
|
||||
|
||||
return $this->setValue($this->generateUniqueKey($id), $value, $expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* Nothing will be done if the cache already contains the key.
|
||||
* @param string $id the key identifying the value to be cached
|
||||
* @param mixed $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
public function add($id,$value,$expire=0,$dependency=null)
|
||||
{
|
||||
Yii::trace('Adding "'.$id.'" to cache','system.caching.'.get_class($this));
|
||||
|
||||
if ($dependency !== null && $this->serializer !== false)
|
||||
$dependency->evaluateDependency();
|
||||
|
||||
if ($this->serializer === null)
|
||||
$value = serialize(array($value,$dependency));
|
||||
elseif ($this->serializer !== false)
|
||||
$value = call_user_func($this->serializer[0], array($value,$dependency));
|
||||
|
||||
return $this->addValue($this->generateUniqueKey($id), $value, $expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* @param string $id the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
Yii::trace('Deleting "'.$id.'" from cache','system.caching.'.get_class($this));
|
||||
return $this->deleteValue($this->generateUniqueKey($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* Be careful of performing this operation if the cache is shared by multiple applications.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
Yii::trace('Flushing cache','system.caching.'.get_class($this));
|
||||
return $this->flushValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* This method should be implemented by child classes to retrieve the data
|
||||
* from specific cache storage. The uniqueness and dependency are handled
|
||||
* in {@link get()} already. So only the implementation of data retrieval
|
||||
* is needed.
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
* @throws CException if this method is not overridden by child classes
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
throw new CException(Yii::t('yii','{className} does not support get() functionality.',
|
||||
array('{className}'=>get_class($this))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple values from cache with the specified keys.
|
||||
* The default implementation simply calls {@link getValue} multiple
|
||||
* times to retrieve the cached values one by one.
|
||||
* If the underlying cache storage supports multiget, this method should
|
||||
* be overridden to exploit that feature.
|
||||
* @param array $keys a list of keys identifying the cached values
|
||||
* @return array a list of cached values indexed by the keys
|
||||
*/
|
||||
protected function getValues($keys)
|
||||
{
|
||||
$results=array();
|
||||
foreach($keys as $key)
|
||||
$results[$key]=$this->getValue($key);
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
* This method should be implemented by child classes to store the data
|
||||
* in specific cache storage. The uniqueness and dependency are handled
|
||||
* in {@link set()} already. So only the implementation of data storage
|
||||
* is needed.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
* @throws CException if this method is not overridden by child classes
|
||||
*/
|
||||
protected function setValue($key,$value,$expire)
|
||||
{
|
||||
throw new CException(Yii::t('yii','{className} does not support set() functionality.',
|
||||
array('{className}'=>get_class($this))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* This method should be implemented by child classes to store the data
|
||||
* in specific cache storage. The uniqueness and dependency are handled
|
||||
* in {@link add()} already. So only the implementation of data storage
|
||||
* is needed.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
* @throws CException if this method is not overridden by child classes
|
||||
*/
|
||||
protected function addValue($key,$value,$expire)
|
||||
{
|
||||
throw new CException(Yii::t('yii','{className} does not support add() functionality.',
|
||||
array('{className}'=>get_class($this))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* This method should be implemented by child classes to delete the data from actual cache storage.
|
||||
* @param string $key the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
* @throws CException if this method is not overridden by child classes
|
||||
*/
|
||||
protected function deleteValue($key)
|
||||
{
|
||||
throw new CException(Yii::t('yii','{className} does not support delete() functionality.',
|
||||
array('{className}'=>get_class($this))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* Child classes may implement this method to realize the flush operation.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
* @throws CException if this method is not overridden by child classes
|
||||
* @since 1.1.5
|
||||
*/
|
||||
protected function flushValues()
|
||||
{
|
||||
throw new CException(Yii::t('yii','{className} does not support flushValues() functionality.',
|
||||
array('{className}'=>get_class($this))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is a cache entry with a specified key.
|
||||
* This method is required by the interface ArrayAccess.
|
||||
* @param string $id a key identifying the cached value
|
||||
* @return boolean
|
||||
*/
|
||||
public function offsetExists($id)
|
||||
{
|
||||
return $this->get($id)!==false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value from cache with a specified key.
|
||||
* This method is required by the interface ArrayAccess.
|
||||
* @param string $id a key identifying the cached value
|
||||
* @return mixed the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
public function offsetGet($id)
|
||||
{
|
||||
return $this->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the value identified by a key into cache.
|
||||
* If the cache already contains such a key, the existing value will be
|
||||
* replaced with the new ones. To add expiration and dependencies, use the set() method.
|
||||
* This method is required by the interface ArrayAccess.
|
||||
* @param string $id the key identifying the value to be cached
|
||||
* @param mixed $value the value to be cached
|
||||
*/
|
||||
public function offsetSet($id, $value)
|
||||
{
|
||||
$this->set($id, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the value with the specified key from cache
|
||||
* This method is required by the interface ArrayAccess.
|
||||
* @param string $id the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
public function offsetUnset($id)
|
||||
{
|
||||
$this->delete($id);
|
||||
}
|
||||
}
|
||||
313
framework/caching/CDbCache.php
Normal file
313
framework/caching/CDbCache.php
Normal file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/**
|
||||
* CDbCache class file
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CDbCache implements a cache application component by storing cached data in a database.
|
||||
*
|
||||
* CDbCache stores cache data in a DB table named {@link cacheTableName}.
|
||||
* If the table does not exist, it will be automatically created.
|
||||
* By setting {@link autoCreateCacheTable} to false, you can also manually create the DB table.
|
||||
*
|
||||
* CDbCache relies on {@link http://www.php.net/manual/en/ref.pdo.php PDO} to access database.
|
||||
* By default, it will use a SQLite3 database under the application runtime directory.
|
||||
* You can also specify {@link connectionID} so that it makes use of
|
||||
* a DB application component to access database.
|
||||
*
|
||||
* See {@link CCache} manual for common cache operations that are supported by CDbCache.
|
||||
*
|
||||
* @property integer $gCProbability The probability (parts per million) that garbage collection (GC) should be performed
|
||||
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance.
|
||||
* @property CDbConnection $dbConnection The DB connection instance.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching
|
||||
* @since 1.0
|
||||
*/
|
||||
class CDbCache extends CCache
|
||||
{
|
||||
/**
|
||||
* @var string the ID of the {@link CDbConnection} application component. If not set,
|
||||
* a SQLite3 database will be automatically created and used. The SQLite database file
|
||||
* is <code>protected/runtime/cache-YiiVersion.db</code>.
|
||||
*/
|
||||
public $connectionID;
|
||||
/**
|
||||
* @var string name of the DB table to store cache content. Defaults to 'YiiCache'.
|
||||
* Note, if {@link autoCreateCacheTable} is false and you want to create the DB table
|
||||
* manually by yourself, you need to make sure the DB table is of the following structure:
|
||||
* <pre>
|
||||
* (id CHAR(128) PRIMARY KEY, expire INTEGER, value BLOB)
|
||||
* </pre>
|
||||
* Note, some DBMS might not support BLOB type. In this case, replace 'BLOB' with a suitable
|
||||
* binary data type (e.g. LONGBLOB in MySQL, BYTEA in PostgreSQL.)
|
||||
* @see autoCreateCacheTable
|
||||
*/
|
||||
public $cacheTableName='YiiCache';
|
||||
/**
|
||||
* @var boolean whether the cache DB table should be created automatically if it does not exist. Defaults to true.
|
||||
* If you already have the table created, it is recommended you set this property to be false to improve performance.
|
||||
* @see cacheTableName
|
||||
*/
|
||||
public $autoCreateCacheTable=true;
|
||||
/**
|
||||
* @var CDbConnection the DB connection instance
|
||||
*/
|
||||
private $_db;
|
||||
private $_gcProbability=100;
|
||||
private $_gced=false;
|
||||
|
||||
/**
|
||||
* Initializes this application component.
|
||||
*
|
||||
* This method is required by the {@link IApplicationComponent} interface.
|
||||
* It ensures the existence of the cache DB table.
|
||||
* It also removes expired data items from the cache.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$db=$this->getDbConnection();
|
||||
$db->setActive(true);
|
||||
if($this->autoCreateCacheTable)
|
||||
{
|
||||
$sql="DELETE FROM {$this->cacheTableName} WHERE expire>0 AND expire<".time();
|
||||
try
|
||||
{
|
||||
$db->createCommand($sql)->execute();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$this->createCacheTable($db,$this->cacheTableName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer the probability (parts per million) that garbage collection (GC) should be performed
|
||||
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance.
|
||||
*/
|
||||
public function getGCProbability()
|
||||
{
|
||||
return $this->_gcProbability;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $value the probability (parts per million) that garbage collection (GC) should be performed
|
||||
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance.
|
||||
* This number should be between 0 and 1000000. A value 0 meaning no GC will be performed at all.
|
||||
*/
|
||||
public function setGCProbability($value)
|
||||
{
|
||||
$value=(int)$value;
|
||||
if($value<0)
|
||||
$value=0;
|
||||
if($value>1000000)
|
||||
$value=1000000;
|
||||
$this->_gcProbability=$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the cache DB table.
|
||||
* @param CDbConnection $db the database connection
|
||||
* @param string $tableName the name of the table to be created
|
||||
*/
|
||||
protected function createCacheTable($db,$tableName)
|
||||
{
|
||||
$driver=$db->getDriverName();
|
||||
if($driver==='mysql')
|
||||
$blob='LONGBLOB';
|
||||
elseif($driver==='pgsql')
|
||||
$blob='BYTEA';
|
||||
else
|
||||
$blob='BLOB';
|
||||
$sql=<<<EOD
|
||||
CREATE TABLE $tableName
|
||||
(
|
||||
id CHAR(128) PRIMARY KEY,
|
||||
expire INTEGER,
|
||||
value $blob
|
||||
)
|
||||
EOD;
|
||||
$db->createCommand($sql)->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CDbConnection the DB connection instance
|
||||
* @throws CException if {@link connectionID} does not point to a valid application component.
|
||||
*/
|
||||
public function getDbConnection()
|
||||
{
|
||||
if($this->_db!==null)
|
||||
return $this->_db;
|
||||
elseif(($id=$this->connectionID)!==null)
|
||||
{
|
||||
if(($this->_db=Yii::app()->getComponent($id)) instanceof CDbConnection)
|
||||
return $this->_db;
|
||||
else
|
||||
throw new CException(Yii::t('yii','CDbCache.connectionID "{id}" is invalid. Please make sure it refers to the ID of a CDbConnection application component.',
|
||||
array('{id}'=>$id)));
|
||||
}
|
||||
else
|
||||
{
|
||||
$dbFile=Yii::app()->getRuntimePath().DIRECTORY_SEPARATOR.'cache-'.Yii::getVersion().'.db';
|
||||
return $this->_db=new CDbConnection('sqlite:'.$dbFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the DB connection used by the cache component.
|
||||
* @param CDbConnection $value the DB connection instance
|
||||
* @since 1.1.5
|
||||
*/
|
||||
public function setDbConnection($value)
|
||||
{
|
||||
$this->_db=$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
$time=time();
|
||||
$sql="SELECT value FROM {$this->cacheTableName} WHERE id='$key' AND (expire=0 OR expire>$time)";
|
||||
$db=$this->getDbConnection();
|
||||
if($db->queryCachingDuration>0)
|
||||
{
|
||||
$duration=$db->queryCachingDuration;
|
||||
$db->queryCachingDuration=0;
|
||||
$result=$db->createCommand($sql)->queryScalar();
|
||||
$db->queryCachingDuration=$duration;
|
||||
return $result;
|
||||
}
|
||||
else
|
||||
return $db->createCommand($sql)->queryScalar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple values from cache with the specified keys.
|
||||
* @param array $keys a list of keys identifying the cached values
|
||||
* @return array a list of cached values indexed by the keys
|
||||
*/
|
||||
protected function getValues($keys)
|
||||
{
|
||||
if(empty($keys))
|
||||
return array();
|
||||
|
||||
$ids=implode("','",$keys);
|
||||
$time=time();
|
||||
$sql="SELECT id, value FROM {$this->cacheTableName} WHERE id IN ('$ids') AND (expire=0 OR expire>$time)";
|
||||
|
||||
$db=$this->getDbConnection();
|
||||
if($db->queryCachingDuration>0)
|
||||
{
|
||||
$duration=$db->queryCachingDuration;
|
||||
$db->queryCachingDuration=0;
|
||||
$rows=$db->createCommand($sql)->queryAll();
|
||||
$db->queryCachingDuration=$duration;
|
||||
}
|
||||
else
|
||||
$rows=$db->createCommand($sql)->queryAll();
|
||||
|
||||
$results=array();
|
||||
foreach($keys as $key)
|
||||
$results[$key]=false;
|
||||
foreach($rows as $row)
|
||||
$results[$row['id']]=$row['value'];
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function setValue($key,$value,$expire)
|
||||
{
|
||||
$this->deleteValue($key);
|
||||
return $this->addValue($key,$value,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function addValue($key,$value,$expire)
|
||||
{
|
||||
if(!$this->_gced && mt_rand(0,1000000)<$this->_gcProbability)
|
||||
{
|
||||
$this->gc();
|
||||
$this->_gced=true;
|
||||
}
|
||||
|
||||
if($expire>0)
|
||||
$expire+=time();
|
||||
else
|
||||
$expire=0;
|
||||
$sql="INSERT INTO {$this->cacheTableName} (id,expire,value) VALUES ('$key',$expire,:value)";
|
||||
try
|
||||
{
|
||||
$command=$this->getDbConnection()->createCommand($sql);
|
||||
$command->bindValue(':value',$value,PDO::PARAM_LOB);
|
||||
$command->execute();
|
||||
return true;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
protected function deleteValue($key)
|
||||
{
|
||||
$sql="DELETE FROM {$this->cacheTableName} WHERE id='$key'";
|
||||
$this->getDbConnection()->createCommand($sql)->execute();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the expired data values.
|
||||
*/
|
||||
protected function gc()
|
||||
{
|
||||
$this->getDbConnection()->createCommand("DELETE FROM {$this->cacheTableName} WHERE expire>0 AND expire<".time())->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
* @since 1.1.5
|
||||
*/
|
||||
protected function flushValues()
|
||||
{
|
||||
$this->getDbConnection()->createCommand("DELETE FROM {$this->cacheTableName}")->execute();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
163
framework/caching/CDummyCache.php
Normal file
163
framework/caching/CDummyCache.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/**
|
||||
* CDummyCache class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CDummyCache is a placeholder cache component.
|
||||
*
|
||||
* CDummyCache does not cache anything. It is provided so that one can always configure
|
||||
* a 'cache' application component and he does not need to check if Yii::app()->cache is null or not.
|
||||
* By replacing CDummyCache with some other cache component, one can quickly switch from
|
||||
* non-caching mode to caching mode.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching
|
||||
* @since 1.0
|
||||
*/
|
||||
class CDummyCache extends CApplicationComponent implements ICache, ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @var string a string prefixed to every cache key so that it is unique. Defaults to {@link CApplication::getId() application ID}.
|
||||
*/
|
||||
public $keyPrefix;
|
||||
|
||||
/**
|
||||
* Initializes the application component.
|
||||
* This method overrides the parent implementation by setting default cache key prefix.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if($this->keyPrefix===null)
|
||||
$this->keyPrefix=Yii::app()->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* @param string $id a key identifying the cached value
|
||||
* @return mixed the value stored in cache, false if the value is not in the cache, expired or the dependency has changed.
|
||||
*/
|
||||
public function get($id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple values from cache with the specified keys.
|
||||
* Some caches (such as memcache, apc) allow retrieving multiple cached values at one time,
|
||||
* which may improve the performance since it reduces the communication cost.
|
||||
* In case a cache doesn't support this feature natively, it will be simulated by this method.
|
||||
* @param array $ids list of keys identifying the cached values
|
||||
* @return array list of cached values corresponding to the specified keys. The array
|
||||
* is returned in terms of (key,value) pairs.
|
||||
* If a value is not cached or expired, the corresponding array value will be false.
|
||||
*/
|
||||
public function mget($ids)
|
||||
{
|
||||
$results=array();
|
||||
foreach($ids as $id)
|
||||
$results[$id]=false;
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache.
|
||||
* If the cache already contains such a key, the existing value and
|
||||
* expiration time will be replaced with the new ones.
|
||||
*
|
||||
* @param string $id the key identifying the value to be cached
|
||||
* @param mixed $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
public function set($id,$value,$expire=0,$dependency=null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* Nothing will be done if the cache already contains the key.
|
||||
* @param string $id the key identifying the value to be cached
|
||||
* @param mixed $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
public function add($id,$value,$expire=0,$dependency=null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* @param string $id the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* Be careful of performing this operation if the cache is shared by multiple applications.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
* @throws CException if this method is not overridden by child classes
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is a cache entry with a specified key.
|
||||
* This method is required by the interface ArrayAccess.
|
||||
* @param string $id a key identifying the cached value
|
||||
* @return boolean
|
||||
*/
|
||||
public function offsetExists($id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value from cache with a specified key.
|
||||
* This method is required by the interface ArrayAccess.
|
||||
* @param string $id a key identifying the cached value
|
||||
* @return mixed the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
public function offsetGet($id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the value identified by a key into cache.
|
||||
* If the cache already contains such a key, the existing value will be
|
||||
* replaced with the new ones. To add expiration and dependencies, use the set() method.
|
||||
* This method is required by the interface ArrayAccess.
|
||||
* @param string $id the key identifying the value to be cached
|
||||
* @param mixed $value the value to be cached
|
||||
*/
|
||||
public function offsetSet($id, $value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the value with the specified key from cache
|
||||
* This method is required by the interface ArrayAccess.
|
||||
* @param string $id the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
public function offsetUnset($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
106
framework/caching/CEAcceleratorCache.php
Normal file
106
framework/caching/CEAcceleratorCache.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* CEAcceleratorCache class file
|
||||
*
|
||||
* @author Steffen Dietz <steffo.dietz[at]googlemail[dot]com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CEAcceleratorCache implements a cache application module based on {@link http://eaccelerator.net/ eaccelerator}.
|
||||
*
|
||||
* To use this application component, the eAccelerator PHP extension must be loaded.
|
||||
*
|
||||
* See {@link CCache} manual for common cache operations that are supported by CEAccelerator.
|
||||
*
|
||||
* Please note that as of v0.9.6, eAccelerator no longer supports data caching.
|
||||
* This means if you still want to use this component, your eAccelerator should be of 0.9.5.x or lower version.
|
||||
*
|
||||
* @author Steffen Dietz <steffo.dietz[at]googlemail[dot]com>
|
||||
* @package system.caching
|
||||
*/
|
||||
class CEAcceleratorCache extends CCache
|
||||
{
|
||||
/**
|
||||
* Initializes this application component.
|
||||
* This method is required by the {@link IApplicationComponent} interface.
|
||||
* It checks the availability of eAccelerator.
|
||||
* @throws CException if eAccelerator extension is not loaded, is disabled or the cache functions are not compiled in.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if(!function_exists('eaccelerator_get'))
|
||||
throw new CException(Yii::t('yii','CEAcceleratorCache requires PHP eAccelerator extension to be loaded, enabled or compiled with the "--with-eaccelerator-shared-memory" option.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
$result = eaccelerator_get($key);
|
||||
return $result !== NULL ? $result : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function setValue($key,$value,$expire)
|
||||
{
|
||||
return eaccelerator_put($key,$value,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function addValue($key,$value,$expire)
|
||||
{
|
||||
return (NULL === eaccelerator_get($key)) ? $this->setValue($key,$value,$expire) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
protected function deleteValue($key)
|
||||
{
|
||||
return eaccelerator_rm($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
* @since 1.1.5
|
||||
*/
|
||||
protected function flushValues()
|
||||
{
|
||||
// first, remove expired content from cache
|
||||
eaccelerator_gc();
|
||||
// now, remove leftover cache-keys
|
||||
$keys = eaccelerator_list_keys();
|
||||
foreach($keys as $key)
|
||||
$this->deleteValue(substr($key['name'], 1));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
242
framework/caching/CFileCache.php
Normal file
242
framework/caching/CFileCache.php
Normal file
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
/**
|
||||
* CFileCache class file
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CFileCache provides a file-based caching mechanism.
|
||||
*
|
||||
* For each data value being cached, CFileCache will use store it in a separate file
|
||||
* under {@link cachePath} which defaults to 'protected/runtime/cache'.
|
||||
* CFileCache will perform garbage collection automatically to remove expired cache files.
|
||||
*
|
||||
* See {@link CCache} manual for common cache operations that are supported by CFileCache.
|
||||
*
|
||||
* @property integer $gCProbability The probability (parts per million) that garbage collection (GC) should be performed
|
||||
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching
|
||||
*/
|
||||
class CFileCache extends CCache
|
||||
{
|
||||
/**
|
||||
* @var string the directory to store cache files. Defaults to null, meaning
|
||||
* using 'protected/runtime/cache' as the directory.
|
||||
*/
|
||||
public $cachePath;
|
||||
/**
|
||||
* @var string cache file suffix. Defaults to '.bin'.
|
||||
*/
|
||||
public $cacheFileSuffix='.bin';
|
||||
/**
|
||||
* @var integer the level of sub-directories to store cache files. Defaults to 0,
|
||||
* meaning no sub-directories. If the system has huge number of cache files (e.g. 10K+),
|
||||
* you may want to set this value to be 1 or 2 so that the file system is not over burdened.
|
||||
* The value of this property should not exceed 16 (less than 3 is recommended).
|
||||
*/
|
||||
public $directoryLevel=0;
|
||||
/**
|
||||
* @var boolean whether cache entry expiration time should be embedded into a physical file.
|
||||
* Defaults to false meaning that the file modification time will be used to store expire value.
|
||||
* True value means that first ten bytes of the file would be reserved and used to store expiration time.
|
||||
* On some systems PHP is not allowed to change file modification time to be in future even with 777
|
||||
* permissions, so this property could be useful in this case.
|
||||
* @since 1.1.14
|
||||
*/
|
||||
public $embedExpiry=false;
|
||||
|
||||
private $_gcProbability=100;
|
||||
private $_gced=false;
|
||||
|
||||
/**
|
||||
* Initializes this application component.
|
||||
* This method is required by the {@link IApplicationComponent} interface.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if($this->cachePath===null)
|
||||
$this->cachePath=Yii::app()->getRuntimePath().DIRECTORY_SEPARATOR.'cache';
|
||||
if(!is_dir($this->cachePath))
|
||||
mkdir($this->cachePath,0777,true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer the probability (parts per million) that garbage collection (GC) should be performed
|
||||
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance.
|
||||
*/
|
||||
public function getGCProbability()
|
||||
{
|
||||
return $this->_gcProbability;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $value the probability (parts per million) that garbage collection (GC) should be performed
|
||||
* when storing a piece of data in the cache. Defaults to 100, meaning 0.01% chance.
|
||||
* This number should be between 0 and 1000000. A value 0 meaning no GC will be performed at all.
|
||||
*/
|
||||
public function setGCProbability($value)
|
||||
{
|
||||
$value=(int)$value;
|
||||
if($value<0)
|
||||
$value=0;
|
||||
if($value>1000000)
|
||||
$value=1000000;
|
||||
$this->_gcProbability=$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
* @since 1.1.5
|
||||
*/
|
||||
protected function flushValues()
|
||||
{
|
||||
$this->gc(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
$cacheFile=$this->getCacheFile($key);
|
||||
if(($time=$this->filemtime($cacheFile))>time())
|
||||
return @file_get_contents($cacheFile,false,null,$this->embedExpiry ? 10 : -1);
|
||||
elseif($time>0)
|
||||
@unlink($cacheFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function setValue($key,$value,$expire)
|
||||
{
|
||||
if(!$this->_gced && mt_rand(0,1000000)<$this->_gcProbability)
|
||||
{
|
||||
$this->gc();
|
||||
$this->_gced=true;
|
||||
}
|
||||
|
||||
if($expire<=0)
|
||||
$expire=31536000; // 1 year
|
||||
$expire+=time();
|
||||
|
||||
$cacheFile=$this->getCacheFile($key);
|
||||
if($this->directoryLevel>0)
|
||||
@mkdir(dirname($cacheFile),0777,true);
|
||||
if(@file_put_contents($cacheFile,$this->embedExpiry ? $expire.$value : $value,LOCK_EX)!==false)
|
||||
{
|
||||
@chmod($cacheFile,0777);
|
||||
return $this->embedExpiry ? true : @touch($cacheFile,$expire);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function addValue($key,$value,$expire)
|
||||
{
|
||||
$cacheFile=$this->getCacheFile($key);
|
||||
if($this->filemtime($cacheFile)>time())
|
||||
return false;
|
||||
return $this->setValue($key,$value,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
protected function deleteValue($key)
|
||||
{
|
||||
$cacheFile=$this->getCacheFile($key);
|
||||
return @unlink($cacheFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cache file path given the cache key.
|
||||
* @param string $key cache key
|
||||
* @return string the cache file path
|
||||
*/
|
||||
protected function getCacheFile($key)
|
||||
{
|
||||
if($this->directoryLevel>0)
|
||||
{
|
||||
$base=$this->cachePath;
|
||||
for($i=0;$i<$this->directoryLevel;++$i)
|
||||
{
|
||||
if(($prefix=substr($key,$i+$i,2))!==false)
|
||||
$base.=DIRECTORY_SEPARATOR.$prefix;
|
||||
}
|
||||
return $base.DIRECTORY_SEPARATOR.$key.$this->cacheFileSuffix;
|
||||
}
|
||||
else
|
||||
return $this->cachePath.DIRECTORY_SEPARATOR.$key.$this->cacheFileSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes expired cache files.
|
||||
* @param boolean $expiredOnly whether only expired cache files should be removed.
|
||||
* If false, all cache files under {@link cachePath} will be removed.
|
||||
* @param string $path the path to clean with. If null, it will be {@link cachePath}.
|
||||
*/
|
||||
public function gc($expiredOnly=true,$path=null)
|
||||
{
|
||||
if($path===null)
|
||||
$path=$this->cachePath;
|
||||
if(($handle=opendir($path))===false)
|
||||
return;
|
||||
while(($file=readdir($handle))!==false)
|
||||
{
|
||||
if($file[0]==='.')
|
||||
continue;
|
||||
$fullPath=$path.DIRECTORY_SEPARATOR.$file;
|
||||
if(is_dir($fullPath))
|
||||
$this->gc($expiredOnly,$fullPath);
|
||||
elseif($expiredOnly && $this->filemtime($fullPath)<time() || !$expiredOnly)
|
||||
@unlink($fullPath);
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns cache file modification time. {@link $embedExpiry} aware.
|
||||
* @param string $path to the file, modification time to be retrieved from.
|
||||
* @return integer file modification time.
|
||||
*/
|
||||
private function filemtime($path)
|
||||
{
|
||||
if($this->embedExpiry)
|
||||
return (int)@file_get_contents($path,false,null,0,10);
|
||||
else
|
||||
return @filemtime($path);
|
||||
}
|
||||
}
|
||||
281
framework/caching/CMemCache.php
Normal file
281
framework/caching/CMemCache.php
Normal file
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
/**
|
||||
* CMemCache class file
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CMemCache implements a cache application component based on {@link http://memcached.org/ memcached}.
|
||||
*
|
||||
* CMemCache can be configured with a list of memcache servers by settings
|
||||
* its {@link setServers servers} property. By default, CMemCache assumes
|
||||
* there is a memcache server running on localhost at port 11211.
|
||||
*
|
||||
* See {@link CCache} manual for common cache operations that are supported by CMemCache.
|
||||
*
|
||||
* Note, there is no security measure to protected data in memcache.
|
||||
* All data in memcache can be accessed by any process running in the system.
|
||||
*
|
||||
* To use CMemCache as the cache application component, configure the application as follows,
|
||||
* <pre>
|
||||
* array(
|
||||
* 'components'=>array(
|
||||
* 'cache'=>array(
|
||||
* 'class'=>'CMemCache',
|
||||
* 'servers'=>array(
|
||||
* array(
|
||||
* 'host'=>'server1',
|
||||
* 'port'=>11211,
|
||||
* 'weight'=>60,
|
||||
* ),
|
||||
* array(
|
||||
* 'host'=>'server2',
|
||||
* 'port'=>11211,
|
||||
* 'weight'=>40,
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
* )
|
||||
* </pre>
|
||||
* In the above, two memcache servers are used: server1 and server2.
|
||||
* You can configure more properties of every server, including:
|
||||
* host, port, persistent, weight, timeout, retryInterval, status.
|
||||
* See {@link http://www.php.net/manual/en/function.memcache-addserver.php}
|
||||
* for more details.
|
||||
*
|
||||
* CMemCache can also be used with {@link http://pecl.php.net/package/memcached memcached}.
|
||||
* To do so, set {@link useMemcached} to be true.
|
||||
*
|
||||
* @property mixed $memCache The memcache instance (or memcached if {@link useMemcached} is true) used by this component.
|
||||
* @property array $servers List of memcache server configurations. Each element is a {@link CMemCacheServerConfiguration}.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching
|
||||
* @since 1.0
|
||||
*/
|
||||
class CMemCache extends CCache
|
||||
{
|
||||
/**
|
||||
* @var boolean whether to use memcached or memcache as the underlying caching extension.
|
||||
* If true {@link http://pecl.php.net/package/memcached memcached} will be used.
|
||||
* If false {@link http://pecl.php.net/package/memcache memcache}. will be used.
|
||||
* Defaults to false.
|
||||
*/
|
||||
public $useMemcached=false;
|
||||
/**
|
||||
* @var Memcache the Memcache instance
|
||||
*/
|
||||
private $_cache=null;
|
||||
/**
|
||||
* @var array list of memcache server configurations
|
||||
*/
|
||||
private $_servers=array();
|
||||
|
||||
/**
|
||||
* Initializes this application component.
|
||||
* This method is required by the {@link IApplicationComponent} interface.
|
||||
* It creates the memcache instance and adds memcache servers.
|
||||
* @throws CException if memcache extension is not loaded
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
$servers=$this->getServers();
|
||||
$cache=$this->getMemCache();
|
||||
if(count($servers))
|
||||
{
|
||||
foreach($servers as $server)
|
||||
{
|
||||
if($this->useMemcached)
|
||||
$cache->addServer($server->host,$server->port,$server->weight);
|
||||
else
|
||||
$cache->addServer($server->host,$server->port,$server->persistent,$server->weight,$server->timeout,$server->retryInterval,$server->status);
|
||||
}
|
||||
}
|
||||
else
|
||||
$cache->addServer('localhost',11211);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws CException if extension isn't loaded
|
||||
* @return Memcache|Memcached the memcache instance (or memcached if {@link useMemcached} is true) used by this component.
|
||||
*/
|
||||
public function getMemCache()
|
||||
{
|
||||
if($this->_cache!==null)
|
||||
return $this->_cache;
|
||||
else
|
||||
{
|
||||
$extension=$this->useMemcached ? 'memcached' : 'memcache';
|
||||
if(!extension_loaded($extension))
|
||||
throw new CException(Yii::t('yii',"CMemCache requires PHP {extension} extension to be loaded.",
|
||||
array('{extension}'=>$extension)));
|
||||
return $this->_cache=$this->useMemcached ? new Memcached : new Memcache;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array list of memcache server configurations. Each element is a {@link CMemCacheServerConfiguration}.
|
||||
*/
|
||||
public function getServers()
|
||||
{
|
||||
return $this->_servers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $config list of memcache server configurations. Each element must be an array
|
||||
* with the following keys: host, port, persistent, weight, timeout, retryInterval, status.
|
||||
* @see http://www.php.net/manual/en/function.Memcache-addServer.php
|
||||
*/
|
||||
public function setServers($config)
|
||||
{
|
||||
foreach($config as $c)
|
||||
$this->_servers[]=new CMemCacheServerConfiguration($c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
return $this->_cache->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple values from cache with the specified keys.
|
||||
* @param array $keys a list of keys identifying the cached values
|
||||
* @return array a list of cached values indexed by the keys
|
||||
*/
|
||||
protected function getValues($keys)
|
||||
{
|
||||
return $this->useMemcached ? $this->_cache->getMulti($keys) : $this->_cache->get($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function setValue($key,$value,$expire)
|
||||
{
|
||||
if($expire>0)
|
||||
$expire+=time();
|
||||
else
|
||||
$expire=0;
|
||||
|
||||
return $this->useMemcached ? $this->_cache->set($key,$value,$expire) : $this->_cache->set($key,$value,0,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function addValue($key,$value,$expire)
|
||||
{
|
||||
if($expire>0)
|
||||
$expire+=time();
|
||||
else
|
||||
$expire=0;
|
||||
|
||||
return $this->useMemcached ? $this->_cache->add($key,$value,$expire) : $this->_cache->add($key,$value,0,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
protected function deleteValue($key)
|
||||
{
|
||||
return $this->_cache->delete($key, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
* @since 1.1.5
|
||||
*/
|
||||
protected function flushValues()
|
||||
{
|
||||
return $this->_cache->flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CMemCacheServerConfiguration represents the configuration data for a single memcache server.
|
||||
*
|
||||
* See {@link http://www.php.net/manual/en/function.Memcache-addServer.php}
|
||||
* for detailed explanation of each configuration property.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching
|
||||
* @since 1.0
|
||||
*/
|
||||
class CMemCacheServerConfiguration extends CComponent
|
||||
{
|
||||
/**
|
||||
* @var string memcache server hostname or IP address
|
||||
*/
|
||||
public $host;
|
||||
/**
|
||||
* @var integer memcache server port
|
||||
*/
|
||||
public $port=11211;
|
||||
/**
|
||||
* @var boolean whether to use a persistent connection
|
||||
*/
|
||||
public $persistent=true;
|
||||
/**
|
||||
* @var integer probability of using this server among all servers.
|
||||
*/
|
||||
public $weight=1;
|
||||
/**
|
||||
* @var integer value in seconds which will be used for connecting to the server
|
||||
*/
|
||||
public $timeout=15;
|
||||
/**
|
||||
* @var integer how often a failed server will be retried (in seconds)
|
||||
*/
|
||||
public $retryInterval=15;
|
||||
/**
|
||||
* @var boolean if the server should be flagged as online upon a failure
|
||||
*/
|
||||
public $status=true;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param array $config list of memcache server configurations.
|
||||
* @throws CException if the configuration is not an array
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
if(is_array($config))
|
||||
{
|
||||
foreach($config as $key=>$value)
|
||||
$this->$key=$value;
|
||||
if($this->host===null)
|
||||
throw new CException(Yii::t('yii','CMemCache server configuration must have "host" value.'));
|
||||
}
|
||||
else
|
||||
throw new CException(Yii::t('yii','CMemCache server configuration must be an array.'));
|
||||
}
|
||||
}
|
||||
257
framework/caching/CRedisCache.php
Normal file
257
framework/caching/CRedisCache.php
Normal file
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/**
|
||||
* CRedisCache class file
|
||||
*
|
||||
* @author Carsten Brandt <mail@cebe.cc>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CRedisCache implements a cache application component based on {@link http://redis.io/ redis}.
|
||||
*
|
||||
* CRedisCache needs to be configured with {@link hostname}, {@link port} and {@link database} of the server
|
||||
* to connect to. By default CRedisCache assumes there is a redis server running on localhost at
|
||||
* port 6379 and uses the database number 0.
|
||||
*
|
||||
* CRedisCache also supports {@link http://redis.io/commands/auth the AUTH command} of redis.
|
||||
* When the server needs authentication, you can set the {@link password} property to
|
||||
* authenticate with the server after connect.
|
||||
*
|
||||
* See {@link CCache} manual for common cache operations that are supported by CRedisCache.
|
||||
*
|
||||
* To use CRedisCache as the cache application component, configure the application as follows,
|
||||
* <pre>
|
||||
* array(
|
||||
* 'components'=>array(
|
||||
* 'cache'=>array(
|
||||
* 'class'=>'CRedisCache',
|
||||
* 'hostname'=>'localhost',
|
||||
* 'port'=>6379,
|
||||
* 'database'=>0,
|
||||
* ),
|
||||
* ),
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* The minimum required redis version is 2.0.0.
|
||||
*
|
||||
* @author Carsten Brandt <mail@cebe.cc>
|
||||
* @package system.caching
|
||||
* @since 1.1.14
|
||||
*/
|
||||
class CRedisCache extends CCache
|
||||
{
|
||||
/**
|
||||
* @var string hostname to use for connecting to the redis server. Defaults to 'localhost'.
|
||||
*/
|
||||
public $hostname='localhost';
|
||||
/**
|
||||
* @var int the port to use for connecting to the redis server. Default port is 6379.
|
||||
*/
|
||||
public $port=6379;
|
||||
/**
|
||||
* @var string the password to use to authenticate with the redis server. If not set, no AUTH command will be sent.
|
||||
*/
|
||||
public $password;
|
||||
/**
|
||||
* @var int the redis database to use. This is an integer value starting from 0. Defaults to 0.
|
||||
*/
|
||||
public $database=0;
|
||||
/**
|
||||
* @var float timeout to use for connection to redis. If not set the timeout set in php.ini will be used: ini_get("default_socket_timeout")
|
||||
*/
|
||||
public $timeout=null;
|
||||
/**
|
||||
* @var resource redis socket connection
|
||||
*/
|
||||
private $_socket;
|
||||
|
||||
/**
|
||||
* Establishes a connection to the redis server.
|
||||
* It does nothing if the connection has already been established.
|
||||
* @throws CException if connecting fails
|
||||
*/
|
||||
protected function connect()
|
||||
{
|
||||
$this->_socket=@stream_socket_client(
|
||||
$this->hostname.':'.$this->port,
|
||||
$errorNumber,
|
||||
$errorDescription,
|
||||
$this->timeout ? $this->timeout : ini_get("default_socket_timeout")
|
||||
);
|
||||
if ($this->_socket)
|
||||
{
|
||||
if($this->password!==null)
|
||||
$this->executeCommand('AUTH',array($this->password));
|
||||
$this->executeCommand('SELECT',array($this->database));
|
||||
}
|
||||
else
|
||||
throw new CException('Failed to connect to redis: '.$errorDescription,(int)$errorNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a redis command.
|
||||
* For a list of available commands and their parameters see {@link http://redis.io/commands}.
|
||||
*
|
||||
* @param string $name the name of the command
|
||||
* @param array $params list of parameters for the command
|
||||
* @return array|bool|null|string Dependend on the executed command this method
|
||||
* will return different data types:
|
||||
* <ul>
|
||||
* <li><code>true</code> for commands that return "status reply".</li>
|
||||
* <li><code>string</code> for commands that return "integer reply"
|
||||
* as the value is in the range of a signed 64 bit integer.</li>
|
||||
* <li><code>string</code> or <code>null</code> for commands that return "bulk reply".</li>
|
||||
* <li><code>array</code> for commands that return "Multi-bulk replies".</li>
|
||||
* </ul>
|
||||
* See {@link http://redis.io/topics/protocol redis protocol description}
|
||||
* for details on the mentioned reply types.
|
||||
* @trows CException for commands that return {@link http://redis.io/topics/protocol#error-reply error reply}.
|
||||
*/
|
||||
public function executeCommand($name,$params=array())
|
||||
{
|
||||
if($this->_socket===null)
|
||||
$this->connect();
|
||||
|
||||
array_unshift($params,$name);
|
||||
$command='*'.count($params)."\r\n";
|
||||
foreach($params as $arg)
|
||||
$command.='$'.strlen($arg)."\r\n".$arg."\r\n";
|
||||
|
||||
fwrite($this->_socket,$command);
|
||||
|
||||
return $this->parseResponse(implode(' ',$params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the result from socket and parses it
|
||||
* @return array|bool|null|string
|
||||
* @throws CException socket or data problems
|
||||
*/
|
||||
private function parseResponse()
|
||||
{
|
||||
if(($line=fgets($this->_socket))===false)
|
||||
throw new CException('Failed reading data from redis connection socket.');
|
||||
$type=$line[0];
|
||||
$line=substr($line,1,-2);
|
||||
switch($type)
|
||||
{
|
||||
case '+': // Status reply
|
||||
return true;
|
||||
case '-': // Error reply
|
||||
throw new CException('Redis error: '.$line);
|
||||
case ':': // Integer reply
|
||||
// no cast to int as it is in the range of a signed 64 bit integer
|
||||
return $line;
|
||||
case '$': // Bulk replies
|
||||
if($line=='-1')
|
||||
return null;
|
||||
$length=$line+2;
|
||||
$data='';
|
||||
while($length>0)
|
||||
{
|
||||
if(($block=fread($this->_socket,$length))===false)
|
||||
throw new CException('Failed reading data from redis connection socket.');
|
||||
$data.=$block;
|
||||
$length-=(function_exists('mb_strlen') ? mb_strlen($block,'8bit') : strlen($block));
|
||||
}
|
||||
return substr($data,0,-2);
|
||||
case '*': // Multi-bulk replies
|
||||
$count=(int)$line;
|
||||
$data=array();
|
||||
for($i=0;$i<$count;$i++)
|
||||
$data[]=$this->parseResponse();
|
||||
return $data;
|
||||
default:
|
||||
throw new CException('Unable to parse data received from redis.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
return $this->executeCommand('GET',array($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple values from cache with the specified keys.
|
||||
* @param array $keys a list of keys identifying the cached values
|
||||
* @return array a list of cached values indexed by the keys
|
||||
*/
|
||||
protected function getValues($keys)
|
||||
{
|
||||
$response=$this->executeCommand('MGET',$keys);
|
||||
$result=array();
|
||||
$i=0;
|
||||
foreach($keys as $key)
|
||||
$result[$key]=$response[$i++];
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function setValue($key,$value,$expire)
|
||||
{
|
||||
if ($expire==0)
|
||||
return (bool)$this->executeCommand('SET',array($key,$value));
|
||||
return (bool)$this->executeCommand('SETEX',array($key,$expire,$value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function addValue($key,$value,$expire)
|
||||
{
|
||||
if ($expire == 0)
|
||||
return (bool)$this->executeCommand('SETNX',array($key,$value));
|
||||
|
||||
if($this->executeCommand('SETNX',array($key,$value)))
|
||||
{
|
||||
$this->executeCommand('EXPIRE',array($key,$expire));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
protected function deleteValue($key)
|
||||
{
|
||||
return (bool)$this->executeCommand('DEL',array($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
*/
|
||||
protected function flushValues()
|
||||
{
|
||||
return $this->executeCommand('FLUSHDB');
|
||||
}
|
||||
}
|
||||
108
framework/caching/CWinCache.php
Normal file
108
framework/caching/CWinCache.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* CWinCache class file
|
||||
*
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CWinCache implements a cache application component based on {@link http://www.iis.net/expand/wincacheforphp WinCache}.
|
||||
*
|
||||
* To use this application component, the WinCache PHP extension must be loaded.
|
||||
*
|
||||
* See {@link CCache} manual for common cache operations that are supported by CWinCache.
|
||||
*
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @package system.caching
|
||||
* @since 1.1.2
|
||||
*/
|
||||
class CWinCache extends CCache {
|
||||
/**
|
||||
* Initializes this application component.
|
||||
* This method is required by the {@link IApplicationComponent} interface.
|
||||
* It checks the availability of WinCache extension and WinCache user cache.
|
||||
* @throws CException if WinCache extension is not loaded or user cache is disabled
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if(!extension_loaded('wincache'))
|
||||
throw new CException(Yii::t('yii', 'CWinCache requires PHP wincache extension to be loaded.'));
|
||||
if(!ini_get('wincache.ucenabled'))
|
||||
throw new CException(Yii::t('yii', 'CWinCache user cache is disabled. Please set wincache.ucenabled to On in your php.ini.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
return wincache_ucache_get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple values from cache with the specified keys.
|
||||
* @param array $keys a list of keys identifying the cached values
|
||||
* @return array a list of cached values indexed by the keys
|
||||
*/
|
||||
protected function getValues($keys)
|
||||
{
|
||||
return wincache_ucache_get($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function setValue($key,$value,$expire)
|
||||
{
|
||||
return wincache_ucache_set($key,$value,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function addValue($key,$value,$expire)
|
||||
{
|
||||
return wincache_ucache_add($key,$value,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
protected function deleteValue($key)
|
||||
{
|
||||
return wincache_ucache_delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
* @since 1.1.5
|
||||
*/
|
||||
protected function flushValues()
|
||||
{
|
||||
return wincache_ucache_clear();
|
||||
}
|
||||
}
|
||||
103
framework/caching/CXCache.php
Normal file
103
framework/caching/CXCache.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* CXCache class file
|
||||
*
|
||||
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CXCache implements a cache application module based on {@link http://xcache.lighttpd.net/ xcache}.
|
||||
*
|
||||
* To use this application component, the XCache PHP extension must be loaded.
|
||||
* Flush functionality will only work correctly if "xcache.admin.enable_auth" is set to "Off" in php.ini.
|
||||
*
|
||||
* See {@link CCache} manual for common cache operations that are supported by CXCache.
|
||||
*
|
||||
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
|
||||
* @package system.caching
|
||||
*/
|
||||
class CXCache extends CCache
|
||||
{
|
||||
/**
|
||||
* Initializes this application component.
|
||||
* This method is required by the {@link IApplicationComponent} interface.
|
||||
* It checks the availability of memcache.
|
||||
* @throws CException if memcache extension is not loaded or is disabled.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if(!function_exists('xcache_isset'))
|
||||
throw new CException(Yii::t('yii','CXCache requires PHP XCache extension to be loaded.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
return xcache_isset($key) ? xcache_get($key) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function setValue($key,$value,$expire)
|
||||
{
|
||||
return xcache_set($key,$value,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function addValue($key,$value,$expire)
|
||||
{
|
||||
return !xcache_isset($key) ? $this->setValue($key,$value,$expire) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
protected function deleteValue($key)
|
||||
{
|
||||
return xcache_unset($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
* @since 1.1.5
|
||||
*/
|
||||
protected function flushValues()
|
||||
{
|
||||
for($i=0, $max=xcache_count(XC_TYPE_VAR); $i<$max; $i++)
|
||||
{
|
||||
if(xcache_clear_cache(XC_TYPE_VAR, $i)===false)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
98
framework/caching/CZendDataCache.php
Normal file
98
framework/caching/CZendDataCache.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* CZendDataCache class file
|
||||
*
|
||||
* @author Steffen Dietz <steffo.dietz[at]googlemail[dot]com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CZendDataCache implements a cache application module based on the Zend Data Cache
|
||||
* delivered with {@link http://www.zend.com/en/products/server/ ZendServer}.
|
||||
*
|
||||
* To use this application component, the Zend Data Cache PHP extension must be loaded.
|
||||
*
|
||||
* See {@link CCache} manual for common cache operations that are supported by CZendDataCache.
|
||||
*
|
||||
* @author Steffen Dietz <steffo.dietz[at]googlemail[dot]com>
|
||||
* @package system.caching
|
||||
*/
|
||||
class CZendDataCache extends CCache
|
||||
{
|
||||
/**
|
||||
* Initializes this application component.
|
||||
* This method is required by the {@link IApplicationComponent} interface.
|
||||
* It checks the availability of Zend Data Cache.
|
||||
* @throws CException if Zend Data Cache extension is not loaded.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if(!function_exists('zend_shm_cache_store'))
|
||||
throw new CException(Yii::t('yii','CZendDataCache requires PHP Zend Data Cache extension to be loaded.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
$result = zend_shm_cache_fetch($key);
|
||||
return $result !== NULL ? $result : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function setValue($key,$value,$expire)
|
||||
{
|
||||
return zend_shm_cache_store($key,$value,$expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key into cache if the cache does not contain this key.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param string $value the value to be cached
|
||||
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
protected function addValue($key,$value,$expire)
|
||||
{
|
||||
return (NULL === zend_shm_cache_fetch($key)) ? $this->setValue($key,$value,$expire) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a value with the specified key from cache
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @param string $key the key of the value to be deleted
|
||||
* @return boolean if no error happens during deletion
|
||||
*/
|
||||
protected function deleteValue($key)
|
||||
{
|
||||
return zend_shm_cache_delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
* This is the implementation of the method declared in the parent class.
|
||||
* @return boolean whether the flush operation was successful.
|
||||
* @since 1.1.5
|
||||
*/
|
||||
protected function flushValues()
|
||||
{
|
||||
return zend_shm_cache_clear();
|
||||
}
|
||||
}
|
||||
117
framework/caching/dependencies/CCacheDependency.php
Normal file
117
framework/caching/dependencies/CCacheDependency.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* CCacheDependency class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CCacheDependency is the base class for cache dependency classes.
|
||||
*
|
||||
* CCacheDependency implements the {@link ICacheDependency} interface.
|
||||
* Child classes should override its {@link generateDependentData} for
|
||||
* actual dependency checking.
|
||||
*
|
||||
* @property boolean $hasChanged Whether the dependency has changed.
|
||||
* @property mixed $dependentData The data used to determine if dependency has been changed.
|
||||
* This data is available after {@link evaluateDependency} is called.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching.dependencies
|
||||
* @since 1.0
|
||||
*/
|
||||
class CCacheDependency extends CComponent implements ICacheDependency
|
||||
{
|
||||
/**
|
||||
* @var boolean Whether this dependency is reusable or not.
|
||||
* If set to true, dependent data for this cache dependency will only be generated once per request.
|
||||
* You can then use the same cache dependency for multiple separate cache calls on the same page
|
||||
* without the overhead of re-evaluating the dependency each time.
|
||||
* Defaults to false;
|
||||
* @since 1.1.11
|
||||
*/
|
||||
public $reuseDependentData=false;
|
||||
|
||||
/**
|
||||
* @var array cached data for reusable dependencies.
|
||||
* @since 1.1.11
|
||||
*/
|
||||
private static $_reusableData=array();
|
||||
|
||||
private $_hash;
|
||||
private $_data;
|
||||
|
||||
/**
|
||||
* Evaluates the dependency by generating and saving the data related with dependency.
|
||||
* This method is invoked by cache before writing data into it.
|
||||
*/
|
||||
public function evaluateDependency()
|
||||
{
|
||||
if ($this->reuseDependentData)
|
||||
{
|
||||
$hash=$this->getHash();
|
||||
if(!isset(self::$_reusableData[$hash]['dependentData']))
|
||||
self::$_reusableData[$hash]['dependentData']=$this->generateDependentData();
|
||||
$this->_data=self::$_reusableData[$hash]['dependentData'];
|
||||
}
|
||||
else
|
||||
$this->_data=$this->generateDependentData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean whether the dependency has changed.
|
||||
*/
|
||||
public function getHasChanged()
|
||||
{
|
||||
if ($this->reuseDependentData)
|
||||
{
|
||||
$hash=$this->getHash();
|
||||
if(!isset(self::$_reusableData[$hash]['dependentData']))
|
||||
self::$_reusableData[$hash]['dependentData']=$this->generateDependentData();
|
||||
return self::$_reusableData[$hash]['dependentData']!=$this->_data;
|
||||
}
|
||||
else
|
||||
return $this->generateDependentData()!=$this->_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed the data used to determine if dependency has been changed.
|
||||
* This data is available after {@link evaluateDependency} is called.
|
||||
*/
|
||||
public function getDependentData()
|
||||
{
|
||||
return $this->_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets cached data for reusable dependencies.
|
||||
* @since 1.1.14
|
||||
*/
|
||||
public static function resetReusableData()
|
||||
{
|
||||
self::$_reusableData=array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the data needed to determine if dependency has been changed.
|
||||
* Derived classes should override this method to generate actual dependent data.
|
||||
* @return mixed the data needed to determine if dependency has been changed.
|
||||
*/
|
||||
protected function generateDependentData()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Generates a unique hash that identifies this cache dependency.
|
||||
* @return string the hash for this cache dependency
|
||||
*/
|
||||
private function getHash()
|
||||
{
|
||||
if($this->_hash===null)
|
||||
$this->_hash=sha1(serialize($this));
|
||||
return $this->_hash;
|
||||
}
|
||||
}
|
||||
97
framework/caching/dependencies/CChainedCacheDependency.php
Normal file
97
framework/caching/dependencies/CChainedCacheDependency.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* CChainedCacheDependency class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CChainedCacheDependency represents a list of cache dependencies.
|
||||
*
|
||||
* If any of the dependencies reports a dependency change, CChainedCacheDependency
|
||||
* will return true for the checking.
|
||||
*
|
||||
* To add dependencies to CChainedCacheDependency, use {@link getDependencies Dependencies}
|
||||
* which gives a {@link CTypedList} instance and can be used like an array
|
||||
* (see {@link CList} for more details}).
|
||||
*
|
||||
* @property CTypedList $dependencies List of dependency objects.
|
||||
* @property boolean $hasChanged Whether the dependency is changed or not.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching.dependencies
|
||||
* @since 1.0
|
||||
*/
|
||||
class CChainedCacheDependency extends CComponent implements ICacheDependency
|
||||
{
|
||||
private $_dependencies=null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param array $dependencies the dependencies to be added to this chain.
|
||||
* @since 1.1.4
|
||||
*/
|
||||
public function __construct($dependencies=array())
|
||||
{
|
||||
if(!empty($dependencies))
|
||||
$this->setDependencies($dependencies);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CTypedList list of dependency objects
|
||||
*/
|
||||
public function getDependencies()
|
||||
{
|
||||
if($this->_dependencies===null)
|
||||
$this->_dependencies=new CTypedList('ICacheDependency');
|
||||
return $this->_dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $values list of dependency objects or configurations to be added to this chain.
|
||||
* If a dependency is specified as a configuration, it must be an array that can be recognized
|
||||
* by {@link YiiBase::createComponent}.
|
||||
*/
|
||||
public function setDependencies($values)
|
||||
{
|
||||
$dependencies=$this->getDependencies();
|
||||
foreach($values as $value)
|
||||
{
|
||||
if(is_array($value))
|
||||
$value=Yii::createComponent($value);
|
||||
$dependencies->add($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the dependency by generating and saving the data related with dependency.
|
||||
*/
|
||||
public function evaluateDependency()
|
||||
{
|
||||
if($this->_dependencies!==null)
|
||||
{
|
||||
foreach($this->_dependencies as $dependency)
|
||||
$dependency->evaluateDependency();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the actual dependency checking.
|
||||
* This method returns true if any of the dependency objects
|
||||
* reports a dependency change.
|
||||
* @return boolean whether the dependency is changed or not.
|
||||
*/
|
||||
public function getHasChanged()
|
||||
{
|
||||
if($this->_dependencies!==null)
|
||||
{
|
||||
foreach($this->_dependencies as $dependency)
|
||||
if($dependency->getHasChanged())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
112
framework/caching/dependencies/CDbCacheDependency.php
Normal file
112
framework/caching/dependencies/CDbCacheDependency.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* CDbCacheDependency class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CDbCacheDependency represents a dependency based on the query result of a SQL statement.
|
||||
*
|
||||
* If the query result (a scalar) changes, the dependency is considered as changed.
|
||||
* To specify the SQL statement, set {@link sql} property.
|
||||
* The {@link connectionID} property specifies the ID of a {@link CDbConnection} application
|
||||
* component. It is this DB connection that is used to perform the query.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching.dependencies
|
||||
* @since 1.0
|
||||
*/
|
||||
class CDbCacheDependency extends CCacheDependency
|
||||
{
|
||||
/**
|
||||
* @var string the ID of a {@link CDbConnection} application component. Defaults to 'db'.
|
||||
*/
|
||||
public $connectionID='db';
|
||||
/**
|
||||
* @var string the SQL statement whose result is used to determine if the dependency has been changed.
|
||||
* Note, the SQL statement should return back a single value.
|
||||
*/
|
||||
public $sql;
|
||||
/**
|
||||
* @var array parameters (name=>value) to be bound to the SQL statement specified by {@link sql}.
|
||||
* @since 1.1.4
|
||||
*/
|
||||
public $params;
|
||||
|
||||
private $_db;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param string $sql the SQL statement whose result is used to determine if the dependency has been changed.
|
||||
*/
|
||||
public function __construct($sql=null)
|
||||
{
|
||||
$this->sql=$sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP sleep magic method.
|
||||
* This method ensures that the database instance is set null because it contains resource handles.
|
||||
* @return array
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
$this->_db=null;
|
||||
return array_keys((array)$this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the data needed to determine if dependency has been changed.
|
||||
* This method returns the value of the global state.
|
||||
* @throws CException if {@link sql} is empty
|
||||
* @return mixed the data needed to determine if dependency has been changed.
|
||||
*/
|
||||
protected function generateDependentData()
|
||||
{
|
||||
if($this->sql!==null)
|
||||
{
|
||||
$db=$this->getDbConnection();
|
||||
$command=$db->createCommand($this->sql);
|
||||
if(is_array($this->params))
|
||||
{
|
||||
foreach($this->params as $name=>$value)
|
||||
$command->bindValue($name,$value);
|
||||
}
|
||||
if($db->queryCachingDuration>0)
|
||||
{
|
||||
// temporarily disable and re-enable query caching
|
||||
$duration=$db->queryCachingDuration;
|
||||
$db->queryCachingDuration=0;
|
||||
$result=$command->queryRow();
|
||||
$db->queryCachingDuration=$duration;
|
||||
}
|
||||
else
|
||||
$result=$command->queryRow();
|
||||
return $result;
|
||||
}
|
||||
else
|
||||
throw new CException(Yii::t('yii','CDbCacheDependency.sql cannot be empty.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CDbConnection the DB connection instance
|
||||
* @throws CException if {@link connectionID} does not point to a valid application component.
|
||||
*/
|
||||
protected function getDbConnection()
|
||||
{
|
||||
if($this->_db!==null)
|
||||
return $this->_db;
|
||||
else
|
||||
{
|
||||
if(($this->_db=Yii::app()->getComponent($this->connectionID)) instanceof CDbConnection)
|
||||
return $this->_db;
|
||||
else
|
||||
throw new CException(Yii::t('yii','CDbCacheDependency.connectionID "{id}" is invalid. Please make sure it refers to the ID of a CDbConnection application component.',
|
||||
array('{id}'=>$this->connectionID)));
|
||||
}
|
||||
}
|
||||
}
|
||||
135
framework/caching/dependencies/CDirectoryCacheDependency.php
Normal file
135
framework/caching/dependencies/CDirectoryCacheDependency.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* CDirectoryCacheDependency class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CDirectoryCacheDependency represents a dependency based on change of a directory.
|
||||
*
|
||||
* CDirectoryCacheDependency performs dependency checking based on the
|
||||
* modification time of the files contained in the specified directory.
|
||||
* The directory being checked is specified via {@link directory}.
|
||||
*
|
||||
* By default, all files under the specified directory and subdirectories
|
||||
* will be checked. If the last modification time of any of them is changed
|
||||
* or if different number of files are contained in a directory, the dependency
|
||||
* is reported as changed. By specifying {@link recursiveLevel},
|
||||
* one can limit the checking to a certain depth of the directory.
|
||||
*
|
||||
* Note, dependency checking for a directory is expensive because it involves
|
||||
* accessing modification time of multiple files under the directory.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching.dependencies
|
||||
* @since 1.0
|
||||
*/
|
||||
class CDirectoryCacheDependency extends CCacheDependency
|
||||
{
|
||||
/**
|
||||
* @var string the directory whose change is used to determine if the dependency has been changed.
|
||||
* If any of the files under the directory is changed, the dependency is considered as changed.
|
||||
*/
|
||||
public $directory;
|
||||
/**
|
||||
* @var integer the depth of the subdirectories to be recursively checked.
|
||||
* If the value is less than 0, it means unlimited depth.
|
||||
* If the value is 0, it means checking the files directly under the specified directory.
|
||||
*/
|
||||
public $recursiveLevel=-1;
|
||||
/**
|
||||
* @var string the regular expression matching valid file/directory names.
|
||||
* Only the matching files or directories will be checked for changes.
|
||||
* Defaults to null, meaning all files/directories will qualify.
|
||||
*/
|
||||
public $namePattern;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param string $directory the directory to be checked
|
||||
*/
|
||||
public function __construct($directory=null)
|
||||
{
|
||||
$this->directory=$directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the data needed to determine if dependency has been changed.
|
||||
* This method returns the modification timestamps for files under the directory.
|
||||
* @throws CException if {@link directory} is empty
|
||||
* @return mixed the data needed to determine if dependency has been changed.
|
||||
*/
|
||||
protected function generateDependentData()
|
||||
{
|
||||
if($this->directory!==null)
|
||||
return $this->generateTimestamps($this->directory);
|
||||
else
|
||||
throw new CException(Yii::t('yii','CDirectoryCacheDependency.directory cannot be empty.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the last modification time for files under the directory.
|
||||
* This method may go recursively into subdirectories if {@link recursiveLevel} is not 0.
|
||||
* @param string $directory the directory name
|
||||
* @param integer $level level of the recursion
|
||||
* @throws CException if given directory is not valid
|
||||
* @return array list of file modification time indexed by the file path
|
||||
*/
|
||||
protected function generateTimestamps($directory,$level=0)
|
||||
{
|
||||
if(($dir=@opendir($directory))===false)
|
||||
throw new CException(Yii::t('yii','"{path}" is not a valid directory.',
|
||||
array('{path}'=>$directory)));
|
||||
$timestamps=array();
|
||||
while(($file=readdir($dir))!==false)
|
||||
{
|
||||
$path=$directory.DIRECTORY_SEPARATOR.$file;
|
||||
if($file==='.' || $file==='..')
|
||||
continue;
|
||||
if($this->namePattern!==null && !preg_match($this->namePattern,$file))
|
||||
continue;
|
||||
if(is_file($path))
|
||||
{
|
||||
if($this->validateFile($path))
|
||||
$timestamps[$path]=filemtime($path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(($this->recursiveLevel<0 || $level<$this->recursiveLevel) && $this->validateDirectory($path))
|
||||
$timestamps=array_merge($timestamps, $this->generateTimestamps($path,$level+1));
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
return $timestamps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the file should be checked for dependency.
|
||||
* This method is invoked when dependency of the whole directory is being checked.
|
||||
* By default, it always returns true, meaning the file should be checked.
|
||||
* You may override this method to check only certain files.
|
||||
* @param string $fileName the name of the file that may be checked for dependency.
|
||||
* @return boolean whether this file should be checked.
|
||||
*/
|
||||
protected function validateFile($fileName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the specified subdirectory should be checked for dependency.
|
||||
* This method is invoked when dependency of the whole directory is being checked.
|
||||
* By default, it always returns true, meaning the subdirectory should be checked.
|
||||
* You may override this method to check only certain subdirectories.
|
||||
* @param string $directory the name of the subdirectory that may be checked for dependency.
|
||||
* @return boolean whether this subdirectory should be checked.
|
||||
*/
|
||||
protected function validateDirectory($directory)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
55
framework/caching/dependencies/CExpressionDependency.php
Normal file
55
framework/caching/dependencies/CExpressionDependency.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* CExpressionDependency class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CExpressionDependency represents a dependency based on the result of a PHP expression.
|
||||
*
|
||||
* CExpressionDependency performs dependency checking based on the
|
||||
* result of a PHP {@link expression}.
|
||||
* The dependency is reported as unchanged if and only if the result is
|
||||
* the same as the one evaluated when storing the data to cache.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching.dependencies
|
||||
* @since 1.0
|
||||
*/
|
||||
class CExpressionDependency extends CCacheDependency
|
||||
{
|
||||
/**
|
||||
* @var string the PHP expression whose result is used to determine the dependency.
|
||||
* The expression can also be a valid serializable PHP callback.
|
||||
* It will be passed with a parameter which is the dependency object itself.
|
||||
*
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*/
|
||||
public $expression;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param string $expression the PHP expression whose result is used to determine the dependency.
|
||||
*/
|
||||
public function __construct($expression='true')
|
||||
{
|
||||
$this->expression=$expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the data needed to determine if dependency has been changed.
|
||||
* This method returns the result of the PHP expression.
|
||||
* @return mixed the data needed to determine if dependency has been changed.
|
||||
*/
|
||||
protected function generateDependentData()
|
||||
{
|
||||
return $this->evaluateExpression($this->expression);
|
||||
}
|
||||
}
|
||||
53
framework/caching/dependencies/CFileCacheDependency.php
Normal file
53
framework/caching/dependencies/CFileCacheDependency.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* CFileCacheDependency class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CFileCacheDependency represents a dependency based on a file's last modification time.
|
||||
*
|
||||
* CFileCacheDependency performs dependency checking based on the
|
||||
* last modification time of the file specified via {@link fileName}.
|
||||
* The dependency is reported as unchanged if and only if the file's
|
||||
* last modification time remains unchanged.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching.dependencies
|
||||
* @since 1.0
|
||||
*/
|
||||
class CFileCacheDependency extends CCacheDependency
|
||||
{
|
||||
/**
|
||||
* @var string the name of the file whose last modification time is used to
|
||||
* check if the dependency has been changed.
|
||||
*/
|
||||
public $fileName;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param string $fileName name of the file whose change is to be checked.
|
||||
*/
|
||||
public function __construct($fileName=null)
|
||||
{
|
||||
$this->fileName=$fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the data needed to determine if dependency has been changed.
|
||||
* This method returns the file's last modification time.
|
||||
* @throws CException if {@link fileName} is empty
|
||||
* @return mixed the data needed to determine if dependency has been changed.
|
||||
*/
|
||||
protected function generateDependentData()
|
||||
{
|
||||
if($this->fileName!==null)
|
||||
return @filemtime($this->fileName);
|
||||
else
|
||||
throw new CException(Yii::t('yii','CFileCacheDependency.fileName cannot be empty.'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* CGlobalStateCacheDependency class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CGlobalStateCacheDependency represents a dependency based on a global state value.
|
||||
*
|
||||
* CGlobalStateCacheDependency checks if a global state is changed or not.
|
||||
* If the global state is changed, the dependency is reported as changed.
|
||||
* To specify which global state this dependency should check with,
|
||||
* set {@link stateName} to the name of the global state.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package system.caching.dependencies
|
||||
* @since 1.0
|
||||
*/
|
||||
class CGlobalStateCacheDependency extends CCacheDependency
|
||||
{
|
||||
/**
|
||||
* @var string the name of the global state whose value is to check
|
||||
* if the dependency has changed.
|
||||
* @see CApplication::setGlobalState
|
||||
*/
|
||||
public $stateName;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param string $name the name of the global state
|
||||
*/
|
||||
public function __construct($name=null)
|
||||
{
|
||||
$this->stateName=$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the data needed to determine if dependency has been changed.
|
||||
* This method returns the value of the global state.
|
||||
* @throws CException if {@link stateName} is empty
|
||||
* @return mixed the data needed to determine if dependency has been changed.
|
||||
*/
|
||||
protected function generateDependentData()
|
||||
{
|
||||
if($this->stateName!==null)
|
||||
return Yii::app()->getGlobalState($this->stateName);
|
||||
else
|
||||
throw new CException(Yii::t('yii','CGlobalStateCacheDependency.stateName cannot be empty.'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user