These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Pimf |
||
4 | * |
||
5 | * @copyright Copyright (c) Gjero Krsteski (http://krsteski.de) |
||
6 | * @license http://opensource.org/licenses/MIT MIT License |
||
7 | */ |
||
8 | |||
9 | namespace Pimf\Cache\Storages; |
||
10 | |||
11 | /** |
||
12 | * This class provides the functionality required to store |
||
13 | * and retrieve PHP strings, integers or arrays. |
||
14 | * |
||
15 | * It uses the database (dbm-style) abstraction layer for persistence. |
||
16 | * Even instances of SimpleXMLElement can be stored. You don't have |
||
17 | * to matter about the size of the cache-file. It depends on the free |
||
18 | * space of your disk. |
||
19 | * |
||
20 | * @package Cache_Storages |
||
21 | * @author Gjero Krsteski <[email protected]> |
||
22 | */ |
||
23 | class Dba extends Storage |
||
24 | { |
||
25 | /** |
||
26 | * @var resource |
||
27 | */ |
||
28 | protected $dba; |
||
29 | |||
30 | /** |
||
31 | * @var string |
||
32 | */ |
||
33 | protected $handler; |
||
34 | |||
35 | /** |
||
36 | * @var string |
||
37 | */ |
||
38 | protected $file; |
||
39 | |||
40 | /** |
||
41 | * @param string $file the cache-file. |
||
42 | * |
||
43 | * @param string $handler the dba handler. |
||
44 | * |
||
45 | * You have to install one of this handlers before use. |
||
46 | * |
||
47 | * cdb = Tiny Constant Database - for reading. |
||
48 | * cdb_make = Tiny Constant Database - for writing. |
||
49 | * db4 = Oracle Berkeley DB 4 - for reading and writing. |
||
50 | * qdbm = Quick Database Manager - for reading and writing. |
||
51 | * gdbm = GNU Database Manager - for reading and writing. |
||
52 | * flatfile = default dba extension - for reading and writing. |
||
53 | * |
||
54 | * Use flatfile-handler only when you cannot install one, |
||
55 | * of the libraries required by the other handlers, |
||
56 | * and when you cannot use bundled cdb handler. |
||
57 | * |
||
58 | * @param string $mode For read/write access, database creation if it doesn't currently exist. |
||
59 | * |
||
60 | * @param boolean $persistently |
||
61 | * |
||
62 | * @throws \RuntimeException If no DBA extension or handler installed. |
||
63 | */ |
||
64 | public function __construct($file, $handler = 'flatfile', $mode = 'c', $persistently = true) |
||
65 | { |
||
66 | if (false === extension_loaded('dba')) { |
||
67 | throw new \RuntimeException('The DBA extension is required for this wrapper, but the extension is not loaded'); |
||
68 | } |
||
69 | |||
70 | if (false === in_array($handler, dba_handlers(false))) { |
||
71 | throw new \RuntimeException('The ' . $handler . ' handler is required for the DBA extension, but the handler is not installed'); |
||
72 | } |
||
73 | |||
74 | $this->dba = (true === $persistently) ? dba_popen($file, $mode, $handler) : dba_open($file, $mode, $handler); |
||
75 | |||
76 | $this->file = $file; |
||
77 | $this->handler = $handler; |
||
78 | } |
||
79 | |||
80 | /** |
||
81 | * Closes an open dba resource |
||
82 | * |
||
83 | * @return void |
||
84 | */ |
||
85 | public function __destruct() |
||
86 | { |
||
87 | if ($this->dba) { |
||
88 | dba_close($this->dba); |
||
89 | $this->dba = null; |
||
90 | } |
||
91 | } |
||
92 | |||
93 | /** |
||
94 | * @param string $key |
||
95 | * @param mixed $value |
||
96 | * @param int $minutes |
||
97 | * |
||
98 | * @return bool |
||
99 | */ |
||
100 | public function put($key, $value, $minutes) |
||
101 | { |
||
102 | if ($minutes <= 0) { |
||
103 | return; |
||
104 | } |
||
105 | |||
106 | $value = self::expiration($minutes) . serialize($value); |
||
107 | |||
108 | if (true === $this->has($key)) { |
||
109 | return dba_replace($key, $value, $this->dba); |
||
110 | } |
||
111 | |||
112 | return dba_insert($key, $value, $this->dba); |
||
113 | } |
||
114 | |||
115 | /** |
||
116 | * @param string $key |
||
117 | * @param null $default |
||
118 | * |
||
119 | * @return bool|mixed|null |
||
120 | */ |
||
121 | public function get($key, $default = null) |
||
122 | { |
||
123 | $res = $this->retrieve($key); |
||
124 | |||
125 | if (false === $res) { |
||
126 | $this->forget($key); |
||
127 | |||
128 | return false; |
||
129 | } |
||
130 | |||
131 | return $res; |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * @param string $key |
||
136 | * |
||
137 | * @return bool|mixed |
||
138 | */ |
||
139 | View Code Duplication | protected function retrieve($key) |
|
0 ignored issues
–
show
|
|||
140 | { |
||
141 | $value = dba_fetch($key, $this->dba); |
||
142 | |||
143 | if (false === $value) { |
||
144 | return null; |
||
145 | } |
||
146 | |||
147 | // compare the timestamp to the current time when we read the value. |
||
148 | if (time() >= substr($value, 0, 10)) { |
||
149 | $this->forget($key); |
||
150 | return null; |
||
151 | } |
||
152 | |||
153 | return unserialize(substr($value, 10)); |
||
154 | } |
||
155 | |||
156 | /** |
||
157 | * @param string $key |
||
158 | * |
||
159 | * @return boolean |
||
160 | */ |
||
161 | public function forget($key) |
||
162 | { |
||
163 | if (false === is_resource($this->dba)) { |
||
164 | return false; |
||
165 | } |
||
166 | |||
167 | return dba_delete($key, $this->dba); |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * @param string $key |
||
172 | * |
||
173 | * @return boolean |
||
174 | */ |
||
175 | public function has($key) |
||
176 | { |
||
177 | return dba_exists($key, $this->dba); |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * Write an item to the cache for five years. |
||
182 | * |
||
183 | * @param $key |
||
184 | * @param $value |
||
185 | * |
||
186 | * @return boolean |
||
187 | */ |
||
188 | public function forever($key, $value) |
||
189 | { |
||
190 | return $this->put($key, $value, 2628000); |
||
191 | } |
||
192 | |||
193 | /** |
||
194 | * Cleans and optimizes the cache from all expired entries. |
||
195 | * |
||
196 | * @return bool |
||
197 | */ |
||
198 | public function clean() |
||
199 | { |
||
200 | $dba = $this->dba; |
||
201 | $key = dba_firstkey($dba); |
||
202 | |||
203 | while ($key !== false && $key !== null) { |
||
204 | $this->retrieve($key); |
||
205 | $key = dba_nextkey($dba); |
||
206 | } |
||
207 | |||
208 | return dba_optimize($dba); |
||
209 | } |
||
210 | |||
211 | /** |
||
212 | * Flush the whole storage. |
||
213 | * |
||
214 | * @return bool |
||
215 | */ |
||
216 | public function flush() |
||
217 | { |
||
218 | if (file_exists($this->file)) { |
||
219 | |||
220 | // We close the dba file before deleting |
||
221 | // and reopen on next use. |
||
222 | $this->__destruct(); |
||
223 | |||
224 | unlink($this->file); |
||
225 | |||
226 | clearstatcache(); |
||
227 | |||
228 | return true; |
||
229 | } |
||
230 | |||
231 | return false; |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * @return string |
||
236 | */ |
||
237 | public function getFile() |
||
238 | { |
||
239 | return $this->file; |
||
240 | } |
||
241 | } |
||
242 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.