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