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