You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

239 lines
7.0 KiB

<?php
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
/**
* Class Memcachelib
*
* Simple central point for configuring and using memcache support.
*
* This utility library is not a complete wrapper for PHP memcache functions,
* and only provides a minimal set currently in use in SUMO.
*/
class Memcachelib
{
public $memcache;
public $options;
/**
* Memcachelib constructor.
* @param bool $memcached_servers
* @param bool $memcached_options
*/
public function __construct($memcached_servers = false, $memcached_options = false)
{
global $prefs, $tikidomainslash;
if ($memcached_servers === false && $memcached_options === false) {
if (is_array($prefs['memcache_servers'])) {
$memcached_servers = $prefs['memcache_servers'];
} else {
$memcached_servers = unserialize($prefs['memcache_servers']);
}
$memcached_options = [
'enabled' => true,
'expiration' => (int) $prefs['memcache_expiration'],
'key_prefix' => $prefs['memcache_prefix'],
];
}
$localphp = "db/{$tikidomainslash}local.php";
if (is_readable($localphp)) {
// Should be defined by unserializing $prefs['memcache_options']
// and $prefs['memcache_servers']. Currently happens in
// /webroot/tiki-setup_base.php
// preferences are overwritten in local.php (if defined)
require($localphp);
}
if (! $memcached_servers || (! empty($memcached_options) && ! $memcached_options['enabled']) || ! class_exists('Memcached')) {
$this->memcache = false;
$this->options = [ 'enabled' => false ];
} else {
$memcached_options['flags'] = 0;
$this->options = $memcached_options;
$this->memcache = new Memcached();
foreach ($memcached_servers as $server) {
if ($server['host'] == 'localhost') {
$server['host'] = '127.0.0.1';
}
$this->memcache->addServer(
$server['host'],
(int) $server['port'],
isset($server['weight']) ? (int)$server['weight'] : 1
);
}
}
$this->key_prefix = $this->getOption('key_prefix', '');
}
/**
* Return a reference to the memcache object.
* @return object
*/
public function getMemcache()
{
return $this->memcache;
}
/**
* Get an option, with default.
* @param string $name of the option
* @param mixed $default value
* @return mixed value of the option, or default.
*/
public function getOption($name, $default = null)
{
return isset($this->options[$name]) ?
$this->options[$name] : $default;
}
/**
* Return whether this thing is usable.
* @return boolean
*/
public function isEnabled()
{
global $prefs;
if (isset($prefs['memcache_enabled']) && $prefs['memcache_enabled'] == 'y') {
return $this->memcache && $this->getOption('enabled', false);
} else {
return false;
}
}
/**
* Get a key from memcache
*
* @param mixed $key, passed through buildKey() before use
* @param mixed $default value returned if result from memcache is NULL
* @return mixed Value from memcache, or the default
*/
public function get($key, $default = null)
{
$key = $this->buildKey($key);
$val = $this->memcache->get($key);
return ($val !== null) ? $val : $default;
}
/**
* Get multiple keys from memcache at once.
*
* This differs from native memcache get() behavior in that all keys
* passed in will result in a corresponding value returned. If the
* key was not found in the cache, the returned value will be NULL.
*
* @param array $keys, each will be passed through buildKey() before use
* @return array Values, in order of keys passed.
*/
public function getMulti($keys)
{
// Run each key passed in through the buildKey() method.
$keys_built = [];
foreach ($keys as $key) {
$keys_built[] = $this->buildKey($key);
}
// Fetch the assoc array of keys/values available in memcache.
$values_in = $this->memcache->get($keys_built);
// Construct a list of values corresponding to the keys passed in.
$values_out = [];
foreach ($keys_built as $kb) {
$values_out[] = (isset($values_in[$kb])) ? $values_in[$kb] : null;
}
return $values_out;
}
/**
* Set a key in memcache
* @param mixed $key, passed through buildKey() before use
* @param mixed $value
* @param bool $flags Optional memcache flags
* @param bool $expiration Optional expiration time
* @return bool
*/
public function set($key, $value, $flags = false, $expiration = false)
{
$key = $this->buildKey($key);
$expiration = ($expiration) ?
$expiration : $this->getOption('expiration', 0);
if (! empty($this->memcache) && method_exists($this->memcache, "set")) {
return $this->memcache->set($key, $value, $expiration);
}
}
/**
* Delete a key in memcache
*
* @param $key, passed through buildKey() before use
* @return bool
*/
public function delete($key)
{
$key = $this->buildKey($key);
return $this->memcache->delete($key);
}
/**
* Flush the memcache cache
*/
public function flush()
{
return $this->memcache->flush();
}
/**
* Build a cache key from a given parameter
*
* @param mixed A string, or an object to be turned into a key.
* @return string The cache key.
*/
/**
* Build a cache key from a given parameter
*
* @param mixed $key a string, or an object to be turned into a key
* @param bool $use_md5
* @return string the cache key
*/
public function buildKey($key, $use_md5 = false)
{
if (is_string($key)) {
return (strpos($key, $this->key_prefix) !== 0) ?
$this->key_prefix . $key : $key;
}
if (is_array($key)) {
$keys = array_keys($key);
sort($keys);
$parts = [];
foreach ($keys as $name) {
$val = $key[$name];
if ($val !== null) {
$parts[] = $name . '=' . $val;
}
}
$str_key = join(':', $parts);
return $this->key_prefix .
( $use_md5 ? md5($str_key) : '[' . $str_key . ']' );
}
}
}