Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.56% covered (success)
97.56%
40 / 41
91.67% covered (success)
91.67%
11 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
Memcached
97.56% covered (success)
97.56%
40 / 41
91.67% covered (success)
91.67%
11 / 12
19
0.00% covered (danger)
0.00%
0 / 1
 __construct
87.50% covered (success)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
3.02
 memcached
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addServer
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addServers
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getVersion
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getItemTtl
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 saveItem
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getItem
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 hasItem
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 deleteItem
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 clear
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 destroy
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Cache\Adapter;
15
16/**
17 * Memcached cache adapter class
18 *
19 * @category   Pop
20 * @package    Pop\Cache
21 * @author     Nick Sagona, III <dev@nolainteractive.com>
22 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
23 * @license    http://www.popphp.org/license     New BSD License
24 * @version    4.0.0
25 */
26class Memcached extends AbstractAdapter
27{
28
29    /**
30     * Memcached object
31     * @var ?\Memcached
32     */
33    protected ?\Memcached $memcached = null;
34
35    /**
36     * Memcached version
37     * @var ?string
38     */
39    protected ?string $version = null;
40
41    /**
42     * Constructor
43     *
44     * Instantiate the memcached cache object
45     *
46     * @param  int    $ttl
47     * @param  string $host
48     * @param  int    $port
49     * @param  int    $weight
50     * @throws Exception
51     */
52    public function __construct(int $ttl = 0, string $host = 'localhost', int $port = 11211, int $weight = 1)
53    {
54        parent::__construct($ttl);
55        if (!class_exists('Memcached', false)) {
56            throw new Exception('Error: Memcached is not available.');
57        }
58
59        $this->memcached = new \Memcached();
60        $this->addServer($host, $port, $weight);
61
62        $version = $this->memcached->getVersion();
63        if (isset($version[$host . ':' . $port])) {
64            $this->version = $version[$host . ':' . $port];
65        }
66    }
67
68    /**
69     * Get the memcached object.
70     *
71     * @return \Memcached
72     */
73    public function memcached(): \Memcached
74    {
75        return $this->memcached;
76    }
77
78    /**
79     * Get the current version of memcached.
80     *
81     * @param  string $host
82     * @param  int    $port
83     * @param  int    $weight
84     * @return Memcached
85     */
86    public function addServer(string $host, int $port = 11211, int $weight = 1): Memcached
87    {
88        $this->memcached->addServer($host, $port, $weight);
89        return $this;
90    }
91
92    /**
93     * Get the current version of memcached.
94     *
95     * @param  array $servers
96     * @return Memcached
97     */
98    public function addServers(array $servers): Memcached
99    {
100        $this->memcached->addServers($servers);
101        return $this;
102    }
103
104    /**
105     * Get the current version of memcached.
106     *
107     * @return ?string
108     */
109    public function getVersion(): ?string
110    {
111        return $this->version;
112    }
113
114    /**
115     * Get the time-to-live for an item in cache
116     *
117     * @param  string $id
118     * @return int
119     */
120    public function getItemTtl(string $id): int
121    {
122        $cacheValue = $this->memcached->get($id);
123        $ttl        = false;
124
125        if ($cacheValue !== false) {
126            $ttl = $cacheValue['ttl'];
127        }
128
129        return $ttl;
130    }
131
132    /**
133     * Save an item to cache
134     *
135     * @param  string $id
136     * @param  mixed  $value
137     * @param  ?int   $ttl
138     * @return Memcached
139     */
140    public function saveItem(string $id, mixed $value, ?int $ttl = null): Memcached
141    {
142        $cacheValue = [
143            'start' => time(),
144            'ttl'   => ($ttl !== null) ? $ttl : $this->ttl,
145            'value' => $value
146        ];
147
148        $this->memcached->set($id, $cacheValue, $cacheValue['ttl']);
149
150        return $this;
151    }
152
153    /**
154     * Get an item from cache
155     *
156     * @param  string $id
157     * @return mixed
158     */
159    public function getItem(string $id): mixed
160    {
161        $cacheValue = $this->memcached->get($id);
162        $value      = false;
163
164        if (($cacheValue !== false) &&
165            (($cacheValue['ttl'] == 0) || ((time() - $cacheValue['start']) <= $cacheValue['ttl']))) {
166            $value = $cacheValue['value'];
167        } else {
168            $this->deleteItem($id);
169        }
170
171        return $value;
172    }
173
174    /**
175     * Determine if the item exist in cache
176     *
177     * @param  string $id
178     * @return bool
179     */
180    public function hasItem(string $id): bool
181    {
182        return ($this->getItem($id) !== false);
183    }
184
185    /**
186     * Delete a value in cache
187     *
188     * @param  string $id
189     * @return Memcached
190     */
191    public function deleteItem(string $id): Memcached
192    {
193        $this->memcached->delete($id);
194        return $this;
195    }
196
197    /**
198     * Clear all stored values from cache
199     *
200     * @return Memcached
201     */
202    public function clear(): Memcached
203    {
204        $this->memcached->flush();
205        return $this;
206    }
207
208    /**
209     * Destroy cache resource
210     *
211     * @return Memcached
212     */
213    public function destroy(): Memcached
214    {
215        $this->memcached->flush();
216        $this->memcached = null;
217        return $this;
218    }
219
220}