XcacheEngine.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 1.2.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Cache\Engine;
  16. use Cake\Cache\CacheEngine;
  17. /**
  18. * Xcache storage engine for cache
  19. *
  20. * @link http://trac.lighttpd.net/xcache/ Xcache
  21. * @deprecated 3.6.0 Xcache engine has been deprecated and will be removed in 4.0.0.
  22. */
  23. class XcacheEngine extends CacheEngine
  24. {
  25. /**
  26. * The default config used unless overridden by runtime configuration
  27. *
  28. * - `duration` Specify how long items in this cache configuration last.
  29. * - `groups` List of groups or 'tags' associated to every key stored in this config.
  30. * handy for deleting a complete group from cache.
  31. * - `prefix` Prefix appended to all entries. Good for when you need to share a keyspace
  32. * with either another cache config or another application.
  33. * - `probability` Probability of hitting a cache gc cleanup. Setting to 0 will disable
  34. * cache::gc from ever being called automatically.
  35. * - `PHP_AUTH_USER` xcache.admin.user
  36. * - `PHP_AUTH_PW` xcache.admin.password
  37. *
  38. * @var array
  39. */
  40. protected $_defaultConfig = [
  41. 'duration' => 3600,
  42. 'groups' => [],
  43. 'prefix' => null,
  44. 'probability' => 100,
  45. 'PHP_AUTH_USER' => 'user',
  46. 'PHP_AUTH_PW' => 'password'
  47. ];
  48. /**
  49. * Initialize the Cache Engine
  50. *
  51. * Called automatically by the cache frontend
  52. *
  53. * @param array $config array of setting for the engine
  54. * @return bool True if the engine has been successfully initialized, false if not
  55. */
  56. public function init(array $config = [])
  57. {
  58. if (!extension_loaded('xcache')) {
  59. return false;
  60. }
  61. parent::init($config);
  62. return true;
  63. }
  64. /**
  65. * Write data for key into cache
  66. *
  67. * @param string $key Identifier for the data
  68. * @param mixed $value Data to be cached
  69. * @return bool True if the data was successfully cached, false on failure
  70. */
  71. public function write($key, $value)
  72. {
  73. $key = $this->_key($key);
  74. if (!is_numeric($value)) {
  75. $value = serialize($value);
  76. }
  77. $duration = $this->_config['duration'];
  78. $expires = time() + $duration;
  79. xcache_set($key . '_expires', $expires, $duration);
  80. return xcache_set($key, $value, $duration);
  81. }
  82. /**
  83. * Read a key from the cache
  84. *
  85. * @param string $key Identifier for the data
  86. * @return mixed The cached data, or false if the data doesn't exist,
  87. * has expired, or if there was an error fetching it
  88. */
  89. public function read($key)
  90. {
  91. $key = $this->_key($key);
  92. if (xcache_isset($key)) {
  93. $time = time();
  94. $cachetime = (int)xcache_get($key . '_expires');
  95. if ($cachetime < $time || ($time + $this->_config['duration']) < $cachetime) {
  96. return false;
  97. }
  98. $value = xcache_get($key);
  99. if (is_string($value) && !is_numeric($value)) {
  100. $value = unserialize($value);
  101. }
  102. return $value;
  103. }
  104. return false;
  105. }
  106. /**
  107. * Increments the value of an integer cached key
  108. * If the cache key is not an integer it will be treated as 0
  109. *
  110. * @param string $key Identifier for the data
  111. * @param int $offset How much to increment
  112. * @return bool|int New incremented value, false otherwise
  113. */
  114. public function increment($key, $offset = 1)
  115. {
  116. $key = $this->_key($key);
  117. return xcache_inc($key, $offset);
  118. }
  119. /**
  120. * Decrements the value of an integer cached key.
  121. * If the cache key is not an integer it will be treated as 0
  122. *
  123. * @param string $key Identifier for the data
  124. * @param int $offset How much to subtract
  125. * @return bool|int New decremented value, false otherwise
  126. */
  127. public function decrement($key, $offset = 1)
  128. {
  129. $key = $this->_key($key);
  130. return xcache_dec($key, $offset);
  131. }
  132. /**
  133. * Delete a key from the cache
  134. *
  135. * @param string $key Identifier for the data
  136. * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
  137. */
  138. public function delete($key)
  139. {
  140. $key = $this->_key($key);
  141. return xcache_unset($key);
  142. }
  143. /**
  144. * Delete all keys from the cache
  145. *
  146. * @param bool $check If true no deletes will occur and instead CakePHP will rely
  147. * on key TTL values.
  148. * Unused for Xcache engine.
  149. * @return bool True if the cache was successfully cleared, false otherwise
  150. */
  151. public function clear($check)
  152. {
  153. $this->_auth();
  154. $max = xcache_count(XC_TYPE_VAR);
  155. for ($i = 0; $i < $max; $i++) {
  156. xcache_clear_cache(XC_TYPE_VAR, $i);
  157. }
  158. $this->_auth(true);
  159. return true;
  160. }
  161. /**
  162. * Returns the `group value` for each of the configured groups
  163. * If the group initial value was not found, then it initializes
  164. * the group accordingly.
  165. *
  166. * @return array
  167. */
  168. public function groups()
  169. {
  170. $result = [];
  171. foreach ($this->_config['groups'] as $group) {
  172. $value = xcache_get($this->_config['prefix'] . $group);
  173. if (!$value) {
  174. $value = 1;
  175. xcache_set($this->_config['prefix'] . $group, $value, 0);
  176. }
  177. $result[] = $group . $value;
  178. }
  179. return $result;
  180. }
  181. /**
  182. * Increments the group value to simulate deletion of all keys under a group
  183. * old values will remain in storage until they expire.
  184. *
  185. * @param string $group The group to clear.
  186. * @return bool success
  187. */
  188. public function clearGroup($group)
  189. {
  190. return (bool)xcache_inc($this->_config['prefix'] . $group, 1);
  191. }
  192. /**
  193. * Populates and reverses $_SERVER authentication values
  194. * Makes necessary changes (and reverting them back) in $_SERVER
  195. *
  196. * This has to be done because xcache_clear_cache() needs to pass Basic Http Auth
  197. * (see xcache.admin configuration config)
  198. *
  199. * @param bool $reverse Revert changes
  200. * @return void
  201. */
  202. protected function _auth($reverse = false)
  203. {
  204. static $backup = [];
  205. $keys = ['PHP_AUTH_USER' => 'user', 'PHP_AUTH_PW' => 'password'];
  206. foreach ($keys as $key => $value) {
  207. if ($reverse) {
  208. if (isset($backup[$key])) {
  209. $_SERVER[$key] = $backup[$key];
  210. unset($backup[$key]);
  211. } else {
  212. unset($_SERVER[$key]);
  213. }
  214. } else {
  215. $value = env($key);
  216. if (!empty($value)) {
  217. $backup[$key] = $value;
  218. }
  219. if (!empty($this->_config[$value])) {
  220. $_SERVER[$key] = $this->_config[$value];
  221. } elseif (!empty($this->_config[$key])) {
  222. $_SERVER[$key] = $this->_config[$key];
  223. } else {
  224. $_SERVER[$key] = $value;
  225. }
  226. }
  227. }
  228. }
  229. }