File indexing completed on 2024-12-22 05:37:15
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Cache 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 0023 /** 0024 * @package Zend_Cache 0025 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0026 * @license http://framework.zend.com/license/new-bsd New BSD License 0027 */ 0028 abstract class Zend_Cache 0029 { 0030 0031 /** 0032 * Standard frontends 0033 * 0034 * @var array 0035 */ 0036 public static $standardFrontends = array('Core', 'Output', 'Class', 'File', 'Function', 'Page'); 0037 0038 /** 0039 * Standard backends 0040 * 0041 * @var array 0042 */ 0043 public static $standardBackends = array('File', 'Sqlite', 'Memcached', 'Libmemcached', 'Apc', 'ZendPlatform', 0044 'Xcache', 'TwoLevels', 'WinCache', 'ZendServer_Disk', 'ZendServer_ShMem'); 0045 0046 /** 0047 * Standard backends which implement the ExtendedInterface 0048 * 0049 * @var array 0050 */ 0051 public static $standardExtendedBackends = array('File', 'Apc', 'TwoLevels', 'Memcached', 'Libmemcached', 'Sqlite', 'WinCache'); 0052 0053 /** 0054 * Only for backward compatibility (may be removed in next major release) 0055 * 0056 * @var array 0057 * @deprecated 0058 */ 0059 public static $availableFrontends = array('Core', 'Output', 'Class', 'File', 'Function', 'Page'); 0060 0061 /** 0062 * Only for backward compatibility (may be removed in next major release) 0063 * 0064 * @var array 0065 * @deprecated 0066 */ 0067 public static $availableBackends = array('File', 'Sqlite', 'Memcached', 'Libmemcached', 'Apc', 'ZendPlatform', 'Xcache', 'WinCache', 'TwoLevels'); 0068 0069 /** 0070 * Consts for clean() method 0071 */ 0072 const CLEANING_MODE_ALL = 'all'; 0073 const CLEANING_MODE_OLD = 'old'; 0074 const CLEANING_MODE_MATCHING_TAG = 'matchingTag'; 0075 const CLEANING_MODE_NOT_MATCHING_TAG = 'notMatchingTag'; 0076 const CLEANING_MODE_MATCHING_ANY_TAG = 'matchingAnyTag'; 0077 0078 /** 0079 * Factory 0080 * 0081 * @param mixed $frontend frontend name (string) or Zend_Cache_Frontend_ object 0082 * @param mixed $backend backend name (string) or Zend_Cache_Backend_ object 0083 * @param array $frontendOptions associative array of options for the corresponding frontend constructor 0084 * @param array $backendOptions associative array of options for the corresponding backend constructor 0085 * @param boolean $customFrontendNaming if true, the frontend argument is used as a complete class name ; if false, the frontend argument is used as the end of "Zend_Cache_Frontend_[...]" class name 0086 * @param boolean $customBackendNaming if true, the backend argument is used as a complete class name ; if false, the backend argument is used as the end of "Zend_Cache_Backend_[...]" class name 0087 * @param boolean $autoload if true, there will no // require_once for backend and frontend (useful only for custom backends/frontends) 0088 * @throws Zend_Cache_Exception 0089 * @return Zend_Cache_Core|Zend_Cache_Frontend 0090 */ 0091 public static function factory($frontend, $backend, $frontendOptions = array(), $backendOptions = array(), $customFrontendNaming = false, $customBackendNaming = false, $autoload = false) 0092 { 0093 if (is_string($backend)) { 0094 $backendObject = self::_makeBackend($backend, $backendOptions, $customBackendNaming, $autoload); 0095 } else { 0096 if ((is_object($backend)) && (in_array('Zend_Cache_Backend_Interface', class_implements($backend)))) { 0097 $backendObject = $backend; 0098 } else { 0099 self::throwException('backend must be a backend name (string) or an object which implements Zend_Cache_Backend_Interface'); 0100 } 0101 } 0102 if (is_string($frontend)) { 0103 $frontendObject = self::_makeFrontend($frontend, $frontendOptions, $customFrontendNaming, $autoload); 0104 } else { 0105 if (is_object($frontend)) { 0106 $frontendObject = $frontend; 0107 } else { 0108 self::throwException('frontend must be a frontend name (string) or an object'); 0109 } 0110 } 0111 $frontendObject->setBackend($backendObject); 0112 return $frontendObject; 0113 } 0114 0115 /** 0116 * Backend Constructor 0117 * 0118 * @param string $backend 0119 * @param array $backendOptions 0120 * @param boolean $customBackendNaming 0121 * @param boolean $autoload 0122 * @return Zend_Cache_Backend 0123 */ 0124 public static function _makeBackend($backend, $backendOptions, $customBackendNaming = false, $autoload = false) 0125 { 0126 if (!$customBackendNaming) { 0127 $backend = self::_normalizeName($backend); 0128 } 0129 if (in_array($backend, Zend_Cache::$standardBackends)) { 0130 // we use a standard backend 0131 $backendClass = 'Zend_Cache_Backend_' . $backend; 0132 // security controls are explicit 0133 // require_once str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php'; 0134 } else { 0135 // we use a custom backend 0136 if (!preg_match('~^[\w\\\\]+$~D', $backend)) { 0137 Zend_Cache::throwException("Invalid backend name [$backend]"); 0138 } 0139 if (!$customBackendNaming) { 0140 // we use this boolean to avoid an API break 0141 $backendClass = 'Zend_Cache_Backend_' . $backend; 0142 } else { 0143 $backendClass = $backend; 0144 } 0145 if (!$autoload) { 0146 $file = str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php'; 0147 if (!(self::_isReadable($file))) { 0148 self::throwException("file $file not found in include_path"); 0149 } 0150 // require_once $file; 0151 } 0152 } 0153 return new $backendClass($backendOptions); 0154 } 0155 0156 /** 0157 * Frontend Constructor 0158 * 0159 * @param string $frontend 0160 * @param array $frontendOptions 0161 * @param boolean $customFrontendNaming 0162 * @param boolean $autoload 0163 * @return Zend_Cache_Core|Zend_Cache_Frontend 0164 */ 0165 public static function _makeFrontend($frontend, $frontendOptions = array(), $customFrontendNaming = false, $autoload = false) 0166 { 0167 if (!$customFrontendNaming) { 0168 $frontend = self::_normalizeName($frontend); 0169 } 0170 if (in_array($frontend, self::$standardFrontends)) { 0171 // we use a standard frontend 0172 // For perfs reasons, with frontend == 'Core', we can interact with the Core itself 0173 $frontendClass = 'Zend_Cache_' . ($frontend != 'Core' ? 'Frontend_' : '') . $frontend; 0174 // security controls are explicit 0175 // require_once str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php'; 0176 } else { 0177 // we use a custom frontend 0178 if (!preg_match('~^[\w\\\\]+$~D', $frontend)) { 0179 Zend_Cache::throwException("Invalid frontend name [$frontend]"); 0180 } 0181 if (!$customFrontendNaming) { 0182 // we use this boolean to avoid an API break 0183 $frontendClass = 'Zend_Cache_Frontend_' . $frontend; 0184 } else { 0185 $frontendClass = $frontend; 0186 } 0187 if (!$autoload) { 0188 $file = str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php'; 0189 if (!(self::_isReadable($file))) { 0190 self::throwException("file $file not found in include_path"); 0191 } 0192 // require_once $file; 0193 } 0194 } 0195 return new $frontendClass($frontendOptions); 0196 } 0197 0198 /** 0199 * Throw an exception 0200 * 0201 * Note : for perf reasons, the "load" of Zend/Cache/Exception is dynamic 0202 * @param string $msg Message for the exception 0203 * @throws Zend_Cache_Exception 0204 */ 0205 public static function throwException($msg, Exception $e = null) 0206 { 0207 // For perfs reasons, we use this dynamic inclusion 0208 // require_once 'Zend/Cache/Exception.php'; 0209 throw new Zend_Cache_Exception($msg, 0, $e); 0210 } 0211 0212 /** 0213 * Normalize frontend and backend names to allow multiple words TitleCased 0214 * 0215 * @param string $name Name to normalize 0216 * @return string 0217 */ 0218 protected static function _normalizeName($name) 0219 { 0220 $name = ucfirst(strtolower($name)); 0221 $name = str_replace(array('-', '_', '.'), ' ', $name); 0222 $name = ucwords($name); 0223 $name = str_replace(' ', '', $name); 0224 if (stripos($name, 'ZendServer') === 0) { 0225 $name = 'ZendServer_' . substr($name, strlen('ZendServer')); 0226 } 0227 0228 return $name; 0229 } 0230 0231 /** 0232 * Returns TRUE if the $filename is readable, or FALSE otherwise. 0233 * This function uses the PHP include_path, where PHP's is_readable() 0234 * does not. 0235 * 0236 * Note : this method comes from Zend_Loader (see #ZF-2891 for details) 0237 * 0238 * @param string $filename 0239 * @return boolean 0240 */ 0241 private static function _isReadable($filename) 0242 { 0243 if (!$fh = @fopen($filename, 'r', true)) { 0244 return false; 0245 } 0246 @fclose($fh); 0247 return true; 0248 } 0249 0250 }