Memcached.php (2821B)
1 <?php 2 3 namespace Finwo\Cache; 4 5 /** 6 * Implements memcached 7 * Handles refreshing in a server-friendly way 8 */ 9 class Memcached extends Cache 10 { 11 /** 12 * @var \Memcached 13 */ 14 protected $memcached; 15 16 /** 17 * @var string 18 */ 19 protected $server = '127.0.0.1'; 20 21 /** 22 * @var int 23 */ 24 protected $port = 11211; 25 26 /** 27 * @return \Memcached 28 */ 29 protected function getMemcached() 30 { 31 if (null === $this->memcached) { 32 $this->memcached = new \Memcached(); 33 $this->memcached->addServer($this->server, $this->port); 34 } 35 36 return $this->memcached; 37 } 38 39 public function __construct($options = array()) 40 { 41 // Override default options 42 foreach($options as $key => $value) { 43 if (isset($this->{$key})) { 44 $this->{$key} = $value; 45 } 46 } 47 } 48 49 /** 50 * {@inheritdoc} 51 */ 52 public function fetch($key = '', $ttl = 30) 53 { 54 // Generate seperate keys for fetching 55 $key_lock = \md5(\sprintf("%s_lock", $key)); 56 $key_data = \md5(\sprintf("%s_data", $key)); 57 $key_ttl = \md5(\sprintf("%s_ttl", $key)); 58 59 // Fetch memcached object 60 $memcached = $this->getMemcached(); 61 62 // Fetch data 63 $data_data = $memcached->get($key_data); 64 65 // Return data if the current TTL is still valid 66 if ($memcached->get($key_ttl)) { 67 return $data_data; 68 } 69 70 // Return data if we're already "refreshing" 71 if ($memcached->get($key_lock)) { 72 return $data_data; 73 } 74 75 // Mark we're refreshing for ttl/10 76 // Also give it 2 seconds, because some operations take time 77 $memcached->add($key_lock, 'Hello World', max(2,$ttl/10)); 78 79 // And return that we don't have recent data 80 return false; 81 } 82 83 /** 84 * {@inheritdoc} 85 */ 86 public function store($key = '', $value, $ttl = 30) 87 { 88 // Generate seperate keys for storing 89 $key_data = \md5(\sprintf("%s_data", $key)); 90 $key_ttl = \md5(\sprintf("%s_ttl", $key)); 91 92 // Pre-generate time 93 $time_data = \max(3600, $ttl*10); 94 if ($ttl === 0) { 95 $time_data = 0; 96 } 97 98 // Fetch memcached object 99 $memcached = $this->getMemcached(); 100 101 // Store data 102 if($memcached->get($key_data)) { 103 $memcached->replace($key_data, $value, $time_data); 104 } else { 105 $memcached->add($key_data, $value, $time_data); 106 } 107 108 // Store TTL 109 $memcached->add($key_ttl, 'Hello World', $ttl); 110 111 // Return ourselves 112 return $this; 113 } 114 115 /** 116 * (@inheritdoc} 117 */ 118 public function supported() 119 { 120 return class_exists('Memcached'); 121 } 122 }