web/lib/Zend/Cache/Frontend/Class.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     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.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Cache
       
    17  * @subpackage Zend_Cache_Frontend
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: Class.php 23051 2010-10-07 17:01:21Z mabe $
       
    21  */
       
    22 
       
    23 /**
       
    24  * @see Zend_Cache_Core
       
    25  */
       
    26 require_once 'Zend/Cache/Core.php';
       
    27 
       
    28 
       
    29 /**
       
    30  * @package    Zend_Cache
       
    31  * @subpackage Zend_Cache_Frontend
       
    32  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    33  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    34  */
       
    35 class Zend_Cache_Frontend_Class extends Zend_Cache_Core
       
    36 {
       
    37     /**
       
    38      * Available options
       
    39      *
       
    40      * ====> (mixed) cached_entity :
       
    41      * - if set to a class name, we will cache an abstract class and will use only static calls
       
    42      * - if set to an object, we will cache this object methods
       
    43      *
       
    44      * ====> (boolean) cache_by_default :
       
    45      * - if true, method calls will be cached by default
       
    46      *
       
    47      * ====> (array) cached_methods :
       
    48      * - an array of method names which will be cached (even if cache_by_default = false)
       
    49      *
       
    50      * ====> (array) non_cached_methods :
       
    51      * - an array of method names which won't be cached (even if cache_by_default = true)
       
    52      *
       
    53      * @var array available options
       
    54      */
       
    55     protected $_specificOptions = array(
       
    56         'cached_entity' => null,
       
    57         'cache_by_default' => true,
       
    58         'cached_methods' => array(),
       
    59         'non_cached_methods' => array()
       
    60     );
       
    61 
       
    62     /**
       
    63      * Tags array
       
    64      *
       
    65      * @var array
       
    66      */
       
    67     private $_tags = array();
       
    68 
       
    69     /**
       
    70      * SpecificLifetime value
       
    71      *
       
    72      * false => no specific life time
       
    73      *
       
    74      * @var int
       
    75      */
       
    76     private $_specificLifetime = false;
       
    77 
       
    78     /**
       
    79      * The cached object or the name of the cached abstract class
       
    80      *
       
    81      * @var mixed
       
    82      */
       
    83     private $_cachedEntity = null;
       
    84 
       
    85      /**
       
    86       * The class name of the cached object or cached abstract class
       
    87       *
       
    88       * Used to differentiate between different classes with the same method calls.
       
    89       *
       
    90       * @var string
       
    91       */
       
    92     private $_cachedEntityLabel = '';
       
    93 
       
    94     /**
       
    95      * Priority (used by some particular backends)
       
    96      *
       
    97      * @var int
       
    98      */
       
    99     private $_priority = 8;
       
   100 
       
   101     /**
       
   102      * Constructor
       
   103      *
       
   104      * @param  array $options Associative array of options
       
   105      * @throws Zend_Cache_Exception
       
   106      * @return void
       
   107      */
       
   108     public function __construct(array $options = array())
       
   109     {
       
   110         while (list($name, $value) = each($options)) {
       
   111             $this->setOption($name, $value);
       
   112         }
       
   113         if ($this->_specificOptions['cached_entity'] === null) {
       
   114             Zend_Cache::throwException('cached_entity must be set !');
       
   115         }
       
   116         $this->setCachedEntity($this->_specificOptions['cached_entity']);
       
   117         $this->setOption('automatic_serialization', true);
       
   118     }
       
   119 
       
   120     /**
       
   121      * Set a specific life time
       
   122      *
       
   123      * @param  int $specificLifetime
       
   124      * @return void
       
   125      */
       
   126     public function setSpecificLifetime($specificLifetime = false)
       
   127     {
       
   128         $this->_specificLifetime = $specificLifetime;
       
   129     }
       
   130 
       
   131     /**
       
   132      * Set the priority (used by some particular backends)
       
   133      *
       
   134      * @param int $priority integer between 0 (very low priority) and 10 (maximum priority)
       
   135      */
       
   136     public function setPriority($priority)
       
   137     {
       
   138         $this->_priority = $priority;
       
   139     }
       
   140 
       
   141     /**
       
   142      * Public frontend to set an option
       
   143      *
       
   144      * Just a wrapper to get a specific behaviour for cached_entity
       
   145      *
       
   146      * @param  string $name  Name of the option
       
   147      * @param  mixed  $value Value of the option
       
   148      * @throws Zend_Cache_Exception
       
   149      * @return void
       
   150      */
       
   151     public function setOption($name, $value)
       
   152     {
       
   153         if ($name == 'cached_entity') {
       
   154             $this->setCachedEntity($value);
       
   155         } else {
       
   156             parent::setOption($name, $value);
       
   157         }
       
   158     }
       
   159 
       
   160     /**
       
   161      * Specific method to set the cachedEntity
       
   162      *
       
   163      * if set to a class name, we will cache an abstract class and will use only static calls
       
   164      * if set to an object, we will cache this object methods
       
   165      *
       
   166      * @param mixed $cachedEntity
       
   167      */
       
   168     public function setCachedEntity($cachedEntity)
       
   169     {
       
   170         if (!is_string($cachedEntity) && !is_object($cachedEntity)) {
       
   171             Zend_Cache::throwException('cached_entity must be an object or a class name');
       
   172         }
       
   173         $this->_cachedEntity = $cachedEntity;
       
   174         $this->_specificOptions['cached_entity'] = $cachedEntity;
       
   175         if (is_string($this->_cachedEntity)){
       
   176             $this->_cachedEntityLabel = $this->_cachedEntity;
       
   177         } else {
       
   178             $ro = new ReflectionObject($this->_cachedEntity);
       
   179             $this->_cachedEntityLabel = $ro->getName();
       
   180         }
       
   181     }
       
   182 
       
   183     /**
       
   184      * Set the cache array
       
   185      *
       
   186      * @param  array $tags
       
   187      * @return void
       
   188      */
       
   189     public function setTagsArray($tags = array())
       
   190     {
       
   191         $this->_tags = $tags;
       
   192     }
       
   193 
       
   194     /**
       
   195      * Main method : call the specified method or get the result from cache
       
   196      *
       
   197      * @param  string $name       Method name
       
   198      * @param  array  $parameters Method parameters
       
   199      * @return mixed Result
       
   200      */
       
   201     public function __call($name, $parameters)
       
   202     {
       
   203         $cacheBool1 = $this->_specificOptions['cache_by_default'];
       
   204         $cacheBool2 = in_array($name, $this->_specificOptions['cached_methods']);
       
   205         $cacheBool3 = in_array($name, $this->_specificOptions['non_cached_methods']);
       
   206         $cache = (($cacheBool1 || $cacheBool2) && (!$cacheBool3));
       
   207         if (!$cache) {
       
   208             // We do not have not cache
       
   209             return call_user_func_array(array($this->_cachedEntity, $name), $parameters);
       
   210         }
       
   211 
       
   212         $id = $this->_makeId($name, $parameters);
       
   213         if ( ($rs = $this->load($id)) && isset($rs[0], $rs[1]) ) {
       
   214             // A cache is available
       
   215             $output = $rs[0];
       
   216             $return = $rs[1];
       
   217         } else {
       
   218             // A cache is not available (or not valid for this frontend)
       
   219             ob_start();
       
   220             ob_implicit_flush(false);
       
   221 
       
   222             try {
       
   223                 $return = call_user_func_array(array($this->_cachedEntity, $name), $parameters);
       
   224                 $output = ob_get_clean();
       
   225                 $data = array($output, $return);
       
   226                 $this->save($data, $id, $this->_tags, $this->_specificLifetime, $this->_priority);
       
   227             } catch (Exception $e) {
       
   228                 ob_end_clean();
       
   229                 throw $e;
       
   230             }
       
   231         }
       
   232 
       
   233         echo $output;
       
   234         return $return;
       
   235     }
       
   236 
       
   237     /**
       
   238      * ZF-9970
       
   239      *
       
   240      * @deprecated
       
   241      */
       
   242     private function _makeId($name, $args)
       
   243     {
       
   244         return $this->makeId($name, $args);
       
   245     }
       
   246 
       
   247     /**
       
   248      * Make a cache id from the method name and parameters
       
   249      *
       
   250      * @param  string $name Method name
       
   251      * @param  array  $args Method parameters
       
   252      * @return string Cache id
       
   253      */
       
   254     public function makeId($name, array $args = array())
       
   255     {
       
   256         return md5($this->_cachedEntityLabel . '__' . $name . '__' . serialize($args));
       
   257     }
       
   258 
       
   259 }