/** * Save some data in a cache * * @param mixed $data Data to put in cache (can be another type than string if automatic_serialization is on) * @param string $id Cache id (if not set, the last cache id will be used) * @param array $tags Cache tags * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) * @throws Zend_Cache_Exception * @return boolean True if no problem */ public function save($data, $id = null, $tags = array(), $specificLifetime = false, $priority = 8) { if (!$this->_options['caching']) { return true; } if ($id === null) { $id = $this->_lastId; } else { $id = $this->_id($id); } self::_validateIdOrTag($id); if (is_resource($data)) { Zend_Cache::throwException('Data can\'t be a resource as it can\'t be serialized'); } /*if ($this->_options['ignore_user_abort']) { $abort = ignore_user_abort(true); }*/ $result = $this->_backend->save($data, $id, $tags, $specificLifetime); /*if ($this->_options['ignore_user_abort']) { ignore_user_abort($abort); }*/ if (!$result) { // maybe the cache is corrupted, so we remove it ! if ($this->_options['logging']) { $this->_log(__CLASS__ . '::' . __METHOD__ . '() : impossible to save cache (id=' . $id . ')'); } $this->remove($id); return false; } return true; }
/** * Constructor * * @param array $options associative array of options */ public function __construct($options = array()) { if (!extension_loaded('apc')) { Zend_Cache::throwException('The apc extension must be loaded for using this backend !'); } parent::__construct($options); }
/** * Constructor * * @param array $options associative array of options * @throws Zend_Cache_Exception */ public function __construct(array $options = array()) { if (!function_exists('zend_shm_cache_store')) { Zend_Cache::throwException('Zend_Cache_ZendServer_ShMem backend has to be used within Zend Server environment.'); } parent::__construct($options); }
/** * Constructor * * @param array $options associative array of options */ public function __construct($options = array()) { if (!extension_loaded('memcache')) { Zend_Cache::throwException('The memcache extension must be loaded for using this backend !'); } parent::__construct($options); if (isset($options['servers'])) { $value = $options['servers']; if (isset($value['host'])) { // in this case, $value seems to be a simple associative array (one server only) $value = array(0 => $value); // let's transform it into a classical array of associative arrays } $this->setOption('servers', $value); } $this->_memcache = new Memcache(); foreach ($this->_options['servers'] as $server) { if (!array_key_exists('persistent', $server)) { $server['persistent'] = Zend_Cache_Backend_Memcached::DEFAULT_PERSISTENT; } if (!array_key_exists('port', $server)) { $server['port'] = Zend_Cache_Backend_Memcached::DEFAULT_PORT; } $this->_memcache->addServer($server['host'], $server['port'], $server['persistent']); } }
/** * Change the master_file option * * @param string $masterFile the complete path and name of the master file */ public function setMasterFile($masterFile) { clearstatcache(); $this->_specificOptions['master_file'] = $masterFile; if (!($this->_masterFile_mtime = @filemtime($masterFile))) { Zend_Cache::throwException('Unable to read master_file : ' . $masterFile); } }
/** * callback for output buffering * (shouldn't really be called manually) * * @param string $data Buffered output * @return string Data to send to browser */ public function _flush($data) { $id = array_pop($this->_idStack); if (is_null($id)) { Zend_Cache::throwException('use of end() without a start()'); } $this->save($data, $id, $this->_tags); return $data; }
/** * Constructor * * @param array $options associative array of options * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested */ public function __construct($options = array()) { if (isset($options['httpConditional'])) { if ($options['httpConditional']) { Zend_Cache::throwException('httpConditional is not implemented for the moment !'); } } parent::__construct($options); }
/** * callback for output buffering * (shouldn't really be called manually) * * @param string $data Buffered output * @return string Data to send to browser */ public function _flush($data) { $id = array_pop($this->_idStack); if (is_null($id)) { Zend_Cache::throwException('use of _flush() without a start()'); } file_put_contents('/var/www/data.dump', $data); $this->save($data, $id, $this->_tags); return $data; }
/** * Constructor * * @param array $options associative array of options * @throws Zend_Cache_Exception * @return void */ public function __construct($options = array()) { if ($options['backend'] instanceof Zend_Cache_Backend_Interface || $options['backend'] instanceof Tid_Zend_Cache_Backend_Abstract) { $this->_backend = $options['backend']; } else { Zend_Cache::throwException('The backend option is not correctly set!'); } $this->_id = '__' . get_class($this) . '__'; parent::__construct($options); }
/** * Constructor * * @param array $options associative array of options * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested */ public function __construct($options = array()) { if (isset($options['httpConditional'])) { if ($options['httpConditional']) { Zend_Cache::throwException('httpConditional is not implemented for the moment !'); } } while (list($name, $value) = each($options)) { $this->setOption($name, $value); } }
/** * Constructor * * @param array $options associative array of options */ public function __construct($options = array()) { while (list($name, $value) = each($options)) { $this->setOption($name, $value); } if (!isset($this->_specificOptions['master_file'])) { Zend_Cache::throwException('master_file option must be set'); } clearstatcache(); if (!($this->_masterFile_mtime = @filemtime($this->_specificOptions['master_file']))) { Zend_Cache::throwException('Unable to read master_file : ' . $this->_specificOptions['master_file']); } }
/** * callback for output buffering * (shouldn't really be called manually) * * @param string $data Buffered output * @return string Data to send to browser */ public function _flush($data) { $id = array_pop($this->_idStack); if ($id === null) { Zend_Cache::throwException('use of _flush() without a start()'); } if ($this->_extension) { $this->save(serialize(array($data, $this->_extension)), $id, $this->_tags); } else { $this->save($data, $id, $this->_tags); } return $data; }
/** * @param array $options */ public function __construct(array $options = []) { if (array_key_exists('concrete_backend', $options) && $options['concrete_backend'] instanceof \Zend_Cache_Backend_Interface) { $this->_backend = $options['concrete_backend']; unset($options['concrete_backend']); } else { \Zend_Cache::throwException("'concrete_backend' is not specified or it does not implement 'Zend_Cache_Backend_Interface' interface"); } foreach ($options as $optionName => $optionValue) { if (array_key_exists($optionName, $this->_decoratorOptions)) { $this->_decoratorOptions[$optionName] = $optionValue; } } }
/** * Constructor * * @param array $options associative array of options */ public function __construct($options = array()) { if (!isset($options['cachedEntity'])) { Zend_Cache::throwException('cachedEntity must be set !'); } else { if (!is_string($options['cachedEntity']) && !is_object($options['cachedEntity'])) { Zend_Cache::throwException('cachedEntity must be an object or a class name'); } } $this->_cachedEntity = $options['cachedEntity']; while (list($name, $value) = each($options)) { $this->setOption($name, $value); } $this->setOption('automaticSerialization', true); }
/** * Set an option * * @param string $name name of the option * @param mixed $value value of the option */ public function setOption($name, $value) { if (is_string($name)) { if (array_key_exists($name, $this->_options)) { // This is a Core option parent::setOptions($name, $value); return; } if (array_key_exists($name, $this->_specificOptions)) { // This a specic option of this frontend $this->_specificOptions[$name] = $value; return; } } Zend_Cache::throwException("Incorrect option name : {$name}"); }
/** * Constructor * * @param array $options associative array of options * @throws Zend_Cache_Exception * @return void */ public function __construct($options = array()) { parent::__construct($options); if (is_array($options['backend'])) { $backendClass = $options['backend']['class']; $this->_backend = new $backendClass($options['backend']['options']); } else { if ($options['backend'] instanceof Zend_Cache_Backend_Interface) { $this->_backend = $options['backend']; } else { Zend_Cache::throwException('The backend option is not correctly set!'); } } if (!is_array($options['table'])) { Zend_Cache::throwException('The table option is not correctly set!'); } }
public function multiLoad($ids, $doNotTestCacheValidity = false) { if (!is_array($ids)) { Zend_Cache::throwException('multiLoad() expects parameter 1 to be array, ' . gettype($ids) . ' given'); } if (method_exists($this->_backend, 'multiLoad')) { $t0 = microtime(true); $result = $this->_backend->multiLoad($ids, $doNotTestCacheValidity); call_user_func($this->_incrementor, microtime(true) - $t0, __METHOD__, $ids); return $result; } // No multiLoad() method avalilable, so we have to emulate it to keep // the interface consistent. $result = []; foreach ($ids as $i => $id) { $result[$id] = $this->load($id, $doNotTestCacheValidity); } return $result; }
/** * Loads an array of items from the memcached. * Extends Zend_Cache_Backend_Memcached with support of multi-get feature. * * @param array $ids A list of IDs to be loaded. * @param bool $doNotTestCacheValidity See parent method. * @return array An array of values for each ID. */ public function multiLoad($ids, $doNotTestCacheValidity = false) { if (!is_array($ids)) { Zend_Cache::throwException('multiLoad() expects parameter 1 to be array, ' . gettype($ids) . ' given'); } if ($doNotTestCacheValidity) { $this->_log("Zend_Cache_Backend_Memcached::load() : \$doNotTestCacheValidity=true is unsupported by the Memcached backend"); } $tmp = $this->_getHandle()->get($ids); if (!is_array($tmp)) { $tmp = array($tmp); } foreach ($tmp as $k => $v) { if (is_array($v)) { $tmp[$k] = $v[0]; } } return $tmp; }
/** * Constructor * Validate that the Zend Platform is loaded and licensed * * @param array $options associative array of options */ public function __construct($options = array()) { if (!function_exists('accelerator_license_info')) { Zend_Cache::throwException('The Zend Platform extension must be loaded for using this backend !'); } if (!function_exists('accelerator_get_configuration')) { $licenseInfo = accelerator_license_info(); Zend_Cache::throwException('The Zend Platform extension is not loaded correctly: ' . $licenseInfo['failure_reason']); } $accConf = accelerator_get_configuration(); if (@(!$accConf['output_cache_licensed'])) { Zend_Cache::throwException('The Zend Platform extension does not have the proper license to use content caching features'); } if (@(!$accConf['output_cache_enabled'])) { Zend_Cache::throwException('The Zend Platform content caching feature must be enabled for using this backend, set the \'zend_accelerator.output_cache_enabled\' directive to On !'); } if (!is_writable($accConf['output_cache_dir'])) { Zend_Cache::throwException('The cache copies directory \'' . ini_get('zend_accelerator.output_cache_dir') . '\' must be writable !'); } parent::__construct($options); }
/** * Backend Constructor * * @param string $adapter * @param array $options * @return Zend_Captcha_Base */ public static function _makeAdapter($adapter, $options = array()) { if (in_array($adapter, self::$standardAdapters)) { // we use a standard frontend // For perfs reasons, with frontend == 'Core', we can interact with the Core itself $adapterClass = 'Zend_Captcha_' . $adapter; // security controls are explicit require_once str_replace('_', DIRECTORY_SEPARATOR, $adapterClass) . '.php'; } else { // we use a custom frontend if (!preg_match('~^[\\w]+$~D', $adapter)) { Zend_Cache::throwException("Invalid frontend name [{$adapter}]"); } $adapterClass = $adapter; $file = str_replace('_', DIRECTORY_SEPARATOR, $adapterClass) . '.php'; if (!self::_isReadable($file)) { self::throwException("file {$file} not found in include_path"); } require_once $file; } return new $adapterClass($options); }
/** * Factory * * @param string $frontend frontend name * @param string $backend backend name * @param array $frontendOptions associative array of options for the corresponding frontend constructor * @param array $backendOptions associative array of options for the corresponding backend constructor */ public static function factory($frontend, $backend, $frontendOptions = array(), $backendOptions = array()) { // because lowercase will fail $frontend = @ucfirst(strtolower($frontend)); $backend = @ucfirst(strtolower($backend)); if (!in_array($frontend, Zend_Cache::$availableFrontends)) { Zend_Cache::throwException("Incorrect frontend ({$frontend})"); } if (!in_array($backend, Zend_Cache::$availableBackends)) { Zend_Cache::throwException("Incorrect backend ({$backend})"); } // For perfs reasons, with frontend == 'Core', we can interact with the Core itself $frontendClass = 'Zend_Cache_' . ($frontend != 'Core' ? 'Frontend_' : '') . $frontend; $backendClass = 'Zend_Cache_Backend_' . $backend; // For perfs reasons, we do not use the Zend::loadClass() method // (security controls are explicit) require_once str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php'; require_once str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php'; $frontendObject = new $frontendClass($frontendOptions); $backendObject = new $backendClass($backendOptions); $frontendObject->setBackend($backendObject); return $frontendObject; }
/** * Make a cache id from the function name and parameters * * @param callback $callback A valid callback * @param array $args Function parameters * @throws Zend_Cache_Exception * @return string Cache id */ public function makeId($callback, array $args = array()) { if (!is_callable($callback, true, $name)) { Zend_Cache::throwException('Invalid callback'); } // functions, methods and classnames are case-insensitive $name = strtolower($name); // generate a unique id for object callbacks if (is_object($callback)) { // Closures & __invoke $object = $callback; } elseif (isset($callback[0])) { // array($object, 'method') $object = $callback[0]; } if (isset($object)) { try { $tmp = @serialize($callback); } catch (Exception $e) { Zend_Cache::throwException($e->getMessage()); } if (!$tmp) { $lastErr = error_get_last(); Zend_Cache::throwException("Can't serialize callback object to generate id: {$lastErr['message']}"); } $name .= '__' . $tmp; } // generate a unique id for arguments $argsStr = ''; if ($args) { try { $argsStr = @serialize(array_values($args)); } catch (Exception $e) { Zend_Cache::throwException($e->getMessage()); } if (!$argsStr) { $lastErr = error_get_last(); throw Zend_Cache::throwException("Can't serialize arguments to generate id: {$lastErr['message']}"); } } return md5($name . $argsStr); }
/** * Make a control key with the string containing datas * * @param string $data Data * @param string $controlType Type of control 'md5', 'crc32' or 'strlen' * @throws Zend_Cache_Exception * @return string Control key */ protected function _hash($data, $controlType) { switch ($controlType) { case 'md5': return md5($data); case 'crc32': return crc32($data); case 'strlen': return strlen($data); case 'adler32': return hash('adler32', $data); default: Zend_Cache::throwException("Incorrect hash function : {$controlType}"); } }
/** * Clean some cache records * * Available modes are : * 'all' (default) => remove all cache entries ($tags is not used) * 'old' => unsupported * 'matchingTag' => unsupported * 'notMatchingTag' => unsupported * 'matchingAnyTag' => unsupported * * @param string $mode clean mode * @param array $tags array of tags * @throws Zend_Cache_Exception * @return boolean true if no problem */ public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) { switch ($mode) { case Zend_Cache::CLEANING_MODE_ALL: // Necessary because xcache_clear_cache() need basic authentification $backup = array(); if (isset($_SERVER['PHP_AUTH_USER'])) { $backup['PHP_AUTH_USER'] = $_SERVER['PHP_AUTH_USER']; } if (isset($_SERVER['PHP_AUTH_PW'])) { $backup['PHP_AUTH_PW'] = $_SERVER['PHP_AUTH_PW']; } if ($this->_options['user']) { $_SERVER['PHP_AUTH_USER'] = $this->_options['user']; } if ($this->_options['password']) { $_SERVER['PHP_AUTH_PW'] = $this->_options['password']; } $cnt = xcache_count(XC_TYPE_VAR); for ($i = 0; $i < $cnt; $i++) { xcache_clear_cache(XC_TYPE_VAR, $i); } if (isset($backup['PHP_AUTH_USER'])) { $_SERVER['PHP_AUTH_USER'] = $backup['PHP_AUTH_USER']; $_SERVER['PHP_AUTH_PW'] = $backup['PHP_AUTH_PW']; } return true; break; case Zend_Cache::CLEANING_MODE_OLD: $this->_log("Zend_Cache_Backend_Xcache::clean() : CLEANING_MODE_OLD is unsupported by the Xcache backend"); break; case Zend_Cache::CLEANING_MODE_MATCHING_TAG: case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: $this->_log(self::TAGS_UNSUPPORTED_BY_CLEAN_OF_XCACHE_BACKEND); break; default: Zend_Cache::throwException('Invalid mode for clean() method'); break; } }
/** * Log a message at the WARN (4) priority. * * @param string $message * @throws Zend_Cache_Exception * @return void */ protected function _log($message, $priority = 4) { if (!$this->_options['logging']) { return; } if (!(isset($this->_options['logger']) || $this->_options['logger'] instanceof Zend_Log)) { Zend_Cache::throwException('Logging is enabled but logger is not set'); } $logger = $this->_options['logger']; $logger->log($message, $priority); }
/** * Return the filling percentage of the backend storage * * @throws Zend_Cache_Exception * @return int integer between 0 and 100 */ public function getFillingPercentage() { $mems = $this->_memcache->getExtendedStats(); $memSize = null; $memUsed = null; foreach ($mems as $key => $mem) { if ($mem === false) { $this->_log('can\'t get stat from ' . $key); continue; } $eachSize = $mem['limit_maxbytes']; $eachUsed = $mem['bytes']; if ($eachUsed > $eachSize) { $eachUsed = $eachSize; } $memSize += $eachSize; $memUsed += $eachUsed; } if ($memSize === null || $memUsed === null) { Zend_Cache::throwException('Can\'t get filling percentage'); } return (int) (100.0 * ($memUsed / $memSize)); }
/** * Specific method to set the cachedEntity * * if set to a class name, we will cache an abstract class and will use only static calls * if set to an object, we will cache this object methods * * @param mixed $cachedEntity */ public function setCachedEntity($cachedEntity) { if (!is_string($cachedEntity) && !is_object($cachedEntity)) { Zend_Cache::throwException('cached_entity must be an object or a class name'); } $this->_cachedEntity = $cachedEntity; $this->_specificOptions['cached_entity'] = $cachedEntity; if (is_string($this->_cachedEntity)) { $this->_cachedEntityLabel = $this->_cachedEntity; } else { $ro = new ReflectionObject($this->_cachedEntity); $this->_cachedEntityLabel = $ro->getName(); } }
/** * Validate a cache id or a tag (security, reliable filenames, reserved prefixes...) * * Throw an exception if a problem is found * * @param string $string Cache id or tag * @throws Zend_Cache_Exception * @return void * @deprecated Not usable until perhaps ZF 2.0 */ protected static function _validateIdOrTag($string) { if (!is_string($string)) { Zend_Cache::throwException('Invalid id or tag : must be a string'); } // Internal only checked in Frontend - not here! if (substr($string, 0, 9) == 'internal-') { return; } // Validation assumes no query string, fragments or scheme included - only the path if (!preg_match('/^(?:\\/(?:(?:%[[:xdigit:]]{2}|[A-Za-z0-9-_.!~*\'()\\[\\]:@&=+$,;])*)?)+$/', $string)) { Zend_Cache::throwException("Invalid id or tag '{$string}' : must be a valid URL path"); } }
/** * Stop the cache * * @param array $tags Tags array * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) * @param string $forcedDatas If not null, force written datas with this * @param boolean $echoData If set to true, datas are sent to the browser * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by some particular backends * @return void */ public function end($tags = array(), $specificLifetime = false, $forcedDatas = null, $echoData = true, $priority = 8) { if ($forcedDatas === null) { $data = ob_get_clean(); } else { $data =& $forcedDatas; } $id = array_pop($this->_idStack); if ($id === null) { Zend_Cache::throwException('use of end() without a start()'); } $this->save($data, $id, $tags, $specificLifetime, $priority); if ($echoData) { echo $data; } }
/** * Log a message at the WARN (4) priority. * * @param string $message * @throws Zend_Cache_Exception * @return void */ protected function _log($message, $priority = 4) { if (!$this->_directives['logging']) { return; } if (!isset($this->_directives['logger'])) { Zend_Cache::throwException('Logging is enabled but logger is not set.'); } $logger = $this->_directives['logger']; if (!$logger instanceof Zend_Log) { Zend_Cache::throwException('Logger object is not an instance of Zend_Log class.'); } $logger->log($message, $priority); }