8b752fb3a8b8cb585566feec1913c3449f780914
[friendica.git/.git] / src / Core / Cache / MemcachedCacheDriver.php
1 <?php
2
3 namespace Friendica\Core\Cache;
4
5 use Friendica\Core\Cache;
6
7 use Exception;
8 use Memcached;
9
10 /**
11  * Memcached Cache Driver
12  *
13  * @author Hypolite Petovan <mrpetovan@gmail.com>
14  */
15 class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDriver
16 {
17         use TraitCompareSet;
18         use TraitCompareDelete;
19
20         /**
21          * @var \Memcached
22          */
23         private $memcached;
24
25         /**
26          * Due to limitations of the INI format, the expected configuration for Memcached servers is the following:
27          * array {
28          *   0 => "hostname, port(, weight)",
29          *   1 => ...
30          * }
31          *
32          * @param array $memcached_hosts
33          * @throws \Exception
34          */
35         public function __construct(array $memcached_hosts)
36         {
37                 if (!class_exists('Memcached', false)) {
38                         throw new Exception('Memcached class isn\'t available');
39                 }
40
41                 $this->memcached = new Memcached();
42
43                 array_walk($memcached_hosts, function (&$value) {
44                         $value = array_map('trim', explode(',', $value));
45                 });
46
47                 $this->memcached->addServers($memcached_hosts);
48
49                 if (count($this->memcached->getServerList()) == 0) {
50                         throw new Exception('Expected Memcached servers aren\'t available, config:' . var_export($memcached_hosts, true));
51                 }
52         }
53
54         public function get($key)
55         {
56                 $return = null;
57                 $cachekey = $this->getCacheKey($key);
58
59                 // We fetch with the hostname as key to avoid problems with other applications
60                 $value = $this->memcached->get($cachekey);
61
62                 if ($this->memcached->getResultCode() === Memcached::RES_SUCCESS) {
63                         $return = $value;
64                 }
65
66                 return $return;
67         }
68
69         public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
70         {
71                 $cachekey = $this->getCacheKey($key);
72
73                 // We store with the hostname as key to avoid problems with other applications
74                 if ($ttl > 0) {
75                         return $this->memcached->set(
76                                 $cachekey,
77                                 $value,
78                                 $ttl
79                         );
80                 } else {
81                         return $this->memcached->set(
82                                 $cachekey,
83                                 $value
84                         );
85                 }
86
87         }
88
89         public function delete($key)
90         {
91                 $cachekey = $this->getCacheKey($key);
92                 return $this->memcached->delete($cachekey);
93         }
94
95         public function clear($outdated = true)
96         {
97                 if ($outdated) {
98                         return true;
99                 } else {
100                         return $this->memcached->flush();
101                 }
102         }
103
104         /**
105          * @brief Sets a value if it's not already stored
106          *
107          * @param string $key      The cache key
108          * @param mixed  $value    The old value we know from the cache
109          * @param int    $ttl      The cache lifespan, must be one of the Cache constants
110          * @return bool
111          */
112         public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
113         {
114                 $cachekey = $this->getCacheKey($key);
115                 return $this->memcached->add($cachekey, $value, $ttl);
116         }
117 }