4 * This class extends Cache_Lite and can be used to cache the result and output of functions/methods
6 * This class is completly inspired from Sebastian Bergmann's
7 * PEAR/Cache_Function class. This is only an adaptation to
10 * There are some examples in the 'docs/examples' file
11 * Technical choices are described in the 'docs/technical' file
14 * @version $Id: Function.php,v 1.10 2006/02/04 18:36:36 fab Exp $
15 * @author Sebastian BERGMANN <sb@sebastian-bergmann.de>
16 * @author Fabien MARTY <fab@php.net>
19 require_once('Cache/Lite.php');
21 class Cache_Lite_Function
extends Cache_Lite
24 // --- Private properties ---
27 * Default cache group for function caching
29 * @var string $_defaultGroup
31 var $_defaultGroup = 'Cache_Lite_Function';
34 * Don't cache the method call when its output contains the string "NOCACHE"
36 * if set to true, the output of the method will never be displayed (because the output is used
37 * to control the cache)
39 * @var boolean $_dontCacheWhenTheOutputContainsNOCACHE
41 var $_dontCacheWhenTheOutputContainsNOCACHE = false;
44 * Don't cache the method call when its result is false
46 * @var boolean $_dontCacheWhenTheResultIsFalse
48 var $_dontCacheWhenTheResultIsFalse = false;
51 * Don't cache the method call when its result is null
53 * @var boolean $_dontCacheWhenTheResultIsNull
55 var $_dontCacheWhenTheResultIsNull = false;
58 * Debug the Cache_Lite_Function caching process
60 * @var boolean $_debugCacheLiteFunction
62 var $_debugCacheLiteFunction = false;
64 // --- Public methods ----
69 * $options is an assoc. To have a look at availables options,
70 * see the constructor of the Cache_Lite class in 'Cache_Lite.php'
72 * Comparing to Cache_Lite constructor, there is another option :
74 * (...) see Cache_Lite constructor
75 * 'debugCacheLiteFunction' => (bool) debug the caching process,
76 * 'defaultGroup' => default cache group for function caching (string),
77 * 'dontCacheWhenTheOutputContainsNOCACHE' => (bool) don't cache when the function output contains "NOCACHE",
78 * 'dontCacheWhenTheResultIsFalse' => (bool) don't cache when the function result is false,
79 * 'dontCacheWhenTheResultIsNull' => (bool don't cache when the function result is null
82 * @param array $options options
85 function Cache_Lite_Function($options = array(NULL))
87 $availableOptions = array('debugCacheLiteFunction', 'defaultGroup', 'dontCacheWhenTheOutputContainsNOCACHE', 'dontCacheWhenTheResultIsFalse', 'dontCacheWhenTheResultIsNull');
88 while (list($name, $value) = each($options)) {
89 if (in_array($name, $availableOptions)) {
90 $property = '_'.$name;
91 $this->$property = $value;
95 $this->Cache_Lite($options);
99 * Calls a cacheable function or method (or not if there is already a cache for it)
101 * Arguments of this method are read with func_get_args. So it doesn't appear
102 * in the function definition. Synopsis :
103 * call('functionName', $arg1, $arg2, ...)
104 * (arg1, arg2... are arguments of 'functionName')
106 * @return mixed result of the function/method
111 $arguments = func_get_args();
112 $id = $this->_makeId($arguments);
113 $data = $this->get($id, $this->_defaultGroup
);
114 if ($data !== false) {
115 if ($this->_debugCacheLiteFunction
) {
116 echo "Cache hit !\n";
118 $array = unserialize($data);
119 $output = $array['output'];
120 $result = $array['result'];
122 if ($this->_debugCacheLiteFunction
) {
123 echo "Cache missed !\n";
126 ob_implicit_flush(false);
127 $target = array_shift($arguments);
128 if (is_array($target)) {
129 // in this case, $target is for example array($obj, 'method')
130 $object = $target[0];
131 $method = $target[1];
132 $result = call_user_func_array(array(&$object, $method), $arguments);
134 if (strstr($target, '::')) { // classname::staticMethod
135 list($class, $method) = explode('::', $target);
136 $result = call_user_func_array(array($class, $method), $arguments);
137 } else if (strstr($target, '->')) { // object->method
138 // use a stupid name ($objet_123456789 because) of problems where the object
139 // name is the same as this var name
140 list($object_123456789, $method) = explode('->', $target);
141 global $
$object_123456789;
142 $result = call_user_func_array(array($
$object_123456789, $method), $arguments);
144 $result = call_user_func_array($target, $arguments);
147 $output = ob_get_contents();
149 if ($this->_dontCacheWhenTheResultIsFalse
) {
150 if ((is_bool($result)) && (!($result))) {
155 if ($this->_dontCacheWhenTheResultIsNull
) {
156 if (is_null($result)) {
161 if ($this->_dontCacheWhenTheOutputContainsNOCACHE
) {
162 if (strpos($output, 'NOCACHE') > -1) {
166 $array['output'] = $output;
167 $array['result'] = $result;
168 $this->save(serialize($array), $id, $this->_defaultGroup
);
177 * Arguments of this method are read with func_get_args. So it doesn't appear
178 * in the function definition. Synopsis :
179 * remove('functionName', $arg1, $arg2, ...)
180 * (arg1, arg2... are arguments of 'functionName')
182 * @return boolean true if no problem
187 $id = $this->_makeId(func_get_args());
188 $this->remove($id, $this->_defaultGroup
);
192 * Make an id for the cache
194 * @var array result of func_get_args for the call() or the remove() method
198 function _makeId($arguments)
200 $id = serialize($arguments); // Generate a cache id
201 if (!$this->_fileNameProtection
) {
203 // if fileNameProtection is set to false, then the id has to be hashed
204 // because it's a very bad file name in most cases