Commit 06235cd1 by Qiang Xue

Fixes #2558: Enhanced support for memcached by adding…

Fixes #2558: Enhanced support for memcached by adding `yii\caching\MemCache::persistentId` and `yii\caching\MemCache::options`
parent 91caf681
...@@ -59,6 +59,7 @@ Yii Framework 2 Change Log ...@@ -59,6 +59,7 @@ Yii Framework 2 Change Log
- Bug: Fixed Object of class Imagick could not be converted to string in CaptchaAction (eXprojects, cebe) - Bug: Fixed Object of class Imagick could not be converted to string in CaptchaAction (eXprojects, cebe)
- Enh #2264: `CookieCollection::has()` will return false for expired or removed cookies (qiangxue) - Enh #2264: `CookieCollection::has()` will return false for expired or removed cookies (qiangxue)
- Enh #2435: `yii\db\IntegrityException` is now thrown on database integrity errors instead of general `yii\db\Exception` (samdark) - Enh #2435: `yii\db\IntegrityException` is now thrown on database integrity errors instead of general `yii\db\Exception` (samdark)
- Enh #2558: Enhanced support for memcached by adding `yii\caching\MemCache::persistentId` and `yii\caching\MemCache::options` (qiangxue)
- Enh #2837: Error page now shows arguments in stack trace method calls (samdark) - Enh #2837: Error page now shows arguments in stack trace method calls (samdark)
- Enh #2906: Added support for using conditional comments for js and css files registered through asset bundles and Html helper (exromany, qiangxue) - Enh #2906: Added support for using conditional comments for js and css files registered through asset bundles and Html helper (exromany, qiangxue)
- Enh #2942: Added truncate and truncateWord methods (Alex-Code, samdark) - Enh #2942: Added truncate and truncateWord methods (Alex-Code, samdark)
......
...@@ -70,6 +70,19 @@ class MemCache extends Cache ...@@ -70,6 +70,19 @@ class MemCache extends Cache
*/ */
public $useMemcached = false; public $useMemcached = false;
/** /**
* @var string an ID that identifies a Memcached instance. This property is used only when [[useMemcached]] is true.
* By default the Memcached instances are destroyed at the end of the request. To create an instance that
* persists between requests, you may specify a unique ID for the instance. All instances created with the
* same ID will share the same connection.
* @see http://ca2.php.net/manual/en/memcached.construct.php
*/
public $persistentId;
/**
* @var array options for Memcached. This property is used only when [[useMemcached]] is true.
* @see http://ca2.php.net/manual/en/memcached.setoptions.php
*/
public $options;
/**
* @var \Memcache|\Memcached the Memcache instance * @var \Memcache|\Memcached the Memcache instance
*/ */
private $_cache = null; private $_cache = null;
...@@ -86,24 +99,64 @@ class MemCache extends Cache ...@@ -86,24 +99,64 @@ class MemCache extends Cache
public function init() public function init()
{ {
parent::init(); parent::init();
$servers = $this->getServers(); $this->addServers($this->getMemcache(), $this->getServers());
$cache = $this->getMemCache(); }
/**
* @param \Memcache|\Memcached $cache
* @param array $servers
* @throws InvalidConfigException
*/
protected function addServers($cache, $servers)
{
if (empty($servers)) { if (empty($servers)) {
$cache->addServer('127.0.0.1', 11211); $servers = [new MemCacheServer([
'host' => '127.0.0.1',
'port' => 11211,
])];
} else { } else {
if (!$this->useMemcached) {
// different version of memcache may have different number of parameters for the addServer method.
$class = new \ReflectionClass($cache);
$paramCount = $class->getMethod('addServer')->getNumberOfParameters();
}
foreach ($servers as $server) { foreach ($servers as $server) {
if ($server->host === null) { if ($server->host === null) {
throw new InvalidConfigException("The 'host' property must be specified for every memcache server."); throw new InvalidConfigException("The 'host' property must be specified for every memcache server.");
} }
}
}
if ($this->useMemcached) { if ($this->useMemcached) {
$cache->addServer($server->host, $server->port, $server->weight); $this->addMemcachedServers($cache, $servers);
} else { } else {
// $timeout is used for memcache versions that do not have timeoutms parameter $this->addMemcacheServers($cache, $servers);
}
}
/**
* @param \Memcached $cache
* @param array $servers
*/
protected function addMemcachedServers($cache, $servers)
{
$existingServers = [];
if ($this->persistentId !== null) {
foreach ($cache->getServerList() as $s) {
$existingServers[$s['host'] . ':' . $s['port']] = true;
}
}
foreach ($servers as $server) {
if (empty($existingServers) || !isset($existingServers[$server->host . ':' . $server->port])) {
$cache->addServer($server->host, $server->port, $server->weight);
}
}
}
/**
* @param \Memcache $cache
* @param array $servers
*/
protected function addMemcacheServers($cache, $servers)
{
$class = new \ReflectionClass($cache);
$paramCount = $class->getMethod('addServer')->getNumberOfParameters();
foreach ($servers as $server) {
// $timeout is used for memcache versions that do not have $timeoutms parameter
$timeout = (int) ($server->timeout / 1000) + (($server->timeout % 1000 > 0) ? 1 : 0); $timeout = (int) ($server->timeout / 1000) + (($server->timeout % 1000 > 0) ? 1 : 0);
if ($paramCount === 9) { if ($paramCount === 9) {
$cache->addServer( $cache->addServer(
...@@ -131,8 +184,6 @@ class MemCache extends Cache ...@@ -131,8 +184,6 @@ class MemCache extends Cache
} }
} }
} }
}
}
/** /**
* Returns the underlying memcache (or memcached) object. * Returns the underlying memcache (or memcached) object.
...@@ -146,14 +197,22 @@ class MemCache extends Cache ...@@ -146,14 +197,22 @@ class MemCache extends Cache
if (!extension_loaded($extension)) { if (!extension_loaded($extension)) {
throw new InvalidConfigException("MemCache requires PHP $extension extension to be loaded."); throw new InvalidConfigException("MemCache requires PHP $extension extension to be loaded.");
} }
$this->_cache = $this->useMemcached ? new \Memcached : new \Memcache;
if ($this->useMemcached) {
$this->_cache = $this->persistentId !== null ? new \Memcached($this->persistentId) : new \Memcached;
if (!empty($this->options)) {
$this->_cache->setOptions($this->options);
}
} else {
$this->_cache = new \Memcache;
}
} }
return $this->_cache; return $this->_cache;
} }
/** /**
* Returns the memcache server configurations. * Returns the memcache or memcached server configurations.
* @return MemCacheServer[] list of memcache server configurations. * @return MemCacheServer[] list of memcache server configurations.
*/ */
public function getServers() public function getServers()
...@@ -162,9 +221,10 @@ class MemCache extends Cache ...@@ -162,9 +221,10 @@ class MemCache extends Cache
} }
/** /**
* @param array $config list of memcache server configurations. Each element must be an array * @param array $config list of memcache or memcached server configurations. Each element must be an array
* with the following keys: host, port, persistent, weight, timeout, retryInterval, status. * with the following keys: host, port, persistent, weight, timeout, retryInterval, status.
* @see http://www.php.net/manual/en/function.Memcache-addServer.php * @see http://php.net/manual/en/memcache.addserver.php
* @see http://php.net/manual/en/memcached.addserver.php
*/ */
public function setServers($config) public function setServers($config)
{ {
......
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