File indexing completed on 2025-01-19 05:20:57
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 * @subpackage Zend_Cache_Frontend 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 0024 /** 0025 * @see Zend_Cache_Core 0026 */ 0027 // require_once 'Zend/Cache/Core.php'; 0028 0029 0030 /** 0031 * @package Zend_Cache 0032 * @subpackage Zend_Cache_Frontend 0033 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0034 * @license http://framework.zend.com/license/new-bsd New BSD License 0035 */ 0036 class Zend_Cache_Frontend_Function extends Zend_Cache_Core 0037 { 0038 /** 0039 * This frontend specific options 0040 * 0041 * ====> (boolean) cache_by_default : 0042 * - if true, function calls will be cached by default 0043 * 0044 * ====> (array) cached_functions : 0045 * - an array of function names which will be cached (even if cache_by_default = false) 0046 * 0047 * ====> (array) non_cached_functions : 0048 * - an array of function names which won't be cached (even if cache_by_default = true) 0049 * 0050 * @var array options 0051 */ 0052 protected $_specificOptions = array( 0053 'cache_by_default' => true, 0054 'cached_functions' => array(), 0055 'non_cached_functions' => array() 0056 ); 0057 0058 /** 0059 * Constructor 0060 * 0061 * @param array $options Associative array of options 0062 * @return void 0063 */ 0064 public function __construct(array $options = array()) 0065 { 0066 foreach ($options as $name => $value) { 0067 $this->setOption($name, $value); 0068 } 0069 $this->setOption('automatic_serialization', true); 0070 } 0071 0072 /** 0073 * Main method : call the specified function or get the result from cache 0074 * 0075 * @param callback $callback A valid callback 0076 * @param array $parameters Function parameters 0077 * @param array $tags Cache tags 0078 * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) 0079 * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by some particular backends 0080 * @return mixed Result 0081 */ 0082 public function call($callback, array $parameters = array(), $tags = array(), $specificLifetime = false, $priority = 8) 0083 { 0084 if (!is_callable($callback, true, $name)) { 0085 Zend_Cache::throwException('Invalid callback'); 0086 } 0087 0088 $cacheBool1 = $this->_specificOptions['cache_by_default']; 0089 $cacheBool2 = in_array($name, $this->_specificOptions['cached_functions']); 0090 $cacheBool3 = in_array($name, $this->_specificOptions['non_cached_functions']); 0091 $cache = (($cacheBool1 || $cacheBool2) && (!$cacheBool3)); 0092 if (!$cache) { 0093 // Caching of this callback is disabled 0094 return call_user_func_array($callback, $parameters); 0095 } 0096 0097 $id = $this->_makeId($callback, $parameters); 0098 if ( ($rs = $this->load($id)) && isset($rs[0], $rs[1])) { 0099 // A cache is available 0100 $output = $rs[0]; 0101 $return = $rs[1]; 0102 } else { 0103 // A cache is not available (or not valid for this frontend) 0104 ob_start(); 0105 ob_implicit_flush(false); 0106 $return = call_user_func_array($callback, $parameters); 0107 $output = ob_get_clean(); 0108 $data = array($output, $return); 0109 $this->save($data, $id, $tags, $specificLifetime, $priority); 0110 } 0111 0112 echo $output; 0113 return $return; 0114 } 0115 0116 /** 0117 * ZF-9970 0118 * 0119 * @deprecated 0120 */ 0121 private function _makeId($callback, array $args) 0122 { 0123 return $this->makeId($callback, $args); 0124 } 0125 0126 /** 0127 * Make a cache id from the function name and parameters 0128 * 0129 * @param callback $callback A valid callback 0130 * @param array $args Function parameters 0131 * @throws Zend_Cache_Exception 0132 * @return string Cache id 0133 */ 0134 public function makeId($callback, array $args = array()) 0135 { 0136 if (!is_callable($callback, true, $name)) { 0137 Zend_Cache::throwException('Invalid callback'); 0138 } 0139 0140 // functions, methods and classnames are case-insensitive 0141 $name = strtolower($name); 0142 0143 // generate a unique id for object callbacks 0144 if (is_object($callback)) { // Closures & __invoke 0145 $object = $callback; 0146 } elseif (isset($callback[0])) { // array($object, 'method') 0147 $object = $callback[0]; 0148 } 0149 if (isset($object)) { 0150 try { 0151 $tmp = @serialize($callback); 0152 } catch (Exception $e) { 0153 Zend_Cache::throwException($e->getMessage()); 0154 } 0155 if (!$tmp) { 0156 $lastErr = error_get_last(); 0157 Zend_Cache::throwException("Can't serialize callback object to generate id: {$lastErr['message']}"); 0158 } 0159 $name.= '__' . $tmp; 0160 } 0161 0162 // generate a unique id for arguments 0163 $argsStr = ''; 0164 if ($args) { 0165 try { 0166 $argsStr = @serialize(array_values($args)); 0167 } catch (Exception $e) { 0168 Zend_Cache::throwException($e->getMessage()); 0169 } 0170 if (!$argsStr) { 0171 $lastErr = error_get_last(); 0172 throw Zend_Cache::throwException("Can't serialize arguments to generate id: {$lastErr['message']}"); 0173 } 0174 } 0175 0176 return md5($name . $argsStr); 0177 } 0178 0179 }