Commit f5d0bcbc by Qiang Xue

Refactored cache key generation.

parent f17fde4a
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
namespace yii\caching; namespace yii\caching;
use Yii;
use yii\base\Component; use yii\base\Component;
use yii\base\InvalidConfigException;
use yii\helpers\StringHelper; use yii\helpers\StringHelper;
/** /**
...@@ -52,10 +54,12 @@ use yii\helpers\StringHelper; ...@@ -52,10 +54,12 @@ use yii\helpers\StringHelper;
abstract class Cache extends Component implements \ArrayAccess abstract class Cache extends Component implements \ArrayAccess
{ {
/** /**
* @var string a string prefixed to every cache key so that it is unique. Defaults to null, meaning using * @var string a string prefixed to every cache key so that it is unique. If not set,
* the value of [[Application::id]] as the key prefix. You may set this property to be an empty string * it will use a prefix generated from [[Application::id]]. You may set this property to be an empty string
* if you don't want to use key prefix. It is recommended that you explicitly set this property to some * if you don't want to use key prefix. It is recommended that you explicitly set this property to some
* static value if the cached data needs to be shared among multiple applications. * static value if the cached data needs to be shared among multiple applications.
*
* To ensure interoperability, only use alphanumeric characters should be used.
*/ */
public $keyPrefix; public $keyPrefix;
/** /**
...@@ -78,18 +82,18 @@ abstract class Cache extends Component implements \ArrayAccess ...@@ -78,18 +82,18 @@ abstract class Cache extends Component implements \ArrayAccess
{ {
parent::init(); parent::init();
if ($this->keyPrefix === null) { if ($this->keyPrefix === null) {
$this->keyPrefix = \Yii::$app->id; $this->keyPrefix = substr(md5(Yii::$app->id), 0, 5);
} elseif (!ctype_alnum($this->keyPrefix)) {
throw new InvalidConfigException(get_class($this) . '::keyPrefix should only contain alphanumeric characters.');
} }
} }
/** /**
* Builds a normalized cache key from a given key. * Builds a normalized cache key from a given key.
* *
* The generated key contains letters and digits only, and its length is no more than 32.
*
* If the given key is a string containing alphanumeric characters only and no more than 32 characters, * If the given key is a string containing alphanumeric characters only and no more than 32 characters,
* then the key will be returned back without change. Otherwise, a normalized key * then the key will be returned back prefixed with [[keyPrefix]]. Otherwise, a normalized key
* is generated by serializing the given key and applying MD5 hashing. * is generated by serializing the given key, applying MD5 hashing, and prefixing with [[keyPrefix]].
* *
* The following example builds a cache key using three parameters: * The following example builds a cache key using three parameters:
* *
...@@ -97,8 +101,8 @@ abstract class Cache extends Component implements \ArrayAccess ...@@ -97,8 +101,8 @@ abstract class Cache extends Component implements \ArrayAccess
* $key = $cache->buildKey(array($className, $method, $id)); * $key = $cache->buildKey(array($className, $method, $id));
* ~~~ * ~~~
* *
* @param array|string $key the key to be normalized * @param mixed $key the key to be normalized
* @return string the generated cache key include $this->keyPrefix * @return string the generated cache key
*/ */
public function buildKey($key) public function buildKey($key)
{ {
......
...@@ -391,12 +391,12 @@ class Command extends \yii\base\Component ...@@ -391,12 +391,12 @@ class Command extends \yii\base\Component
} }
if (isset($cache) && $cache instanceof Cache) { if (isset($cache) && $cache instanceof Cache) {
$cacheKey = $cache->buildKey(array( $cacheKey = array(
__CLASS__, __CLASS__,
$db->dsn, $db->dsn,
$db->username, $db->username,
$rawSql, $rawSql,
)); );
if (($result = $cache->get($cacheKey)) !== false) { if (($result = $cache->get($cacheKey)) !== false) {
Yii::trace('Query result served from cache', __METHOD__); Yii::trace('Query result served from cache', __METHOD__);
return $result; return $result;
......
...@@ -89,7 +89,7 @@ abstract class Schema extends \yii\base\Object ...@@ -89,7 +89,7 @@ abstract class Schema extends \yii\base\Object
/** @var $cache Cache */ /** @var $cache Cache */
$cache = is_string($db->schemaCache) ? Yii::$app->getComponent($db->schemaCache) : $db->schemaCache; $cache = is_string($db->schemaCache) ? Yii::$app->getComponent($db->schemaCache) : $db->schemaCache;
if ($cache instanceof Cache) { if ($cache instanceof Cache) {
$key = $this->getCacheKey($cache, $name); $key = $this->getCacheKey($name);
if ($refresh || ($table = $cache->get($key)) === false) { if ($refresh || ($table = $cache->get($key)) === false) {
$table = $this->loadTableSchema($realName); $table = $this->loadTableSchema($realName);
if ($table !== null) { if ($table !== null) {
...@@ -104,18 +104,17 @@ abstract class Schema extends \yii\base\Object ...@@ -104,18 +104,17 @@ abstract class Schema extends \yii\base\Object
/** /**
* Returns the cache key for the specified table name. * Returns the cache key for the specified table name.
* @param Cache $cache the cache component
* @param string $name the table name * @param string $name the table name
* @return string the cache key * @return mixed the cache key
*/ */
public function getCacheKey($cache, $name) public function getCacheKey($name)
{ {
return $cache->buildKey(array( return array(
__CLASS__, __CLASS__,
$this->db->dsn, $this->db->dsn,
$this->db->username, $this->db->username,
$name, $name,
)); );
} }
/** /**
...@@ -178,7 +177,7 @@ abstract class Schema extends \yii\base\Object ...@@ -178,7 +177,7 @@ abstract class Schema extends \yii\base\Object
$cache = is_string($this->db->schemaCache) ? Yii::$app->getComponent($this->db->schemaCache) : $this->db->schemaCache; $cache = is_string($this->db->schemaCache) ? Yii::$app->getComponent($this->db->schemaCache) : $this->db->schemaCache;
if ($this->db->enableSchemaCache && $cache instanceof Cache) { if ($this->db->enableSchemaCache && $cache instanceof Cache) {
foreach ($this->_tables as $name => $table) { foreach ($this->_tables as $name => $table) {
$cache->delete($this->getCacheKey($cache, $name)); $cache->delete($this->getCacheKey($name));
} }
} }
$this->_tableNames = array(); $this->_tableNames = array();
......
...@@ -97,10 +97,10 @@ class CacheSession extends Session ...@@ -97,10 +97,10 @@ class CacheSession extends Session
/** /**
* Generates a unique key used for storing session data in cache. * Generates a unique key used for storing session data in cache.
* @param string $id session variable name * @param string $id session variable name
* @return string a safe cache key associated with the session variable name * @return mixed a safe cache key associated with the session variable name
*/ */
protected function calculateKey($id) protected function calculateKey($id)
{ {
return $this->cache->buildKey(array(__CLASS__, $id)); return array(__CLASS__, $id);
} }
} }
...@@ -103,7 +103,7 @@ class UrlManager extends Component ...@@ -103,7 +103,7 @@ class UrlManager extends Component
$this->cache = Yii::$app->getComponent($this->cache); $this->cache = Yii::$app->getComponent($this->cache);
} }
if ($this->cache instanceof Cache) { if ($this->cache instanceof Cache) {
$key = $this->cache->buildKey(__CLASS__); $key = __CLASS__;
$hash = md5(json_encode($this->rules)); $hash = md5(json_encode($this->rules));
if (($data = $this->cache->get($key)) !== false && isset($data[1]) && $data[1] === $hash) { if (($data = $this->cache->get($key)) !== false && isset($data[1]) && $data[1] === $hash) {
$this->rules = $data[0]; $this->rules = $data[0];
......
...@@ -159,7 +159,7 @@ class FragmentCache extends Widget ...@@ -159,7 +159,7 @@ class FragmentCache extends Widget
/** /**
* Generates a unique key used for storing the content in cache. * Generates a unique key used for storing the content in cache.
* The key generated depends on both [[id]] and [[variations]]. * The key generated depends on both [[id]] and [[variations]].
* @return string a valid cache key * @return mixed a valid cache key
*/ */
protected function calculateKey() protected function calculateKey()
{ {
...@@ -169,6 +169,6 @@ class FragmentCache extends Widget ...@@ -169,6 +169,6 @@ class FragmentCache extends Widget
$factors[] = $factor; $factors[] = $factor;
} }
} }
return $this->cache->buildKey($factors); return $factors;
} }
} }
...@@ -65,7 +65,7 @@ abstract class CacheTestCase extends TestCase ...@@ -65,7 +65,7 @@ abstract class CacheTestCase extends TestCase
{ {
$cache = $this->getCacheInstance(); $cache = $this->getCacheInstance();
$this->assertNotNull(\Yii::$app->id); $this->assertNotNull(\Yii::$app->id);
$this->assertEquals(\Yii::$app->id, $cache->keyPrefix); $this->assertNotNull($cache->keyPrefix);
} }
public function testSet() public function testSet()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment