]> git.mxchange.org Git - friendica.git/blob - src/Core/Cache/MemcacheCacheDriver.php
Merge pull request #5824 from annando/fix-follow
[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()
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                 return $list;
63         }
64
65         /**
66          * (@inheritdoc)
67          */
68         public function get($key)
69         {
70                 $return = null;
71                 $cachekey = $this->getCacheKey($key);
72
73                 // We fetch with the hostname as key to avoid problems with other applications
74                 $cached = $this->memcache->get($cachekey);
75
76                 // @see http://php.net/manual/en/memcache.get.php#84275
77                 if (is_bool($cached) || is_double($cached) || is_long($cached)) {
78                         return $return;
79                 }
80
81                 $value = @unserialize($cached);
82
83                 // Only return a value if the serialized value is valid.
84                 // We also check if the db entry is a serialized
85                 // boolean 'false' value (which we want to return).
86                 if ($cached === serialize(false) || $value !== false) {
87                         $return = $value;
88                 }
89
90                 return $return;
91         }
92
93         /**
94          * (@inheritdoc)
95          */
96         public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
97         {
98                 $cachekey = $this->getCacheKey($key);
99
100                 // We store with the hostname as key to avoid problems with other applications
101                 if ($ttl > 0) {
102                         return $this->memcache->set(
103                                 $cachekey,
104                                 serialize($value),
105                                 MEMCACHE_COMPRESSED,
106                                 time() + $ttl
107                         );
108                 } else {
109                         return $this->memcache->set(
110                                 $cachekey,
111                                 serialize($value),
112                                 MEMCACHE_COMPRESSED
113                         );
114                 }
115         }
116
117         /**
118          * (@inheritdoc)
119          */
120         public function delete($key)
121         {
122                 $cachekey = $this->getCacheKey($key);
123                 return $this->memcache->delete($cachekey);
124         }
125
126         /**
127          * (@inheritdoc)
128          */
129         public function clear($outdated = true)
130         {
131                 if ($outdated) {
132                         return true;
133                 } else {
134                         return $this->memcache->flush();
135                 }
136         }
137
138         /**
139          * (@inheritdoc)
140          */
141         public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
142         {
143                 $cachekey = $this->getCacheKey($key);
144                 return $this->memcache->add($cachekey, serialize($value), MEMCACHE_COMPRESSED, $ttl);
145         }
146 }