7 * This source file is subject to the new BSD license that is bundled
8 * with this package in the file LICENSE.txt.
9 * It is also available through the world-wide-web at this URL:
10 * http://framework.zend.com/license/new-bsd
11 * If you did not receive a copy of the license and are unable to
12 * obtain it through the world-wide-web, please send an email
13 * to license@zend.com so we can send you a copy immediately.
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
18 * @license http://framework.zend.com/license/new-bsd New BSD License
25 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
26 * @license http://framework.zend.com/license/new-bsd New BSD License
28 abstract class Zend_Cache
36 public static $standardFrontends = array('Core', 'Output', 'Class', 'File', 'Function', 'Page');
43 public static $standardBackends = array('File', 'Sqlite', 'Memcached', 'Apc', 'ZendPlatform',
44 'Xcache', 'TwoLevels', 'ZendServer_Disk', 'ZendServer_ShMem');
47 * Standard backends which implement the ExtendedInterface
51 public static $standardExtendedBackends = array('File', 'Apc', 'TwoLevels', 'Memcached', 'Sqlite');
54 * Only for backward compatibility (may be removed in next major release)
59 public static $availableFrontends = array('Core', 'Output', 'Class', 'File', 'Function', 'Page');
62 * Only for backward compatibility (may be removed in next major release)
67 public static $availableBackends = array('File', 'Sqlite', 'Memcached', 'Apc', 'ZendPlatform', 'Xcache', 'TwoLevels');
70 * Consts for clean() method
72 const CLEANING_MODE_ALL
= 'all';
73 const CLEANING_MODE_OLD
= 'old';
74 const CLEANING_MODE_MATCHING_TAG
= 'matchingTag';
75 const CLEANING_MODE_NOT_MATCHING_TAG
= 'notMatchingTag';
76 const CLEANING_MODE_MATCHING_ANY_TAG
= 'matchingAnyTag';
81 * @param mixed $frontend frontend name (string) or Zend_Cache_Frontend_ object
82 * @param mixed $backend backend name (string) or Zend_Cache_Backend_ object
83 * @param array $frontendOptions associative array of options for the corresponding frontend constructor
84 * @param array $backendOptions associative array of options for the corresponding backend constructor
85 * @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
86 * @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
87 * @param boolean $autoload if true, there will no require_once for backend and frontend (useful only for custom backends/frontends)
88 * @throws Zend_Cache_Exception
89 * @return Zend_Cache_Core|Zend_Cache_Frontend
91 public static function factory($frontend, $backend, $frontendOptions = array(), $backendOptions = array(), $customFrontendNaming = false, $customBackendNaming = false, $autoload = false)
93 if (is_string($backend)) {
94 $backendObject = self
::_makeBackend($backend, $backendOptions, $customBackendNaming, $autoload);
96 if ((is_object($backend)) && (in_array('Zend_Cache_Backend_Interface', class_implements($backend)))) {
97 $backendObject = $backend;
99 self
::throwException('backend must be a backend name (string) or an object which implements Zend_Cache_Backend_Interface');
102 if (is_string($frontend)) {
103 $frontendObject = self
::_makeFrontend($frontend, $frontendOptions, $customFrontendNaming, $autoload);
105 if (is_object($frontend)) {
106 $frontendObject = $frontend;
108 self
::throwException('frontend must be a frontend name (string) or an object');
111 $frontendObject->setBackend($backendObject);
112 return $frontendObject;
116 * Backend Constructor
118 * @param string $backend
119 * @param array $backendOptions
120 * @param boolean $customBackendNaming
121 * @param boolean $autoload
122 * @return Zend_Cache_Backend
124 public static function _makeBackend($backend, $backendOptions, $customBackendNaming = false, $autoload = false)
126 if (!$customBackendNaming) {
127 $backend = self
::_normalizeName($backend);
129 if (in_array($backend, Zend_Cache
::$standardBackends)) {
130 // we use a standard backend
131 $backendClass = 'Zend_Cache_Backend_' . $backend;
132 // security controls are explicit
133 require_once str_replace('_', DIRECTORY_SEPARATOR
, $backendClass) . '.php';
135 // we use a custom backend
136 if (!preg_match('~^[\w]+$~D', $backend)) {
137 Zend_Cache
::throwException("Invalid backend name [$backend]");
139 if (!$customBackendNaming) {
140 // we use this boolean to avoid an API break
141 $backendClass = 'Zend_Cache_Backend_' . $backend;
143 $backendClass = $backend;
146 $file = str_replace('_', DIRECTORY_SEPARATOR
, $backendClass) . '.php';
147 if (!(self
::_isReadable($file))) {
148 self
::throwException("file $file not found in include_path");
153 return new $backendClass($backendOptions);
157 * Frontend Constructor
159 * @param string $frontend
160 * @param array $frontendOptions
161 * @param boolean $customFrontendNaming
162 * @param boolean $autoload
163 * @return Zend_Cache_Core|Zend_Cache_Frontend
165 public static function _makeFrontend($frontend, $frontendOptions = array(), $customFrontendNaming = false, $autoload = false)
167 if (!$customFrontendNaming) {
168 $frontend = self
::_normalizeName($frontend);
170 if (in_array($frontend, self
::$standardFrontends)) {
171 // we use a standard frontend
172 // For perfs reasons, with frontend == 'Core', we can interact with the Core itself
173 $frontendClass = 'Zend_Cache_' . ($frontend != 'Core' ?
'Frontend_' : '') . $frontend;
174 // security controls are explicit
175 require_once str_replace('_', DIRECTORY_SEPARATOR
, $frontendClass) . '.php';
177 // we use a custom frontend
178 if (!preg_match('~^[\w]+$~D', $frontend)) {
179 Zend_Cache
::throwException("Invalid frontend name [$frontend]");
181 if (!$customFrontendNaming) {
182 // we use this boolean to avoid an API break
183 $frontendClass = 'Zend_Cache_Frontend_' . $frontend;
185 $frontendClass = $frontend;
188 $file = str_replace('_', DIRECTORY_SEPARATOR
, $frontendClass) . '.php';
189 if (!(self
::_isReadable($file))) {
190 self
::throwException("file $file not found in include_path");
195 return new $frontendClass($frontendOptions);
201 * Note : for perf reasons, the "load" of Zend/Cache/Exception is dynamic
202 * @param string $msg Message for the exception
203 * @throws Zend_Cache_Exception
205 public static function throwException($msg, Exception
$e = null)
207 // For perfs reasons, we use this dynamic inclusion
208 require_once 'Zend/Cache/Exception.php';
209 throw new Zend_Cache_Exception($msg, 0, $e);
213 * Normalize frontend and backend names to allow multiple words TitleCased
215 * @param string $name Name to normalize
218 protected static function _normalizeName($name)
220 $name = ucfirst(strtolower($name));
221 $name = str_replace(array('-', '_', '.'), ' ', $name);
222 $name = ucwords($name);
223 $name = str_replace(' ', '', $name);
224 if (stripos($name, 'ZendServer') === 0) {
225 $name = 'ZendServer_' . substr($name, strlen('ZendServer'));
232 * Returns TRUE if the $filename is readable, or FALSE otherwise.
233 * This function uses the PHP include_path, where PHP's is_readable()
236 * Note : this method comes from Zend_Loader (see #ZF-2891 for details)
238 * @param string $filename
241 private static function _isReadable($filename)
243 if (!$fh = @fopen
($filename, 'r', true)) {