<?php/*** memcached driver for PEAR::Cache using PECL::memcache** This driver uses the PECL memcache extension to PHP.* see http://www.php.net/manual/en/ref.memcache.php** You can use as many memcached servers as you want, you* just have to put them in the constructor options list like this:** $options = array('servers' => array('server1:11211', 'server1:11211', 'server1:11211'));** PHP versions 4 and 5** LICENSE: This source file is subject to version 3.0 of the PHP license* that is available through the world-wide-web at the following URI:* http://www.php.net/license/3_0.txt. If you did not receive a copy of* the PHP License and are unable to obtain it through the web, please* send a note to license@php.net so we can mail you a copy immediately.** @category Cache* @package Cache* @author Dieter Rothacker <dieter.rothacker@dmc.de>* @copyright 1997-2007 dmc digital media center GmbH* @license http://www.php.net/license/3_0.txt PHP License 3.0* @version CVS: $Id: $* @link http://pear.php.net/package/Cache* @see Cache/Container.php* @since File available since Release 1.5.6*/require_once 'Cache/Container.php';/*** memcached container driver class using PECL::memcache methods** @category Cache* @package Cache* @author Dieter Rothacker <dieter.rothacker@dmc.de>* @copyright 1997-2007 dmc digital media center GmbH* @license http://www.php.net/license/3_0.txt PHP License 3.0* @version 1.0.0* @link http://pear.php.net/package/Cache*/class Cache_Container_mcd_pecl extends Cache_Container{ /** * the classes version * * @access private * @var string $version */ var $version = '1.0.0'; /** * instance of memcache * * @access private * @var object $memcache */ var $memcache = null; /** * list of possible servers to connect to * * @access private * @var array $servers */ var $servers = array('localhost:11211'); /** * Options that can be set. Overriden from parent. * Lowwater + Highwater omitted on purpose because they have to be set * when initializing the memcached daemon * * @var array */ var $allowedOptions = array('encoding_mode', 'servers'); /** * PHP4 constructor * * @param array $options array 'server' has to contain 'ip:port' elements * * @access public * @return void */ function Cache_Container_mcd_pecl($options) { /* register destructor */ register_shutdown_function(array(&$this, '__destruct')); /* call real constructor */ $this->__construct($options); } /* end func Cache_Container_mcd_pecl */ /** * constructor * * @param array $options array 'server' has to contain 'ip:port' elements * * @access public * @return */ function __construct($options) { if (is_array($options)) { $this->setOptions($options, $this->allowedOptions); } if (extension_loaded('memcache')) { $this->memcache = new Memcache; // Add all memcache servers to connection pool, pecl::memcache handles connections itself for ($i = 0; $i < count($this->servers); $i++) { $server = explode(':', $this->servers[$i]); $this->memcache->addServer($server[0], $server[1]); } } else { die('PECL::memcache extension not loaded!'); return false; } return; } /* end func __construct */ /** * destructor * * @access public * @return void */ function __destruct() { // nothing to be done, memcache cleans up itself } /* end func __destruct */ /** * Fetches a dataset from the storage medium. * * @param string $id dataset ID * @param string $group cache groups are not supported * * @return mixed $returnValue array (format: [expire date, cached data, userdata]) or Cache_Error * @access public */ function fetch($id, $group) { $data = false; //new $returnValue = false; if (PEAR::isError($this->memcache)) { $returnValue = new Cache_Error('Could not fetch data', __FILE__, __LINE__); } else { $getValue = $this->memcache->get($id); // returns array or empty string // var_dump($getValue); $returnValue = $this->decode($getValue); } return $returnValue; } /* end func fetch */ /** * Removes a dataset. * * @param string $id dataset ID * @param string $group cache groups are not supported * * @return boolean $returnValue true, if dataset was removed else false/Cache_Error * @access public */ function remove($id, $group) { $returnValue = null; if (PEAR::isError($this->memcache)) { $returnValue = new Cache_Error('Could not remove data', __FILE__, __LINE__); } else { $returnValue = $this->memcache->delete($id); } return $returnValue; } /* end func remove */ /** * Returns the userdata field of a cached data set. * * @param string $id dataset ID * @param string $group cache groups are not supported * * @return string $returnValue userdata or empty string/Cache_Error * @access public */ function getUserdata($id, $group) { if (PEAR::isError($this->memcache)) { $returnValue = new Cache_Error('Could not fetch userdata', __FILE__, __LINE__); } else { $resultValue = $this->fetch($id, null); if ($resultValue != '') { $resultValue = $resultValue[2]; } } return $resultValue; } /* end func getUserdata */ /** * Stores a dataset. * * @param string $id dataset ID * @param mixed $data data to store * @param integer $expire expire date in seconds * @param string $group cache groups are not supported * @param string $userdata userdefined data * * @return mixed $returnValue Cache_Error or true if data was saved * @access public */ function save($id, $data, $expire, $group, $userdata) { $returnValue = false; $userdata = (integer) $userdata; if (is_null($id)) { $returnValue = new Cache_Error('Key error -> Key is needed to identify data', __FILE__, __LINE__); } if (!is_numeric($userdata) || ($userdata < 0) || ($userdata > pow(2, 16))) { $returnValue = new Cache_Error('Flag error -> Value has to be an unsigned 16bit int', __FILE__, __LINE__); } if (!is_numeric($expire) || ($expire < 0)) { $returnValue = new Cache_Error('Expire time error -> Value has to be an unsigned int', __FILE__, __LINE__); } // is_a($returnValue, 'Cache_Error') if (!PEAR::isError($returnValue)) { /* we put expiration time and userdata into cache data because * memcache provides no functionality to read the * expiration time and userdata of an already stored cache item */ $cacheData = $this->encode(array( time() + $expire, $data, $userdata)); $returnValue = $this->memcache->set($id, $cacheData, 0, $expire); } else { $returnValue = new Cache_Error('Could not save data', __FILE__, __LINE__); } return $returnValue; } /* end func save */ /** * Checks if a dataset is cached. * * @param string $id dataset ID * @param string $group cache groups are not supported * * @return boolean $returnValue true if data is cached, else false/Cache_Error * @access public */ function isCached($id, $group) { $returnValue = false; if (PEAR::isError($this->memcache)) { $returnValue = new Cache_Error('Could not check if data is cached', __FILE__, __LINE__); } else { $returnValue = $this->fetch($id, $group); if (!PEAR::isError($returnValue)) { if ('' == $returnValue) { $returnValue = false; } else { $returnValue = true; } } } return $returnValue; } /* end func isCached */ /** * Checks if data is expired for future time. * if it is expired, memcache daemon removes it from memory automatically * * @param string $id dataset ID * @param string $group cache groups are not supported * @param string $max_age maximum cache item age * * @return boolean $returnValue true if data is expired or not cached, else false/Cache_Error * @access public */ function isExpired($id, $group, $max_age) { $returnValue = false; $returnValue = $this->isCached($id, $group); if (!PEAR::isError($returnValue)) { $fetchResult = $this->fetch($id, $group); if (!PEAR::isError($fetchResult)) { $expireDate = $fetchResult[0]; // is data expired for future date? if ((time() + $max_age) <= $expireDate) { $returnValue = false; } else { $returnValue = true; } } else { $returnValue = $fetchResult; // fetch-Error } } else { $returnValue = new Cache_Error('Could not check if data is expired', __FILE__, __LINE__); } return $returnValue; } /* end func isExpired */ /** * Flushes the cache - removes all cached datasets from the cache. * * @param string $group cache groups are not supported * * @return boolen $returnValue true if data was flushed, else false/Cache_Error * @access public */ function flush($group) { $returnValue = false; if (PEAR::isError($this->memcache)) { $returnValue = new Cache_Error('Could not flush data', __FILE__, __LINE__); } else { $returnValue = $this->memcache->flush(); } return $returnValue; } /* end func flush */}?>