]> git.mxchange.org Git - friendica.git/blob - src/Core/Cache/MemcacheCacheDriver.php
f31e21d14e1a9a239f8aabb30a38ee2cb0d042de
[friendica.git] / src / Core / Cache / MemcacheCacheDriver.php
1 <?php
2
3 namespace Friendica\Core\Cache;
4
5 use Friendica\Core\Cache;
6
7 use Exception;
8 use Memcache;
9
10 /**
11  * Memcache Cache Driver
12  *
13  * @author Hypolite Petovan <hypolite@mrpetovan.com>
14  */
15 class MemcacheCacheDriver extends AbstractCacheDriver implements IMemoryCacheDriver
16 {
17         use TraitCompareSet;
18         use TraitCompareDelete;
19
20         /**
21          * @var Memcache
22          */
23         private $memcache;
24
25         /**
26          * @param string $memcache_host
27          * @param int    $memcache_port
28          * @throws Exception
29          */
30         public function __construct($memcache_host, $memcache_port)
31         {
32                 if (!class_exists('Memcache', false)) {
33                         throw new Exception('Memcache class isn\'t available');
34                 }
35
36                 $this->memcache = new Memcache();
37
38                 if (!$this->memcache->connect($memcache_host, $memcache_port)) {
39                         throw new Exception('Expected Memcache server at ' . $memcache_host . ':' . $memcache_port . ' isn\'t available');
40                 }
41         }
42
43         /**
44          * (@inheritdoc)
45          */
46         public function getAllKeys($prefix = null)
47         {
48                 $list = [];
49                 $allSlabs = $this->memcache->getExtendedStats('slabs');
50                 foreach ($allSlabs as $slabs) {
51                         foreach (array_keys($slabs) as $slabId) {
52                                 $cachedump = $this->memcache->getExtendedStats('cachedump', (int)$slabId);
53                                 foreach ($cachedump as $keys => $arrVal) {
54                                         if (!is_array($arrVal)) {
55                                                 continue;
56                                         }
57                                         $list = array_merge($list, array_keys($arrVal));
58                                 }
59                         }
60                 }
61
62                 $list = $this->getOriginalKeys($list);
63
64                 return $this->filterPrefix($list, $prefix);
65         }
66
67         /**
68          * (@inheritdoc)
69          */
70         public function get($key)
71         {
72                 $return = null;
73                 $cachekey = $this->getCacheKey($key);
74
75                 // We fetch with the hostname as key to avoid problems with other applications
76                 $cached = $this->memcache->get($cachekey);
77
78                 // @see http://php.net/manual/en/memcache.get.php#84275
79                 if (is_bool($cached) || is_double($cached) || is_long($cached)) {
80                         return $return;
81                 }
82
83                 $value = @unserialize($cached);
84
85                 // Only return a value if the serialized value is valid.
86                 // We also check if the db entry is a serialized
87                 // boolean 'false' value (which we want to return).
88                 if ($cached === serialize(false) || $value !== false) {
89                         $return = $value;
90                 }
91
92                 return $return;
93         }
94
95         /**
96          * (@inheritdoc)
97          */
98         public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
99         {
100                 $cachekey = $this->getCacheKey($key);
101
102                 // We store with the hostname as key to avoid problems with other applications
103                 if ($ttl > 0) {
104                         return $this->memcache->set(
105                                 $cachekey,
106                                 serialize($value),
107                                 MEMCACHE_COMPRESSED,
108                                 time() + $ttl
109                         );
110                 } else {
111                         return $this->memcache->set(
112                                 $cachekey,
113                                 serialize($value),
114                                 MEMCACHE_COMPRESSED
115                         );
116                 }
117         }
118
119         /**
120          * (@inheritdoc)
121          */
122         public function delete($key)
123         {
124                 $cachekey = $this->getCacheKey($key);
125                 return $this->memcache->delete($cachekey);
126         }
127
128         /**
129          * (@inheritdoc)
130          */
131         public function clear($outdated = true)
132         {
133                 if ($outdated) {
134                         return true;
135                 } else {
136                         return $this->memcache->flush();
137                 }
138         }
139
140         /**
141          * (@inheritdoc)
142          */
143         public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
144         {
145                 $cachekey = $this->getCacheKey($key);
146                 return $this->memcache->add($cachekey, serialize($value), MEMCACHE_COMPRESSED, $ttl);
147         }
148 }