Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Libmemcached.php
Go to the documentation of this file.
1 <?php
27 #require_once 'Zend/Cache/Backend/ExtendedInterface.php';
28 
32 #require_once 'Zend/Cache/Backend.php';
33 
34 
42 {
46  const DEFAULT_HOST = '127.0.0.1';
47  const DEFAULT_PORT = 11211;
48  const DEFAULT_WEIGHT = 1;
49 
53  const TAGS_UNSUPPORTED_BY_CLEAN_OF_LIBMEMCACHED_BACKEND = 'Zend_Cache_Backend_Libmemcached::clean() : tags are unsupported by the Libmemcached backend';
54  const TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND = 'Zend_Cache_Backend_Libmemcached::save() : tags are unsupported by the Libmemcached backend';
55 
74  protected $_options = array(
75  'servers' => array(array(
76  'host' => self::DEFAULT_HOST,
77  'port' => self::DEFAULT_PORT,
78  'weight' => self::DEFAULT_WEIGHT,
79  )),
80  'client' => array()
81  );
82 
88  protected $_memcache = null;
89 
97  public function __construct(array $options = array())
98  {
99  if (!extension_loaded('memcached')) {
100  Zend_Cache::throwException('The memcached extension must be loaded for using this backend !');
101  }
102 
103  // override default client options
104  $this->_options['client'] = array(
105  Memcached::OPT_DISTRIBUTION => Memcached::DISTRIBUTION_CONSISTENT,
106  Memcached::OPT_HASH => Memcached::HASH_MD5,
107  Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
108  );
109 
110  parent::__construct($options);
111 
112  if (isset($this->_options['servers'])) {
113  $value = $this->_options['servers'];
114  if (isset($value['host'])) {
115  // in this case, $value seems to be a simple associative array (one server only)
116  $value = array(0 => $value); // let's transform it into a classical array of associative arrays
117  }
118  $this->setOption('servers', $value);
119  }
120  $this->_memcache = new Memcached;
121 
122  // setup memcached client options
123  foreach ($this->_options['client'] as $name => $value) {
124  $optId = null;
125  if (is_int($name)) {
126  $optId = $name;
127  } else {
128  $optConst = 'Memcached::OPT_' . strtoupper($name);
129  if (defined($optConst)) {
130  $optId = constant($optConst);
131  } else {
132  $this->_log("Unknown memcached client option '{$name}' ({$optConst})");
133  }
134  }
135  if (null !== $optId) {
136  if (!$this->_memcache->setOption($optId, $value)) {
137  $this->_log("Setting memcached client option '{$optId}' failed");
138  }
139  }
140  }
141 
142  // setup memcached servers
143  $servers = array();
144  foreach ($this->_options['servers'] as $server) {
145  if (!array_key_exists('port', $server)) {
146  $server['port'] = self::DEFAULT_PORT;
147  }
148  if (!array_key_exists('weight', $server)) {
149  $server['weight'] = self::DEFAULT_WEIGHT;
150  }
151 
152  $servers[] = array($server['host'], $server['port'], $server['weight']);
153  }
154  $this->_memcache->addServers($servers);
155  }
156 
164  public function load($id, $doNotTestCacheValidity = false)
165  {
166  $tmp = $this->_memcache->get($id);
167  if (isset($tmp[0])) {
168  return $tmp[0];
169  }
170  return false;
171  }
172 
179  public function test($id)
180  {
181  $tmp = $this->_memcache->get($id);
182  if (isset($tmp[0], $tmp[1])) {
183  return (int)$tmp[1];
184  }
185  return false;
186  }
187 
200  public function save($data, $id, $tags = array(), $specificLifetime = false)
201  {
202  $lifetime = $this->getLifetime($specificLifetime);
203 
204  // ZF-8856: using set because add needs a second request if item already exists
205  $result = @$this->_memcache->set($id, array($data, time(), $lifetime), $lifetime);
206  if ($result === false) {
207  $rsCode = $this->_memcache->getResultCode();
208  $rsMsg = $this->_memcache->getResultMessage();
209  $this->_log("Memcached::set() failed: [{$rsCode}] {$rsMsg}");
210  }
211 
212  if (count($tags) > 0) {
213  $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND);
214  }
215 
216  return $result;
217  }
218 
225  public function remove($id)
226  {
227  return $this->_memcache->delete($id);
228  }
229 
245  public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array())
246  {
247  switch ($mode) {
249  return $this->_memcache->flush();
250  break;
252  $this->_log("Zend_Cache_Backend_Libmemcached::clean() : CLEANING_MODE_OLD is unsupported by the Libmemcached backend");
253  break;
257  $this->_log(self::TAGS_UNSUPPORTED_BY_CLEAN_OF_LIBMEMCACHED_BACKEND);
258  break;
259  default:
260  Zend_Cache::throwException('Invalid mode for clean() method');
261  break;
262  }
263  }
264 
271  {
272  return false;
273  }
274 
282  public function setDirectives($directives)
283  {
284  parent::setDirectives($directives);
285  $lifetime = $this->getLifetime(false);
286  if ($lifetime > 2592000) {
287  // #ZF-3490 : For the memcached backend, there is a lifetime limit of 30 days (2592000 seconds)
288  $this->_log('memcached backend has a limit of 30 days (2592000 seconds) for the lifetime');
289  }
290  if ($lifetime === null) {
291  // #ZF-4614 : we tranform null to zero to get the maximal lifetime
292  parent::setDirectives(array('lifetime' => 0));
293  }
294  }
295 
301  public function getIds()
302  {
303  $this->_log("Zend_Cache_Backend_Libmemcached::save() : getting the list of cache ids is unsupported by the Libmemcached backend");
304  return array();
305  }
306 
312  public function getTags()
313  {
314  $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND);
315  return array();
316  }
317 
326  public function getIdsMatchingTags($tags = array())
327  {
328  $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND);
329  return array();
330  }
331 
340  public function getIdsNotMatchingTags($tags = array())
341  {
342  $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND);
343  return array();
344  }
345 
354  public function getIdsMatchingAnyTags($tags = array())
355  {
356  $this->_log(self::TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND);
357  return array();
358  }
359 
366  public function getFillingPercentage()
367  {
368  $mems = $this->_memcache->getStats();
369  if ($mems === false) {
370  return 0;
371  }
372 
373  $memSize = null;
374  $memUsed = null;
375  foreach ($mems as $key => $mem) {
376  if ($mem === false) {
377  $this->_log('can\'t get stat from ' . $key);
378  continue;
379  }
380 
381  $eachSize = $mem['limit_maxbytes'];
382  $eachUsed = $mem['bytes'];
383  if ($eachUsed > $eachSize) {
384  $eachUsed = $eachSize;
385  }
386 
387  $memSize += $eachSize;
388  $memUsed += $eachUsed;
389  }
390 
391  if ($memSize === null || $memUsed === null) {
392  Zend_Cache::throwException('Can\'t get filling percentage');
393  }
394 
395  return ((int) (100. * ($memUsed / $memSize)));
396  }
397 
409  public function getMetadatas($id)
410  {
411  $tmp = $this->_memcache->get($id);
412  if (isset($tmp[0], $tmp[1], $tmp[2])) {
413  $data = $tmp[0];
414  $mtime = $tmp[1];
415  $lifetime = $tmp[2];
416  return array(
417  'expire' => $mtime + $lifetime,
418  'tags' => array(),
419  'mtime' => $mtime
420  );
421  }
422 
423  return false;
424  }
425 
433  public function touch($id, $extraLifetime)
434  {
435  $tmp = $this->_memcache->get($id);
436  if (isset($tmp[0], $tmp[1], $tmp[2])) {
437  $data = $tmp[0];
438  $mtime = $tmp[1];
439  $lifetime = $tmp[2];
440  $newLifetime = $lifetime - (time() - $mtime) + $extraLifetime;
441  if ($newLifetime <=0) {
442  return false;
443  }
444  // #ZF-5702 : we try replace() first becase set() seems to be slower
445  if (!($result = $this->_memcache->replace($id, array($data, time(), $newLifetime), $newLifetime))) {
446  $result = $this->_memcache->set($id, array($data, time(), $newLifetime), $newLifetime);
447  if ($result === false) {
448  $rsCode = $this->_memcache->getResultCode();
449  $rsMsg = $this->_memcache->getResultMessage();
450  $this->_log("Memcached::set() failed: [{$rsCode}] {$rsMsg}");
451  }
452  }
453  return $result;
454  }
455  return false;
456  }
457 
472  public function getCapabilities()
473  {
474  return array(
475  'automatic_cleaning' => false,
476  'tags' => false,
477  'expired_read' => false,
478  'priority' => false,
479  'infinite_lifetime' => false,
480  'get_list' => false
481  );
482  }
483 
484 }
touch($id, $extraLifetime)
$id
Definition: fieldset.phtml:14
const CLEANING_MODE_OLD
Definition: Cache.php:73
_log($message, $priority=4)
Definition: Backend.php:273
setOption($name, $value)
Definition: Backend.php:101
$value
Definition: gender.phtml:16
const CLEANING_MODE_NOT_MATCHING_TAG
Definition: Cache.php:75
if($exist=($block->getProductCollection() && $block->getProductCollection() ->getSize())) $mode
Definition: grid.phtml:15
const CLEANING_MODE_ALL
Definition: Cache.php:72
static throwException($msg, Exception $e=null)
Definition: Cache.php:205
save($data, $id, $tags=array(), $specificLifetime=false)
clean($mode=Zend_Cache::CLEANING_MODE_ALL, $tags=array())
const CLEANING_MODE_MATCHING_ANY_TAG
Definition: Cache.php:76
load($id, $doNotTestCacheValidity=false)
const CLEANING_MODE_MATCHING_TAG
Definition: Cache.php:74
getLifetime($specificLifetime)
Definition: Backend.php:143
const TAGS_UNSUPPORTED_BY_CLEAN_OF_LIBMEMCACHED_BACKEND
const TAGS_UNSUPPORTED_BY_SAVE_OF_LIBMEMCACHED_BACKEND
__construct(array $options=array())
if(!isset($_GET['name'])) $name
Definition: log.php:14