File: /www/sites/cbgdh_com/index/wp-content/themes/onenav/templates/object-cache.php
<?php
/**
* Memcached Object Cache
*
在PHP中安装了 Memcached 扩展,然后复制此文件到 wp-content 目录下,WordPress 将使用 Memcached 作为对象缓存。
*
* @package WordPress
*/
if (isset($_GET['debug']) && $_GET['debug'] == 'sql') {
return;
}
// 如果多个安装程序共用一个 wp-config.php 或 $table_prefix,
// 用户可以使用此功能来保证此对象缓存生成的密钥的唯一性。
if (!defined('WP_CACHE_KEY_SALT')) {
if (isset($table_prefix) && !empty($table_prefix)) {
define('WP_CACHE_KEY_SALT', $table_prefix);
} else {
define('WP_CACHE_KEY_SALT', md5(__FILE__));
}
}
if (class_exists('Memcached')) {
function wp_cache_add($key, $data, $group = '', $expire = 0)
{
global $wp_object_cache;
return $wp_object_cache->add($key, $data, $group, (int) $expire);
}
function wp_cache_cas($cas_token, $key, $data, $group = '', $expire = 0)
{
global $wp_object_cache;
return $wp_object_cache->cas($cas_token, $key, $data, $group, (int) $expire);
}
function wp_cache_close()
{
global $wp_object_cache;
return $wp_object_cache->close();
}
function wp_cache_decr($key, $offset = 1, $group = '', $initial_value = 0, $expire = 0)
{
global $wp_object_cache;
return $wp_object_cache->decr($key, $offset, $group, $initial_value, $expire);
}
function wp_cache_delete($key, $group = '')
{
global $wp_object_cache;
return $wp_object_cache->delete($key, $group);
}
function wp_cache_flush()
{
global $wp_object_cache;
return $wp_object_cache->flush();
}
function wp_cache_get($key, $group = '', $force = false, &$found = null)
{
global $wp_object_cache;
return $wp_object_cache->get($key, $group, $force, $found);
}
function wp_cache_get_multiple($keys, $group = '', $force = false)
{
global $wp_object_cache;
return $wp_object_cache->get_multiple($keys, $group, $force);
}
function wp_cache_set_multiple($data, $group = '', $expire = 0)
{
global $wp_object_cache;
return $wp_object_cache->set_multiple($data, $group, $expire);
}
function wp_cache_delete_multiple($keys, $group = '')
{
global $wp_object_cache;
return $wp_object_cache->delete_multiple($keys, $group);
}
function wp_cache_get_with_cas($key, $group = '', &$token = null)
{
global $wp_object_cache;
return $wp_object_cache->get_with_cas($key, $group, $token);
}
function wp_cache_incr($key, $offset = 1, $group = '', $initial_value = 0, $expire = 0)
{
global $wp_object_cache;
return $wp_object_cache->incr($key, $offset, $group, $initial_value, $expire);
}
if (!isset($_GET['debug']) || $_GET['debug'] != 'sql') {
function wp_cache_init()
{
global $wp_object_cache;
$wp_object_cache = new WP_Object_Cache();
}
}
function wp_cache_replace($key, $data, $group = '', $expire = 0)
{
global $wp_object_cache;
return $wp_object_cache->replace($key, $data, $group, (int) $expire);
}
function wp_cache_set($key, $data, $group = '', $expire = 0)
{
global $wp_object_cache;
return $wp_object_cache->set($key, $data, $group, (int) $expire);
}
function wp_cache_switch_to_blog($blog_id)
{
global $wp_object_cache;
return $wp_object_cache->switch_to_blog($blog_id);
}
function wp_cache_add_global_groups($groups)
{
global $wp_object_cache;
$wp_object_cache->add_global_groups($groups);
}
function wp_cache_add_non_persistent_groups($groups)
{
global $wp_object_cache;
$wp_object_cache->add_non_persistent_groups($groups);
}
function wp_cache_get_stats()
{
global $wp_object_cache;
return $wp_object_cache->get_stats();
}
class WP_Object_Cache
{
private $cache = [];
private $mc = null;
private $blog_prefix;
private $global_prefix;
protected $global_groups = [];
protected $non_persistent_groups = [];
protected function action($action, $id, $group, $data, $expire = 0)
{
if ($this->is_non_persistent_group($group)) {
$internal = $this->internal('get', $id, $group);
if ($action == 'add') {
if ($internal !== false) {
return false;
}
} elseif ($action == 'replace') {
if ($internal === false) {
return false;
}
} elseif ($action == 'increment' || $action == 'decrement') {
$data = $action == 'increment' ? $data : (0 - $data);
$data = (int) $internal + $data;
$data = $data < 0 ? 0 : $data;
}
return $this->internal('add', $id, $group, $data);
} else {
$key = $this->build_key($id, $group);
$expire = (!$expire && strlen($id) > 50) ? DAY_IN_SECONDS : $expire;
if ($action == 'set') {
$result = $this->mc->set($key, $data, $expire);
} elseif ($action == 'add') {
$result = $this->mc->add($key, $data, $expire);
} elseif ($action == 'replace') {
$result = $this->mc->replace($key, $data, $expire);
} elseif ($action == 'increment') {
$result = $data = $this->mc->increment($key, $data);
} elseif ($action == 'decrement') {
$result = $data = $this->mc->decrement($key, $data);
}
$code = $this->mc->getResultCode();
if ($code === Memcached::RES_SUCCESS) {
$this->internal('add', $id, $group, $data);
} else {
$this->internal('del', $id, $group);
if ($code != Memcached::RES_NOTSTORED) {
// trigger_error($code.' '.var_export($result, true).' '.var_export($key, true));
}
}
return $result;
}
}
protected function internal($action, $id, $group, $data = null)
{
$group = $this->parse_group($group);
if ($action == 'get') {
$data = $this->cache[$group][$id] ?? false;
return is_object($data) ? clone $data : $data;
} elseif ($action == 'add') {
$this->cache[$group][$id] = is_object($data) ? clone $data : $data;
return true;
} elseif ($action == 'del') {
unset($this->cache[$group][$id]);
}
}
public function add($id, $data, $group = 'default', $expire = 0)
{
if (wp_suspend_cache_addition()) {
return false;
}
return $this->action('add', $id, $group, $data, $expire);
}
public function replace($id, $data, $group = 'default', $expire = 0)
{
return $this->action('replace', $id, $group, $data, $expire);
}
public function set($id, $data, $group = 'default', $expire = 0)
{
return $this->action('set', $id, $group, $data, $expire);
}
public function incr($id, $offset = 1, $group = 'default', $initial_value = 0, $expire = 0)
{
$this->action('add', $id, $group, $initial_value, $expire);
return $this->action('increment', $id, $group, $offset);
}
public function decr($id, $offset = 1, $group = 'default', $initial_value = 0, $expire = 0)
{
$this->action('add', $id, $group, $initial_value, $expire);
return $this->action('decrement', $id, $group, $offset);
}
public function cas($cas_token, $id, $data, $group = 'default', $expire = 0)
{
$this->internal('del', $id, $group);
return $this->mc->cas($cas_token, $this->build_key($id, $group), $data, $expire);
}
public function delete($id, $group = 'default')
{
$this->internal('del', $id, $group);
return $this->is_non_persistent_group($group) ? true : $this->mc->delete($this->build_key($id, $group));
}
public function flush()
{
$this->cache = [];
return $this->mc->flush();
}
public function get($id, $group = 'default', $force = false, &$found = null)
{
$value = $force ? false : $this->internal('get', $id, $group);
$found = $value !== false;
if (!$found && !$this->is_non_persistent_group($group)) {
$value = $this->mc->get($this->build_key($id, $group));
$code = $this->mc->getResultCode();
$found = $code !== Memcached::RES_NOTFOUND;
if ($found) {
if ($code !== Memcached::RES_SUCCESS) {
trigger_error($code . ' ' . var_export([$id, $group, $value], true));
}
$this->internal('add', $id, $group, $value);
}
}
return $value;
}
public function get_with_cas($id, $group = 'default', &$cas_token = null)
{
$key = $this->build_key($id, $group);
if (defined('Memcached::GET_EXTENDED')) {
$result = $this->mc->get($key, null, Memcached::GET_EXTENDED);
if ($this->mc->getResultCode() === Memcached::RES_NOTFOUND) {
return false;
} else {
$cas_token = $result['cas'];
return $result['value'];
}
} else {
$value = $this->mc->get($key, null, $cas_token);
if ($this->mc->getResultCode() === Memcached::RES_NOTFOUND) {
return false;
} else {
return $value;
}
}
}
public function get_multiple($ids, $group = 'default', $force = false)
{
$caches = [];
$keys = [];
$non_persistent = $this->is_non_persistent_group($group);
if ($non_persistent || !$force) {
foreach ($ids as $id) {
$caches[$id] = $this->internal('get', $id, $group);
$keys[$id] = $this->build_key($id, $group);
if (!$non_persistent && $caches[$id] === false) {
$force = true;
}
}
if ($non_persistent || !$force) {
return $caches;
}
}
$results = $this->mc->getMulti(array_values($keys)) ?: [];
foreach ($keys as $id => $key) {
$caches[$id] = $results[$key] ?? false;
$this->internal('add', $id, $group, $caches[$id]);
}
return $caches;
}
public function set_multiple($data, $group = 'default', $expire = 0)
{
$items = [];
foreach ($data as $id => $value) {
$this->internal('add', $id, $group, $value);
$key = $this->build_key($id, $group);
$items[$key] = $value;
}
if ($this->is_non_persistent_group($group)) {
$result = true;
} else {
$result = $this->mc->setMulti($items, $expire);
$code = $this->mc->getResultCode();
if ($code !== Memcached::RES_SUCCESS) {
if ($code != Memcached::RES_NOTSTORED) {
// trigger_error($code.' '.var_export($result,true));
}
foreach ($data as $id => $value) {
$this->internal('del', $id, $group);
}
return $result;
}
}
return $result;
}
public function delete_multiple($ids, $group = 'default')
{
foreach ($ids as $id) {
$this->internal('del', $id, $group);
$keys[] = $this->build_key($id, $group);
}
return (empty($keys) || $this->is_non_persistent_group($group)) ? true : $this->mc->deleteMulti($keys);
}
public function add_global_groups($groups)
{
$this->global_groups = array_merge($this->global_groups, array_fill_keys((array) $groups, true));
}
public function add_non_persistent_groups($groups)
{
$this->non_persistent_groups = array_merge($this->non_persistent_groups, array_fill_keys((array) $groups, true));
}
public function switch_to_blog($blog_id)
{
if (is_multisite()) {
$this->blog_prefix = ((int) $blog_id) . ':';
}
}
private function is_non_persistent_group($group)
{
return $group ? isset($this->non_persistent_groups[$group]) : false;
}
private function parse_group($group)
{
$group = $group ?: 'default';
$prefix = isset($this->global_groups[$group]) ? $this->global_prefix : $this->blog_prefix;
return WP_CACHE_KEY_SALT . $prefix . $group;
}
public function build_key($id, $group = 'default')
{
return preg_replace('/\s+/', '', $this->parse_group($group) . ':' . $id);
}
public function get_stats()
{
return $this->mc->getStats();
}
public function get_mc()
{
return $this->mc;
}
public function failure_callback($host, $port)
{
}
public function close()
{
$this->mc->quit();
}
public function __construct()
{
$this->mc = new Memcached();
// $this->mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); // 用于启用与 libketama 一致性哈希算法兼容的服务器分布策略
if (!$this->mc->getServerList()) {
global $memcached_servers;
if (isset($memcached_servers)) {
foreach ($memcached_servers as $memcached) {
$this->mc->addServer(...$memcached);
}
} else {
$this->mc->addServer('127.0.0.1', 11211);
}
}
if (is_multisite()) {
$this->blog_prefix = get_current_blog_id() . ':';
$this->global_prefix = '';
} else {
$this->blog_prefix = $GLOBALS['table_prefix'] . ':';
$this->global_prefix = defined('CUSTOM_USER_TABLE') ? '' : $this->blog_prefix;
}
}
}
}