Completed
Pull Request — master (#2)
by William Johnson S.
02:22
created

MemCached::namespacedKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
namespace Ezcache\Cache;
4
5
/**
6
 * @codeCoverageIgnore
7
 * @author: William Johnson dos Santos Okano <[email protected]>
8
 */
9
class MemCached implements CacheInterface
10
{
11
    /** @var string */
12
    private $namespace;
13
14
    /** @var int */
15
    private $ttl;
16
17
    /** @var \Memcached */
18
    private $memcachedInstance;
19
20
    /**
21
     * MemCached constructor.
22
     *
23
     * @param \Memcached $memcached the memcached instance
24
     * @param int        $ttl       the cache lifetime in seconds (0 = Forever)
25
     * @param string     $namespace the cache namespace
26
     */
27
    public function __construct(\Memcached $memcached, $ttl = 0, string $namespace = null)
28
    {
29
        $this->ttl = $ttl;
30
        $this->memcachedInstance = $memcached;
31
        if ($namespace !== null) {
32
            $this->setNamespace($namespace);
33
        }
34
    }
35
36
    /**
37
     * Set the cache namespace
38
     *
39
     * @param string $namespace the cache namespace
40
     *
41
     * @return bool true on success or false on failure
42
     */
43
    public function setNamespace(string $namespace) : bool
44
    {
45
        $this->namespace = $namespace;
46
        return true;
47
    }
48
49
    /**
50
     * Set a value to a key on cache.
51
     *
52
     * Set a value to a key on cache.
53
     *
54
     * @param string   $key   the key to be set.
55
     * @param mixed    $value the correspondent value of that cache key.
56
     * @param int|null $ttl   the cache life time in seconds (If no value passed will use the default value).
57
     *
58
     * @return bool true on success or false on failure.
59
     */
60
    public function set(string $key, $value, int $ttl = null) : bool
61
    {
62
        $ttl = $ttl ?? $this->ttl;
63
        $key = $this->namespacedKey($key);
64
        return $this->memcachedInstance->set($key, $value, $ttl);
65
    }
66
67
    /**
68
     * Return the valid cache value stored with the given key.
69
     *
70
     * @param string $key the cache key to be found.
71
     *
72
     * @return mixed the data found.
73
     */
74
    public function get(string $key)
75
    {
76
        $key = $this->namespacedKey($key);
77
        $value = $this->memcachedInstance->get($key);
78
        if ($this->exists($key)) {
79
            return $value;
80
        }
81
        return null;
82
    }
83
84
    /**
85
     * Delete cache especified by key.
86
     *
87
     * @param string $key the cache key to be deleted.
88
     *
89
     * @return bool true on success or false on failure.
90
     */
91
    public function delete(string $key) : bool
92
    {
93
        $key = $this->namespacedKey($key);
94
        return $this->memcachedInstance->delete($key);
95
    }
96
97
    /**
98
     * Check if given key exists and is valid on cache.
99
     *
100
     * @param string $key     the cache key to be verified.
101
     * @param bool   $isValid if set to true the function will verify if it is valid (not expired).
102
     *
103
     * @return bool true if exists false otherwise.
104
     */
105
    public function exists(string $key, bool $isValid = false) : bool
106
    {
107
        $this->memcachedInstance->get($key);
108
        return $this->memcachedInstance->getResultCode() !== \Memcached::RES_NOTFOUND;
109
    }
110
111
    /**
112
     * Renew the cache expiration time.
113
     *
114
     * @param string   $key the cache key to be renewed.
115
     * @param int|null $ttl extra time to live in seconds.
116
     *
117
     * @return bool true on success or false on failure.
118
     */
119
    public function renew(string $key, int $ttl) : bool
120
    {
121
        $key = $this->namespacedKey($key);
122
        $ttl = $ttl ?? $this->ttl;
123
        if ($this->exists($key)) {
124
            return $this->memcachedInstance->touch($key, $ttl);
125
        }
126
        return false;
127
    }
128
129
    /**
130
     * Clear all cache records.If namespace set, just clear those that starts with the namespace
131
     *
132
     * @param string|null $namespace the cache namespace.
133
     *
134
     * @return bool true on success or false on failure.
135
     */
136
    public function clear(string $namespace = null) : bool
137
    {
138
        $namespace = $namespace ?? $this->namespace;
139
        if ($namespace === null) {
140
            return $this->memcachedInstance->flush();
141
        }
142
143
        // Find all keys, iterate and them delete the only ones that starts with the namespace
144
        $cacheKeys = $this->memcachedInstance->getAllKeys();
145
        $filteredCacheKeys = array_filter($cacheKeys, function ($key) use ($namespace) {
146
            return strpos($key, $namespace) === 0;
147
        });
148
149
        array_walk($filteredCacheKeys, array($this, 'delete'));
150
151
        return true;
152
    }
153
154
    /**
155
     * Return the key with the namespace. Since Memcached doesn't support namespaces
156
     * the method just simulate it by pre-pending some fixed string to the key
157
     *
158
     * @param string $key the key to prepend the namespace, if necessary
159
     *
160
     * @return string the "namespaced" key
161
     */
162
    private function namespacedKey(string $key) : string {
163
        if ($this->namespace !== null) {
164
            return $this->namespace . $key;
165
        }
166
        return $key;
167
    }
168
}
169