]> git.mxchange.org Git - friendica.git/blob - src/Core/Cache/APCuCache.php
Merge pull request #8129 from nupplaphil/task/cleanup_cache
[friendica.git] / src / Core / Cache / APCuCache.php
1 <?php
2
3 namespace Friendica\Core\Cache;
4
5 use Exception;
6 use Friendica\Core\BaseCache;
7
8 /**
9  * APCu Cache.
10  *
11  * @author Philipp Holzer <admin@philipp.info>
12  */
13 class APCuCache extends BaseCache implements IMemoryCache
14 {
15         use TraitCompareSet;
16         use TraitCompareDelete;
17
18         /**
19          * @throws Exception
20          */
21         public function __construct(string $hostname)
22         {
23                 if (!self::isAvailable()) {
24                         throw new Exception('APCu is not available.');
25                 }
26
27                 parent::__construct($hostname);
28         }
29
30         /**
31          * (@inheritdoc)
32          */
33         public function getAllKeys($prefix = null)
34         {
35                 $ns = $this->getCacheKey($prefix);
36                 $ns = preg_quote($ns, '/');
37
38                 if (class_exists('\APCIterator')) {
39                         $iterator = new \APCIterator('user', '/^' . $ns. '/', APC_ITER_KEY);
40                 } else {
41                         $iterator = new \APCUIterator('/^' . $ns . '/', APC_ITER_KEY);
42                 }
43
44                 $keys = [];
45                 foreach ($iterator as $item) {
46                         array_push($keys, $item['key']);
47                 }
48
49                 return $this->getOriginalKeys($keys);
50         }
51
52         /**
53          * (@inheritdoc)
54          */
55         public function get($key)
56         {
57                 $return = null;
58                 $cachekey = $this->getCacheKey($key);
59
60                 $cached = apcu_fetch($cachekey, $success);
61                 if (!$success) {
62                         return null;
63                 }
64
65                 $value = unserialize($cached);
66
67                 // Only return a value if the serialized value is valid.
68                 // We also check if the db entry is a serialized
69                 // boolean 'false' value (which we want to return).
70                 if ($cached === serialize(false) || $value !== false) {
71                         $return = $value;
72                 }
73
74                 return $return;
75         }
76
77         /**
78          * (@inheritdoc)
79          */
80         public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
81         {
82                 $cachekey = $this->getCacheKey($key);
83
84                 $cached = serialize($value);
85
86                 if ($ttl > 0) {
87                         return apcu_store(
88                                 $cachekey,
89                                 $cached,
90                                 $ttl
91                         );
92                 } else {
93                         return apcu_store(
94                                 $cachekey,
95                                 $cached
96                         );
97                 }
98         }
99
100         /**
101          * (@inheritdoc)
102          */
103         public function delete($key)
104         {
105                 $cachekey = $this->getCacheKey($key);
106                 return apcu_delete($cachekey);
107         }
108
109         /**
110          * (@inheritdoc)
111          */
112         public function clear($outdated = true)
113         {
114                 if ($outdated) {
115                         return true;
116                 } else {
117                         $prefix = $this->getPrefix();
118                         $prefix = preg_quote($prefix, '/');
119
120                         if (class_exists('\APCIterator')) {
121                                 $iterator = new \APCIterator('user', '/^' . $prefix . '/', APC_ITER_KEY);
122                         } else {
123                                 $iterator = new \APCUIterator('/^' . $prefix . '/', APC_ITER_KEY);
124                         }
125
126                         return apcu_delete($iterator);
127                 }
128         }
129
130         /**
131          * (@inheritdoc)
132          */
133         public function add($key, $value, $ttl = Duration::FIVE_MINUTES)
134         {
135                 $cachekey = $this->getCacheKey($key);
136                 $cached = serialize($value);
137
138                 return apcu_add($cachekey, $cached);
139         }
140
141         public static function isAvailable()
142         {
143                 if (!extension_loaded('apcu')) {
144                         return false;
145                 } elseif (!ini_get('apc.enabled') && !ini_get('apc.enable_cli')) {
146                         return false;
147                 } elseif (
148                         version_compare(phpversion('apc') ?: '0.0.0', '4.0.6') === -1 &&
149                         version_compare(phpversion('apcu') ?: '0.0.0', '5.1.0') === -1
150                 ) {
151                         return false;
152                 }
153
154                 return true;
155         }
156
157         /**
158          * {@inheritDoc}
159          */
160         public function getName()
161         {
162                 return Type::APCU;
163         }
164 }