XCache.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <?php
  2. /**
  3. * Lithium: the most rad php framework
  4. *
  5. * @copyright Copyright 2013, Union of RAD (http://union-of-rad.org)
  6. * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7. */
  8. namespace lithium\storage\cache\adapter;
  9. /**
  10. * An XCache opcode cache adapter implementation.
  11. *
  12. * The XCache adapter is meant to be used through the `Cache` interface,
  13. * which abstracts away key generation, adapter instantiation and filter
  14. * implementation.
  15. *
  16. * A simple configuration of this adapter can be accomplished in `config/bootstrap/cache.php`
  17. * as follows:
  18. *
  19. * {{{
  20. * use lithium\storage\Cache;
  21. *
  22. * Cache::config(array(
  23. * 'cache-config-name' => array(
  24. * 'adapter' => 'XCache',
  25. * 'username' => 'user',
  26. * 'password' => 'pass'
  27. * )
  28. * ));
  29. * }}}
  30. *
  31. * Note that the `username` and `password` configuration fields are only required if
  32. * you wish to use `XCache::clear()` - all other methods do not require XCache administrator
  33. * credentials.
  34. *
  35. * This XCache adapter provides basic support for `write`, `read`, `delete`
  36. * and `clear` cache functionality, as well as allowing the first four
  37. * methods to be filtered as per the Lithium filtering system.
  38. *
  39. * This adapter does *not* allow multi-key operations for any methods.
  40. *
  41. * @see lithium\storage\Cache::key()
  42. * @see lithium\storage\cache\adapter
  43. */
  44. class XCache extends \lithium\core\Object {
  45. /**
  46. * Class constructor.
  47. *
  48. * @param array $config
  49. */
  50. public function __construct(array $config = array()) {
  51. $defaults = array('prefix' => '', 'expiry' => '+1 hour');
  52. parent::__construct($config + $defaults);
  53. }
  54. /**
  55. * Write value(s) to the cache
  56. *
  57. * @param string $key The key to uniquely identify the cached item
  58. * @param mixed $data The value to be cached
  59. * @param null|string $expiry A strtotime() compatible cache time. If no expiry time is set,
  60. * then the default cache expiration time set with the cache configuration will be used.
  61. * @return closure Function returning boolean `true` on successful write, `false` otherwise.
  62. */
  63. public function write($key, $data, $expiry = null) {
  64. $expiry = ($expiry) ?: $this->_config['expiry'];
  65. return function($self, $params) use ($expiry) {
  66. return xcache_set($params['key'], $params['data'], strtotime($expiry) - time());
  67. };
  68. }
  69. /**
  70. * Read value(s) from the cache
  71. *
  72. * @param string $key The key to uniquely identify the cached item
  73. * @return closure Function returning cached value if successful, `false` otherwise
  74. */
  75. public function read($key) {
  76. return function($self, $params) {
  77. return xcache_get($params['key']);
  78. };
  79. }
  80. /**
  81. * Delete value from the cache
  82. *
  83. * @param string $key The key to uniquely identify the cached item
  84. * @return closure Function returning boolean `true` on successful delete, `false` otherwise
  85. */
  86. public function delete($key) {
  87. return function($self, $params) {
  88. return xcache_unset($params['key']);
  89. };
  90. }
  91. /**
  92. * Performs an atomic decrement operation on specified numeric cache item.
  93. *
  94. * Note that, as per the XCache specification:
  95. * If the item's value is not numeric, it is treated as if the value were 0.
  96. * It is possible to decrement a value into the negative integers.
  97. *
  98. * @param string $key Key of numeric cache item to decrement
  99. * @param integer $offset Offset to decrement - defaults to 1.
  100. * @return closure Function returning item's new value on successful decrement, else `false`
  101. */
  102. public function decrement($key, $offset = 1) {
  103. return function($self, $params) use ($offset) {
  104. return xcache_dec($params['key'], $offset);
  105. };
  106. }
  107. /**
  108. * Performs an atomic increment operation on specified numeric cache item.
  109. *
  110. * Note that, as per the XCache specification:
  111. * If the item's value is not numeric, it is treated as if the value were 0.
  112. *
  113. * @param string $key Key of numeric cache item to increment
  114. * @param integer $offset Offset to increment - defaults to 1.
  115. * @return closure Function returning item's new value on successful increment, else `false`
  116. */
  117. public function increment($key, $offset = 1) {
  118. return function($self, $params) use ($offset) {
  119. extract($params);
  120. return xcache_inc($params['key'], $offset);
  121. };
  122. }
  123. /**
  124. * Clears user-space cache.
  125. *
  126. * This method requires valid XCache admin credentials to be set when the
  127. * adapter was configured, due to the use of the xcache_clear_cache admin method.
  128. *
  129. * If the xcache.admin.enable_auth ini setting is set to "Off", no credentials
  130. * required.
  131. *
  132. * @return mixed True on successful clear, false otherwise.
  133. */
  134. public function clear() {
  135. $admin = (ini_get('xcache.admin.enable_auth') === "On");
  136. if ($admin && (!isset($this->_config['username']) || !isset($this->_config['password']))) {
  137. return false;
  138. }
  139. $credentials = array();
  140. if (isset($_SERVER['PHP_AUTH_USER'])) {
  141. $credentials['username'] = $_SERVER['PHP_AUTH_USER'];
  142. $_SERVER['PHP_AUTH_USER'] = $this->_config['username'];
  143. }
  144. if (isset($_SERVER['PHP_AUTH_PW'])) {
  145. $credentials['password'] = $_SERVER['PHP_AUTH_PW'];
  146. $_SERVER['PHP_AUTH_PW'] = $this->_config['pass'];
  147. }
  148. for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++) {
  149. if (xcache_clear_cache(XC_TYPE_VAR, $i) === false) {
  150. return false;
  151. }
  152. }
  153. if (isset($_SERVER['PHP_AUTH_USER'])) {
  154. $_SERVER['PHP_AUTH_USER'] = $credentials['username'];
  155. }
  156. if (isset($_SERVER['PHP_AUTH_PW'])) {
  157. $_SERVER['PHP_AUTH_PW'] = $credentials['password'];
  158. }
  159. return true;
  160. }
  161. /**
  162. * Determines if the XCache extension has been installed and
  163. * if the userspace cache is available.
  164. *
  165. * return boolean True if enabled, false otherwise
  166. * @return boolean
  167. */
  168. public static function enabled() {
  169. return extension_loaded('xcache');
  170. }
  171. }
  172. ?>