Overview

Classes

  • Horde_Autoloader_Cache
  • Overview
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Decorator for Horde_Autoloader that implements caching of class-file-maps.
  4:  *
  5:  * @author   Jan Schneider <jan@horde.org>
  6:  * @category Horde
  7:  * @package  Autoloader_Cache
  8:  */
  9: require_once 'Horde/Autoloader/Default.php';
 10: 
 11: class Horde_Autoloader_Cache extends Horde_Autoloader_Default
 12: {
 13:     /* Cache types. */
 14:     const APC = 1;
 15:     const XCACHE = 2;
 16:     const EACCELERATOR = 3;
 17:     const TEMPFILE = 4;
 18: 
 19:     /**
 20:      * Map of all classes already looked up.
 21:      *
 22:      * @var array
 23:      */
 24:     protected $_cache = array();
 25: 
 26:     /**
 27:      * THe cache type.
 28:      *
 29:      * @var array
 30:      */
 31:     protected $_cachetype;
 32: 
 33:     /**
 34:      * Cache key name.
 35:      *
 36:      * @var string
 37:      */
 38:     protected $_cachekey = 'horde_autoloader_cache';
 39: 
 40:     /**
 41:      * Has the cache changed since the last save?
 42:      *
 43:      * @var boolean
 44:      */
 45:     protected $_changed = false;
 46: 
 47:     /**
 48:      * Cached value of the temporary directory.
 49:      *
 50:      * @var string
 51:      */
 52:     protected $_tempdir;
 53: 
 54:     /**
 55:      * Constructor.
 56:      *
 57:      * Tries all supported cache backends and tries to retrieved the cached
 58:      * class map.
 59:      */
 60:     public function __construct()
 61:     {
 62:         parent::__construct();
 63: 
 64:         if (isset($_SERVER['SERVER_NAME'])) {
 65:             $this->_cachekey .= '|' . $_SERVER['SERVER_NAME'];
 66:         }
 67:         $this->_cachekey .= '|' . __FILE__;
 68: 
 69:         if (extension_loaded('apc')) {
 70:             $this->_cache = apc_fetch($this->_cachekey);
 71:             $this->_cachetype = self::APC;
 72:         } elseif (extension_loaded('xcache')) {
 73:             $this->_cache = xcache_get($this->_cachekey);
 74:             $this->_cachetype = self::XCACHE;
 75:         } elseif (extension_loaded('eaccelerator')) {
 76:             $this->_cache = eaccelerator_get($this->_cachekey);
 77:             $this->_cachetype = self::EACCELERATOR;
 78:         } elseif (($this->_tempdir = sys_get_temp_dir()) &&
 79:                   is_readable($this->_tempdir)) {
 80:             $this->_cachekey = hash('md5', $this->_cachekey);
 81:             if (($data = file_get_contents($this->_tempdir . '/' . $this->_cachekey)) !== false) {
 82:                 $this->_cache = @json_decode($data, true);
 83:             }
 84:             $this->_cachetype = self::TEMPFILE;
 85:         }
 86:     }
 87: 
 88:     /**
 89:      * Destructor.
 90:      *
 91:      * Tries all supported cache backends and tries to save the class map to
 92:      * the cache.
 93:      */
 94:     public function __destruct()
 95:     {
 96:         if (!$this->_changed) {
 97:             return;
 98:         }
 99: 
100:         switch ($this->_cachetype) {
101:         case self::APC:
102:             apc_store($this->_cachekey, $this->_cache);
103:             break;
104: 
105:         case self::XCACHE:
106:             xcache_set($this->_cachekey, $this->_cache);
107:             break;
108: 
109:         case self::EACCELERATOR:
110:             eaccelerator_put($this->_cachekey, $this->_cache);
111:             break;
112: 
113:         case self::TEMPFILE:
114:             file_put_contents($this->_tempdir . '/' . $this->_cachekey, json_encode($this->_cache));
115:             break;
116:         }
117:     }
118: 
119:     /**
120:      * Search registered mappers in LIFO order.
121:      *
122:      * @param string $className  TODO.
123:      *
124:      * @return string  TODO
125:      */
126:     public function mapToPath($className)
127:     {
128:         if (!$this->_cache) {
129:             $this->_cache = array();
130:         }
131:         if (!array_key_exists($className, $this->_cache)) {
132:             $this->_cache[$className] = parent::mapToPath($className);
133:             $this->_changed = true;
134:         }
135: 
136:         return $this->_cache[$className];
137:     }
138: 
139:     /**
140:      * Prunes the autoloader cache.
141:      *
142:      * @return boolean  True if pruning succeeded.
143:      */
144:     public function prune()
145:     {
146:         if (extension_loaded('apc')) {
147:             return apc_delete($this->_cachekey);
148:         }
149:         if (extension_loaded('xcache')) {
150:             return xcache_unset($this->_cachekey);
151:         }
152:         if (extension_loaded('eaccelerator')) {
153:             /* Undocumented, unknown return value. */
154:             eaccelerator_rm($this->_cachekey);
155:             return true;
156:         }
157:         if ($this->_tempdir) {
158:             return unlink($this->_tempdir . '/' . $this->_cachekey);
159:         }
160:         return false;
161:     }
162: }
163: 
164: spl_autoload_unregister(array($__autoloader, 'loadClass'));
165: $__autoloader = new Horde_Autoloader_Cache();
166: $__autoloader->registerAutoloader();
167: 
API documentation generated by ApiGen