/classes/cache/CacheMemcache.php

https://gitlab.com/jslee1/PrestaShop · PHP · 269 lines · 140 code · 23 blank · 106 comment · 24 complexity · 35d906a0e603fab5759908e912a11f25 MD5 · raw file

  1. <?php
  2. /**
  3. * 2007-2015 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2015 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. /**
  27. * This class require PECL Memcache extension
  28. *
  29. */
  30. class CacheMemcacheCore extends Cache
  31. {
  32. /**
  33. * @var Memcache
  34. */
  35. protected $memcache;
  36. /**
  37. * @var bool Connection status
  38. */
  39. protected $is_connected = false;
  40. public function __construct()
  41. {
  42. $this->connect();
  43. }
  44. public function __destruct()
  45. {
  46. $this->close();
  47. }
  48. /**
  49. * Connect to memcache server
  50. */
  51. public function connect()
  52. {
  53. if (class_exists('Memcache') && extension_loaded('memcache')) {
  54. $this->memcache = new Memcache();
  55. } else {
  56. return;
  57. }
  58. $servers = self::getMemcachedServers();
  59. if (!$servers) {
  60. return;
  61. }
  62. foreach ($servers as $server) {
  63. $this->memcache->addServer($server['ip'], $server['port'], true, (int)$server['weight']);
  64. }
  65. $this->is_connected = true;
  66. }
  67. /**
  68. * @see Cache::_set()
  69. */
  70. protected function _set($key, $value, $ttl = 0)
  71. {
  72. if (!$this->is_connected) {
  73. return false;
  74. }
  75. return $this->memcache->set($key, $value, 0, $ttl);
  76. }
  77. /**
  78. * @see Cache::_get()
  79. */
  80. protected function _get($key)
  81. {
  82. if (!$this->is_connected) {
  83. return false;
  84. }
  85. return $this->memcache->get($key);
  86. }
  87. /**
  88. * @see Cache::_exists()
  89. */
  90. protected function _exists($key)
  91. {
  92. if (!$this->is_connected) {
  93. return false;
  94. }
  95. return ($this->memcache->get($key) !== false);
  96. }
  97. /**
  98. * @see Cache::_delete()
  99. */
  100. protected function _delete($key)
  101. {
  102. if (!$this->is_connected) {
  103. return false;
  104. }
  105. return $this->memcache->delete($key);
  106. }
  107. /**
  108. * @see Cache::_writeKeys()
  109. */
  110. protected function _writeKeys()
  111. {
  112. if (!$this->is_connected) {
  113. return false;
  114. }
  115. return true;
  116. }
  117. /**
  118. * @see Cache::flush()
  119. */
  120. public function flush()
  121. {
  122. if (!$this->is_connected) {
  123. return false;
  124. }
  125. return $this->memcache->flush();
  126. }
  127. /**
  128. * Store a data in cache
  129. *
  130. * @param string $key
  131. * @param mixed $value
  132. * @param int $ttl
  133. * @return bool
  134. */
  135. public function set($key, $value, $ttl = 0)
  136. {
  137. return $this->_set($key, $value, $ttl);
  138. }
  139. /**
  140. * Retrieve a data from cache
  141. *
  142. * @param string $key
  143. * @return mixed
  144. */
  145. public function get($key)
  146. {
  147. return $this->_get($key);
  148. }
  149. /**
  150. * Check if a data is cached
  151. *
  152. * @param string $key
  153. * @return bool
  154. */
  155. public function exists($key)
  156. {
  157. return $this->_exists($key);
  158. }
  159. /**
  160. * Delete one or several data from cache (* joker can be used, but avoid it !)
  161. * E.g.: delete('*'); delete('my_prefix_*'); delete('my_key_name');
  162. *
  163. * @param string $key
  164. * @return bool
  165. */
  166. public function delete($key)
  167. {
  168. if ($key == '*') {
  169. $this->flush();
  170. } elseif (strpos($key, '*') === false) {
  171. $this->_delete($key);
  172. } else {
  173. // Get keys (this code comes from Doctrine 2 project)
  174. $pattern = str_replace('\\*', '.*', preg_quote($key));
  175. $servers = $this->getMemcachedServers();
  176. if (is_array($servers) && count($servers) > 0 && method_exists('Memcache', 'getStats')) {
  177. $all_slabs = $this->memcache->getStats('slabs');
  178. }
  179. if (isset($all_slabs) && is_array($all_slabs)) {
  180. foreach ($all_slabs as $server => $slabs) {
  181. if (is_array($slabs)) {
  182. foreach (array_keys($slabs) as $i => $slab_id) {
  183. // $slab_id is not an int but a string, using the key instead ?
  184. if (is_int($i)) {
  185. $dump = $this->memcache->getStats('cachedump', (int)$i);
  186. if ($dump) {
  187. foreach ($dump as $entries) {
  188. if ($entries) {
  189. foreach ($entries as $key => $data) {
  190. if (preg_match('#^'.$pattern.'$#', $key)) {
  191. $this->_delete($key);
  192. }
  193. }
  194. }
  195. }
  196. }
  197. }
  198. }
  199. }
  200. }
  201. }
  202. }
  203. return true;
  204. }
  205. /**
  206. * Close connection to memcache server
  207. *
  208. * @return bool
  209. */
  210. protected function close()
  211. {
  212. if (!$this->is_connected) {
  213. return false;
  214. }
  215. return $this->memcache->close();
  216. }
  217. /**
  218. * Add a memcache server
  219. *
  220. * @param string $ip
  221. * @param int $port
  222. * @param int $weight
  223. */
  224. public static function addServer($ip, $port, $weight)
  225. {
  226. return Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'memcached_servers (ip, port, weight) VALUES(\''.pSQL($ip).'\', '.(int)$port.', '.(int)$weight.')', false);
  227. }
  228. /**
  229. * Get list of memcached servers
  230. *
  231. * @return array
  232. */
  233. public static function getMemcachedServers()
  234. {
  235. return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT * FROM '._DB_PREFIX_.'memcached_servers', true, false);
  236. }
  237. /**
  238. * Delete a memcache server
  239. *
  240. * @param int $id_server
  241. */
  242. public static function deleteServer($id_server)
  243. {
  244. return Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'memcached_servers WHERE id_memcached_server='.(int)$id_server);
  245. }
  246. }