Вход Регистрация
Файл: concrete5.7.5.6/concrete/vendor/zendframework/zend-cache/src/Storage/Adapter/Redis.php
Строк: 480
<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/zf2 for the canonical source repository
 * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace ZendCacheStorageAdapter;

use 
Redis as RedisResource;
use 
RedisException as RedisResourceException;
use 
stdClass;
use 
ZendCacheException;
use 
ZendCacheStorageCapabilities;
use 
ZendCacheStorageFlushableInterface;
use 
ZendCacheStorageTotalSpaceCapableInterface;

class 
Redis extends AbstractAdapter implements
    
FlushableInterface,
    
TotalSpaceCapableInterface
{

    
/**
     * Has this instance be initialized
     *
     * @var bool
     */
    
protected $initialized false;

    
/**
     * The redis resource manager
     *
     * @var null|RedisResourceManager
     */
    
protected $resourceManager;

    
/**
     * The redis resource id
     *
     * @var null|string
     */
    
protected $resourceId;

    
/**
     * The namespace prefix
     *
     * @var string
     */
    
protected $namespacePrefix '';

    
/**
     * Create new Adapter for redis storage
     *
     * @param null|array|Traversable|RedisOptions $options
     * @see ZendCacheStorageAdapterAbstract
     */
    
public function __construct($options null)
    {
        if (!
extension_loaded('redis')) {
            throw new 
ExceptionExtensionNotLoadedException("Redis extension is not loaded");
        }

        
parent::__construct($options);

        
// reset initialized flag on update option(s)
        
$initialized = & $this->initialized;
        
$this->getEventManager()->attach('option', function ($event) use (& $initialized) {
            
$initialized false;
        });
    }

    
/**
     * Get Redis resource
     *
     * @return RedisResource
     */
    
protected function getRedisResource()
    {
        if (!
$this->initialized) {
            
$options $this->getOptions();

            
// get resource manager and resource id
            
$this->resourceManager $options->getResourceManager();
            
$this->resourceId      $options->getResourceId();

            
// init namespace prefix
            
$namespace $options->getNamespace();
            if (
$namespace !== '') {
                
$this->namespacePrefix $namespace $options->getNamespaceSeparator();
            } else {
                
$this->namespacePrefix '';
            }

            
// update initialized flag
            
$this->initialized true;
        }

        return 
$this->resourceManager->getResource($this->resourceId);
    }

    
/* options */

    /**
     * Set options.
     *
     * @param  array|Traversable|RedisOptions $options
     * @return Redis
     * @see    getOptions()
     */
    
public function setOptions($options)
    {
        if (!
$options instanceof RedisOptions) {
            
$options = new RedisOptions($options);
        }
        return 
parent::setOptions($options);
    }

    
/**
     * Get options.
     *
     * @return RedisOptions
     * @see setOptions()
     */
    
public function getOptions()
    {
        if (!
$this->options) {
            
$this->setOptions(new RedisOptions());
        }
        return 
$this->options;
    }

    
/**
     * Internal method to get an item.
     *
     * @param string  &$normalizedKey Key where to store data
     * @param bool &$success       If the operation was successfull
     * @param mixed   &$casToken      Token
     * @return mixed Data on success, false on key not found
     * @throws ExceptionRuntimeException
     */
    
protected function internalGetItem(& $normalizedKey, & $success null, & $casToken null)
    {
        
$redis $this->getRedisResource();
        try {
            
$value $redis->get($this->namespacePrefix $normalizedKey);
        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }

        if (
$value === false) {
            
$success false;
            return 
null;
        }

        
$success true;
        
$casToken $value;
        return 
$value;
    }

     
/**
     * Internal method to get multiple items.
     *
     * @param array &$normalizedKeys Array of keys to be obtained
     *
     * @return array Associative array of keys and values
     * @throws ExceptionRuntimeException
     */
    
protected function internalGetItems(array & $normalizedKeys)
    {
        
$redis $this->getRedisResource();

        
$namespacedKeys = array();
        foreach (
$normalizedKeys as & $normalizedKey) {
            
$namespacedKeys[] = $this->namespacePrefix $normalizedKey;
        }

        try {
            
$results $redis->mGet($namespacedKeys);
        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }
        
//combine the key => value pairs and remove all missing values
        
return array_filter(
            
array_combine($normalizedKeys$results),
            function (
$value) {
                return 
$value !== false;
            }
        );
    }

    
/**
     * Internal method to test if an item exists.
     *
     * @param string &$normalizedKey Normalized key which will be checked
     *
     * @return bool
     * @throws ExceptionRuntimeException
     */
    
protected function internalHasItem(& $normalizedKey)
    {
        
$redis $this->getRedisResource();
        try {
            return 
$redis->exists($this->namespacePrefix $normalizedKey);
        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }
    }

    
/**
     * Internal method to store an item.
     *
     * @param string &$normalizedKey Key in Redis under which value will be saved
     * @param mixed  &$value         Value to store under cache key
     *
     * @return bool
     * @throws ExceptionRuntimeException
     */
    
protected function internalSetItem(& $normalizedKey, & $value)
    {
        
$redis $this->getRedisResource();
        
$ttl $this->getOptions()->getTtl();

        try {
            if (
$ttl) {
                if (
$this->resourceManager->getMajorVersion($this->resourceId) < 2) {
                    throw new 
ExceptionUnsupportedMethodCallException("To use ttl you need version >= 2.0.0");
                }
                
$success $redis->setex($this->namespacePrefix $normalizedKey$ttl$value);
            } else {
                
$success $redis->set($this->namespacePrefix $normalizedKey$value);
            }
        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }

        return 
$success;
    }

     
/**
     * Internal method to store multiple items.
     *
     * @param array &$normalizedKeyValuePairs An array of normalized key/value pairs
     *
     * @return array Array of not stored keys
     * @throws ExceptionRuntimeException
     */
    
protected function internalSetItems(array & $normalizedKeyValuePairs)
    {
        
$redis $this->getRedisResource();
        
$ttl   $this->getOptions()->getTtl();

        
$namespacedKeyValuePairs = array();
        foreach (
$normalizedKeyValuePairs as $normalizedKey => & $value) {
            
$namespacedKeyValuePairs[$this->namespacePrefix $normalizedKey] = & $value;
        }
        try {
            if (
$ttl 0) {
                
//check if ttl is supported
                
if ($this->resourceManager->getMajorVersion($this->resourceId) < 2) {
                    throw new 
ExceptionUnsupportedMethodCallException("To use ttl you need version >= 2.0.0");
                }
                
//mSet does not allow ttl, so use transaction
                
$transaction $redis->multi();
                foreach (
$namespacedKeyValuePairs as $key => $value) {
                    
$transaction->setex($key$ttl$value);
                }
                
$success $transaction->exec();
            } else {
                
$success $redis->mSet($namespacedKeyValuePairs);
            }

        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }
        if (!
$success) {
            throw new 
ExceptionRuntimeException($redis->getLastError());
        }

        return array();
    }

    
/**
     * Add an item.
     *
     * @param  string $normalizedKey
     * @param  mixed  $value
     * @return bool
     * @throws ExceptionRuntimeException
     */
    
protected function internalAddItem(& $normalizedKey, & $value)
    {
        
$redis $this->getRedisResource();
        try {
            return 
$redis->setnx($this->namespacePrefix $normalizedKey$value);
        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }
    }

    
/**
     * Internal method to remove an item.
     *
     * @param string &$normalizedKey Key which will be removed
     *
     * @return bool
     * @throws ExceptionRuntimeException
     */
    
protected function internalRemoveItem(& $normalizedKey)
    {
        
$redis $this->getRedisResource();
        try {
            return (bool) 
$redis->delete($this->namespacePrefix $normalizedKey);
        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }
    }

    
/**
     * Internal method to increment an item.
     *
     * @param  string $normalizedKey
     * @param  int    $value
     * @return int|bool The new value on success, false on failure
     * @throws ExceptionRuntimeException
     */
    
protected function internalIncrementItem(& $normalizedKey, & $value)
    {
        
$redis $this->getRedisResource();
        try {
            return 
$redis->incrBy($this->namespacePrefix $normalizedKey$value);
        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }
    }

    
/**
     * Internal method to decrement an item.
     *
     * @param  string $normalizedKey
     * @param  int    $value
     * @return int|bool The new value on success, false on failure
     * @throws ExceptionRuntimeException
     */
    
protected function internalDecrementItem(& $normalizedKey, & $value)
    {
        
$redis $this->getRedisResource();
        try {
            return 
$redis->decrBy($this->namespacePrefix $normalizedKey$value);
        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }
    }

    
/**
     * Flush currently set DB
     *
     * @return bool
     * @throws ExceptionRuntimeException
     */
    
public function flush()
    {
        
$redis $this->getRedisResource();
        try {
            return 
$redis->flushDB();
        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }
    }

    
/* TotalSpaceCapableInterface */

    /**
     * Get total space in bytes
     *
     * @return int|float
     */
    
public function getTotalSpace()
    {
        
$redis  $this->getRedisResource();
        try {
            
$info $redis->info();
        } catch (
RedisResourceException $e) {
            throw new 
ExceptionRuntimeException($redis->getLastError(), $e->getCode(), $e);
        }

        return 
$info['used_memory'];

    }

    
/* status */

    /**
     * Internal method to get capabilities of this adapter
     *
     * @return Capabilities
     */
    
protected function internalGetCapabilities()
    {
        if (
$this->capabilities === null) {
            
$this->capabilityMarker = new stdClass();
            
$minTtl $this->resourceManager->getMajorVersion($this->resourceId) < 1;
            
//without serialization redis supports only strings for simple
            //get/set methods
            
$this->capabilities     = new Capabilities(
                
$this,
                
$this->capabilityMarker,
                array(
                    
'supportedDatatypes' => array(
                        
'NULL'     => 'string',
                        
'boolean'  => 'string',
                        
'integer'  => 'string',
                        
'double'   => 'string',
                        
'string'   => true,
                        
'array'    => false,
                        
'object'   => false,
                        
'resource' => false,
                    ),
                    
'supportedMetadata'  => array(),
                    
'minTtl'             => $minTtl,
                    
'maxTtl'             => 0,
                    
'staticTtl'          => true,
                    
'ttlPrecision'       => 1,
                    
'useRequestTime'     => false,
                    
'expiredRead'        => false,
                    
'maxKeyLength'       => 255,
                    
'namespaceIsPrefix'  => true,
                )
            );
        }

        return 
$this->capabilities;
    }
}
Онлайн: 0
Реклама