Memcache.php 4.92 KB
<?php
/**
 * Created by PhpStorm.
 * User: Zip
 * Date: 15/4/28
 * Time: 下午3:16
 */

namespace Hood\Cache;

use Hood\Core\Root;

class Memcache extends Root implements CacheInterface
{
    private $mcInstances = array();

    private $persistentIDs = array();

    private $section = 'memcached';

    private $node = 'servers';

    private $tagName = '';

    private $prefix = '';

    private $persistentID = 'hood.cache';

    private $childNodes = 'hosts';

    public function __construct($prefix = '', $persistentID = 'hood.cache')
    {
        parent::__construct();
        $this->prefix = $prefix;
        $this->persistentIDs[] = $this->persistentID = $persistentID;
    }

    public function init()
    {
        if (isset($this->mcInstances[$this->persistentID])) {
            $mc = $this->mcInstances[$this->persistentID];
        } else {
            $instance = new \Memcache();
            $server = $this->getServerHost('cache');
            $_serverHosts = $server->getServerConfig($this->section, $this->node);
            $mcServers = $this->_makeHosts($server->getServer($_serverHosts[$this->childNodes], 2));
            foreach ($mcServers as $key => $val) {
                $weight = 100;
                if (count($val) == 3) {
                    list($host, $port, $weight) = $val;
                } else {
                    list($host, $port) = $val;
                }
                $instance->addServer($host, $port, $this->persistentID, $weight);
            }
            $this->mcInstances[$this->persistentID] = $mc = $instance;
        }
        return $mc;
    }

    /**
     * 组织host
     * @param array $hosts
     * @return array
     */
    private function _makeHosts(array $hosts)
    {
        $_server = array();
        foreach ($hosts as $key => $val) {
            $_server[] = explode(':', $val);
        }
        return $_server;
    }

    /**
     * 设置mc配置的块节点
     * @param $node
     * @return $this
     */
    public function setNode($node = null)
    {
        if ($node != null) $this->node = $node;
        return $this;
    }

    /**
     * 设置子节点
     * @param $childNode
     * @return $this
     */
    public function setChildNodes($childNode)
    {
        $this->childNodes = $childNode;
        return $this;
    }

    /**
     * 构建tag
     * @param bool $mode
     * @return string
     */
    private function _makeTag($mode = false)
    {
        if (empty($this->tagName)) return '';
        $_tagVal = $this->init()->get($this->tagName);
        if (empty($_tagVal) && $mode == true) {
            $_tagVal = md5(microtime() . mt_rand() . uniqid());
            $this->init()->set($this->tagName, $_tagVal, 0);
        }
        unset($this->tagName);
        return empty($_tagVal) ? '' : $_tagVal . '.';
    }

    /**
     * 检索一个元素
     * @param $key
     * @param callable $flags
     * @return mixed
     */
    public function get($key, &$flags = \MEMCACHE_COMPRESSED)
    {
        return $this->init()->get($this->_makeTag() . $key, $flags);
    }

    public function getBy($key, $cacheCb = null, &$casToken = null)
    {
        return $this->init()->get($key, $cacheCb, $casToken);
    }

    /**
     *  向一个新的key下面增加一个元素
     * @param $key
     * @param $value
     * @param $expiration
     * @return bool
     */
    public function add($key, $value, $expiration = 0)
    {
        return $this->init()->add($this->_makeTag(true) . $key, $value, $expiration);
    }


    /**
     * 减小数值元素的值
     * @param $key
     * @param int $offset
     * @return int
     */
    public function decrement($key, $offset = 1)
    {
        return $this->init()->decrement($this->_makeTag() . $key, $offset);
    }

    /**
     * @param $key
     * @param int $time
     * @return bool
     */
    public function delete($key, $time = 0)
    {
        return $this->init()->delete($this->_makeTag() . $key, $time);
    }


    /**
     * 增加数值元素的值
     * @param $key
     * @param int $offset
     * @param int $initialValue
     * @param int $expiry
     * @return int
     */
    public function increment($key, $offset = 1, $initialValue = 0, $expiry = 0)
    {
        return $this->init()->increment($this->_makeTag() . $key, $offset, $initialValue, $expiry);
    }


    /**
     * 设置
     * @param $key
     * @param $value
     * @param int $expiration
     * @return bool
     */
    public function set($key, $var, $expire = 0, $flag = \MEMCACHE_COMPRESSED)
    {
        return $this->init()->set($this->_makeTag(true) . $key, $var, $flag, $expire);
    }

    /**
     * 设置tag
     * @param $tagName
     * @return $this
     */
    public function tag($tagName)
    {
        $this->tagName = $tagName;
        return $this;
    }
}