InMemoryCache::set()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SubjectivePHP\Psr\SimpleCache;
4
5
use ArrayObject;
6
use DateInterval;
7
use DateTime;
8
use Psr\SimpleCache\CacheInterface;
9
10
/**
11
 * A PSR-16 implementation which stores data in an array.
12
 */
13
final class InMemoryCache implements CacheInterface
14
{
15
    use KeyValidatorTrait;
16
    use TTLValidatorTrait;
17
18
    /**
19
     * @var ArrayObject
20
     */
21
    private $cache;
22
23
    /**
24
     * Construct a new instance of InMemoryCache.
25
     *
26
     * @param ArrayObject $cache Initial cache container.
27
     */
28
    public function __construct(ArrayObject $cache = null)
29
    {
30
        $this->cache = $cache ?? new ArrayObject();
31
    }
32
33
    /**
34
     * Fetches a value from the cache.
35
     *
36
     * @param string $key     The unique key of this item in the cache.
37
     * @param mixed  $default Default value to return if the key does not exist.
38
     *
39
     * @return mixed The value of the item from the cache, or $default in case of cache miss.
40
     *
41
     * @throws InvalidArgumentException Thrown if the $key string is not a legal value.
42
     */
43
    public function get($key, $default = null)//@codingStandardsIgnoreLine Interface does not define type-hints or return
44
    {
45
        $this->validateKey($key);
46
        $cache = $this->cache[$key] ?? null;
47
        if ($cache === null) {
48
            return $default;
49
        }
50
51
        if ($cache['expires'] >= time()) {
52
            return $cache['data'];
53
        }
54
55
        unset($this->cache[$key]);
56
        return $default;
57
    }
58
59
    /**
60
     * Obtains multiple cache items by their unique keys.
61
     *
62
     * @param iterable $keys    A list of keys that can obtained in a single operation.
63
     * @param mixed    $default Default value to return for keys that do not exist.
64
     *
65
     * @return array List of key => value pairs. Cache keys that do not exist or are stale will have $default as value.
66
     *
67
     * @throws InvalidArgumentException Thrown if the $key string is not a legal value.
68
     */
69
    public function getMultiple($keys, $default = null)//@codingStandardsIgnoreLine Interface does not define type-hints or return
70
    {
71
        $result = [];
72
        foreach ($keys as $key) {
73
            $result[$key] = $this->get($key, $default);
74
        }
75
76
        return $result;
77
    }
78
79
    /**
80
     * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
81
     *
82
     * @param string                    $key   The key of the item to store.
83
     * @param mixed                     $value The value of the item to store, must be serializable.
84
     * @param null|integer|DateInterval $ttl   Optional. The TTL value of this item. If no value is sent and
85
     *                                         the driver supports TTL then the library may set a default value
86
     *                                         for it or let the driver take care of that.
87
     *
88
     * @return boolean True on success and false on failure.
89
     *
90
     * @throws InvalidArgumentException Thrown if the $key string is not a legal value.
91
     */
92
    public function set($key, $value, $ttl = null)//@codingStandardsIgnoreLine Interface does not define type-hints or return
93
    {
94
        $this->validateKey($key);
95
        $this->validateTTL($ttl);
96
        $this->cache[$key] = ['data' => $value, 'expires' => $this->getExpiration($ttl)];
97
        return true;
98
    }
99
100
    /**
101
     * Persists a set of key => value pairs in the cache, with an optional TTL.
102
     *
103
     * @param iterable                  $values A list of key => value pairs for a multiple-set operation.
104
     * @param null|integer|DateInterval $ttl    Optional. The TTL value of this item. If no value is sent and
105
     *                                          the driver supports TTL then the library may set a default value
106
     *                                          for it or let the driver take care of that.
107
     *
108
     * @return boolean True on success and false on failure.
109
     *
110
     * @throws InvalidArgumentException Thrown if $values is neither an array nor a Traversable,
111
     *                                  or if any of the $values are not a legal value.
112
     */
113
    public function setMultiple($values, $ttl = null)//@codingStandardsIgnoreLine Interface does not define type-hints or return
114
    {
115
        $keys = array_keys($values);
0 ignored issues
show
Bug introduced by
$values of type iterable is incompatible with the type array expected by parameter $array of array_keys(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

115
        $keys = array_keys(/** @scrutinizer ignore-type */ $values);
Loading history...
116
        $this->validateKeys($keys);
117
        $this->getExpiration($ttl);
118
119
        foreach ($values as $key => $value) {
120
            $this->set($key, $value, $ttl);
121
        }
122
123
        return true;
124
    }
125
126
    /**
127
     * Delete an item from the cache by its unique key.
128
     *
129
     * @param string $key The unique cache key of the item to delete.
130
     *
131
     * @return boolean True if the item was successfully removed. False if there was an error.
132
     *
133
     * @throws InvalidArgumentException Thrown if the $key string is not a legal value.
134
     */
135
    public function delete($key)//@codingStandardsIgnoreLine Interface does not define type-hints or return
136
    {
137
        $this->validateKey($key);
138
        unset($this->cache[$key]);
139
        return true;
140
    }
141
142
    /**
143
     * Deletes multiple cache items in a single operation.
144
     *
145
     * @param iterable $keys A list of string-based keys to be deleted.
146
     *
147
     * @return boolean True if the items were successfully removed. False if there was an error.
148
     *
149
     * @throws InvalidArgumentException Thrown if $keys is neither an array nor a Traversable,
150
     *                                  or if any of the $keys are not a legal value.
151
     */
152
    public function deleteMultiple($keys)//@codingStandardsIgnoreLine Interface does not define type-hints
153
    {
154
        $this->validateKeys($keys);
0 ignored issues
show
Bug introduced by
$keys of type iterable is incompatible with the type array expected by parameter $keys of SubjectivePHP\Psr\Simple...ryCache::validateKeys(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

154
        $this->validateKeys(/** @scrutinizer ignore-type */ $keys);
Loading history...
155
        foreach ($keys as $key) {
156
            unset($this->cache[$key]);
157
        }
158
159
        return true;
160
    }
161
162
    /**
163
     * Wipes clean the entire cache's keys.
164
     *
165
     * @return boolean True on success and false on failure.
166
     */
167
    public function clear()//@codingStandardsIgnoreLine Interface does not define type-hints or return
168
    {
169
        $this->cache->exchangeArray([]);
170
        return true;
171
    }
172
173
    /**
174
     * Determines whether an item is present in the cache.
175
     *
176
     * NOTE: It is recommended that has() is only to be used for cache warming type purposes
177
     * and not to be used within your live applications operations for get/set, as this method
178
     * is subject to a race condition where your has() will return true and immediately after,
179
     * another script can remove it making the state of your app out of date.
180
     *
181
     * @param string $key The cache item key.
182
     *
183
     * @return boolean
184
     *
185
     * @throws InvalidArgumentException Thrown if the $key string is not a legal value.
186
     */
187
    public function has($key) //@codingStandardsIgnoreLine  Interface does not define type-hints
188
    {
189
        $this->validateKey($key);
190
        return $this->get($key, false) !== false;
191
    }
192
193
    /**
194
     * Converts the given time to live value to a DataTime instance;
195
     *
196
     * @param mixed $ttl The time-to-live value to validate.
197
     *
198
     * @return integer
199
     */
200
    private function getExpiration($ttl) : int
201
    {
202
        if ($ttl === null) {
203
            return PHP_INT_MAX;
204
        }
205
206
        if (is_int($ttl)) {
207
            return time() + $ttl;
208
        }
209
210
        return (new DateTime())->add($ttl)->getTimestamp();
211
    }
212
}
213