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_Backend
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_Backend_Interface
0026  */
0027 // require_once 'Zend/Cache/Backend/Interface.php';
0028 
0029 /**
0030  * @see Zend_Cache_Backend
0031  */
0032 // require_once 'Zend/Cache/Backend.php';
0033 
0034 
0035 /**
0036  * @package    Zend_Cache
0037  * @subpackage Zend_Cache_Backend
0038  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0039  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0040  */
0041 class Zend_Cache_Backend_Xcache extends Zend_Cache_Backend implements Zend_Cache_Backend_Interface
0042 {
0043 
0044     /**
0045      * Log message
0046      */
0047     const TAGS_UNSUPPORTED_BY_CLEAN_OF_XCACHE_BACKEND = 'Zend_Cache_Backend_Xcache::clean() : tags are unsupported by the Xcache backend';
0048     const TAGS_UNSUPPORTED_BY_SAVE_OF_XCACHE_BACKEND =  'Zend_Cache_Backend_Xcache::save() : tags are unsupported by the Xcache backend';
0049 
0050     /**
0051      * Available options
0052      *
0053      * =====> (string) user :
0054      * xcache.admin.user (necessary for the clean() method)
0055      *
0056      * =====> (string) password :
0057      * xcache.admin.pass (clear, not MD5) (necessary for the clean() method)
0058      *
0059      * @var array available options
0060      */
0061     protected $_options = array(
0062         'user' => null,
0063         'password' => null
0064     );
0065 
0066     /**
0067      * Constructor
0068      *
0069      * @param  array $options associative array of options
0070      * @throws Zend_Cache_Exception
0071      * @return void
0072      */
0073     public function __construct(array $options = array())
0074     {
0075         if (!extension_loaded('xcache')) {
0076             Zend_Cache::throwException('The xcache extension must be loaded for using this backend !');
0077         }
0078         parent::__construct($options);
0079     }
0080 
0081     /**
0082      * Test if a cache is available for the given id and (if yes) return it (false else)
0083      *
0084      * WARNING $doNotTestCacheValidity=true is unsupported by the Xcache backend
0085      *
0086      * @param  string  $id                     cache id
0087      * @param  boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
0088      * @return string cached datas (or false)
0089      */
0090     public function load($id, $doNotTestCacheValidity = false)
0091     {
0092         if ($doNotTestCacheValidity) {
0093             $this->_log("Zend_Cache_Backend_Xcache::load() : \$doNotTestCacheValidity=true is unsupported by the Xcache backend");
0094         }
0095         $tmp = xcache_get($id);
0096         if (is_array($tmp)) {
0097             return $tmp[0];
0098         }
0099         return false;
0100     }
0101 
0102     /**
0103      * Test if a cache is available or not (for the given id)
0104      *
0105      * @param  string $id cache id
0106      * @return mixed false (a cache is not available) or "last modified" timestamp (int) of the available cache record
0107      */
0108     public function test($id)
0109     {
0110         if (xcache_isset($id)) {
0111             $tmp = xcache_get($id);
0112             if (is_array($tmp)) {
0113                 return $tmp[1];
0114             }
0115         }
0116         return false;
0117     }
0118 
0119     /**
0120      * Save some string datas into a cache record
0121      *
0122      * Note : $data is always "string" (serialization is done by the
0123      * core not by the backend)
0124      *
0125      * @param string $data datas to cache
0126      * @param string $id cache id
0127      * @param array $tags array of strings, the cache record will be tagged by each string entry
0128      * @param int $specificLifetime if != false, set a specific lifetime for this cache record (null => infinite lifetime)
0129      * @return boolean true if no problem
0130      */
0131     public function save($data, $id, $tags = array(), $specificLifetime = false)
0132     {
0133         $lifetime = $this->getLifetime($specificLifetime);
0134         $result = xcache_set($id, array($data, time()), $lifetime);
0135         if (count($tags) > 0) {
0136             $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_XCACHE_BACKEND);
0137         }
0138         return $result;
0139     }
0140 
0141     /**
0142      * Remove a cache record
0143      *
0144      * @param  string $id cache id
0145      * @return boolean true if no problem
0146      */
0147     public function remove($id)
0148     {
0149         return xcache_unset($id);
0150     }
0151 
0152     /**
0153      * Clean some cache records
0154      *
0155      * Available modes are :
0156      * 'all' (default)  => remove all cache entries ($tags is not used)
0157      * 'old'            => unsupported
0158      * 'matchingTag'    => unsupported
0159      * 'notMatchingTag' => unsupported
0160      * 'matchingAnyTag' => unsupported
0161      *
0162      * @param  string $mode clean mode
0163      * @param  array  $tags array of tags
0164      * @throws Zend_Cache_Exception
0165      * @return boolean true if no problem
0166      */
0167     public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array())
0168     {
0169         switch ($mode) {
0170             case Zend_Cache::CLEANING_MODE_ALL:
0171                 // Necessary because xcache_clear_cache() need basic authentification
0172                 $backup = array();
0173                 if (isset($_SERVER['PHP_AUTH_USER'])) {
0174                     $backup['PHP_AUTH_USER'] = $_SERVER['PHP_AUTH_USER'];
0175                 }
0176                 if (isset($_SERVER['PHP_AUTH_PW'])) {
0177                     $backup['PHP_AUTH_PW'] = $_SERVER['PHP_AUTH_PW'];
0178                 }
0179                 if ($this->_options['user']) {
0180                     $_SERVER['PHP_AUTH_USER'] = $this->_options['user'];
0181                 }
0182                 if ($this->_options['password']) {
0183                     $_SERVER['PHP_AUTH_PW'] = $this->_options['password'];
0184                 }
0185 
0186                 $cnt = xcache_count(XC_TYPE_VAR);
0187                 for ($i=0; $i < $cnt; $i++) {
0188                     xcache_clear_cache(XC_TYPE_VAR, $i);
0189                 }
0190 
0191                 if (isset($backup['PHP_AUTH_USER'])) {
0192                     $_SERVER['PHP_AUTH_USER'] = $backup['PHP_AUTH_USER'];
0193                     $_SERVER['PHP_AUTH_PW'] = $backup['PHP_AUTH_PW'];
0194                 }
0195                 return true;
0196                 break;
0197             case Zend_Cache::CLEANING_MODE_OLD:
0198                 $this->_log("Zend_Cache_Backend_Xcache::clean() : CLEANING_MODE_OLD is unsupported by the Xcache backend");
0199                 break;
0200             case Zend_Cache::CLEANING_MODE_MATCHING_TAG:
0201             case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG:
0202             case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG:
0203                 $this->_log(self::TAGS_UNSUPPORTED_BY_CLEAN_OF_XCACHE_BACKEND);
0204                 break;
0205             default:
0206                 Zend_Cache::throwException('Invalid mode for clean() method');
0207                 break;
0208         }
0209     }
0210 
0211     /**
0212      * Return true if the automatic cleaning is available for the backend
0213      *
0214      * @return boolean
0215      */
0216     public function isAutomaticCleaningAvailable()
0217     {
0218         return false;
0219     }
0220 
0221 }