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