-
-
Notifications
You must be signed in to change notification settings - Fork 133
/
Apc.php
169 lines (144 loc) · 4.82 KB
/
Apc.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
<?php
/*
* This file is part of the Stash package.
*
* (c) Robert Hafner <tedivm@tedivm.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Stash\Driver;
use Stash;
use Stash\Exception\RuntimeException;
/**
* The StashApc is a wrapper for the APC extension, which allows developers to store data in memory.
*
* @package Stash
* @author Robert Hafner <tedivm@tedivm.com>
*/
class Apc implements DriverInterface
{
protected $ttl = 300;
protected $apcNamespace;
/**
* This function should takes an array which is used to pass option values to the driver.
*
* * ttl - This is the maximum time the item will be stored.
* * namespace - This should be used when multiple projects may use the same library.
*
* @param array $options
*/
public function __construct(array $options = array())
{
if (isset($options['ttl']) && is_numeric($options['ttl'])) {
$this->ttl = (int)$options['ttl'];
}
$this->apcNamespace = isset($options['namespace']) ? $options['namespace'] : md5(__FILE__);
if(!static::isAvailable()) {
throw new RuntimeException('Extension is not installed.');
}
}
/**
* Empty destructor to maintain a standardized interface across all drivers.
*
*/
public function __destruct()
{
}
/**
* This function should return the data array, exactly as it was received by the storeData function, or false if it
* is not present. This array should have a value for "createdOn" and for "return", which should be the data the
* main script is trying to store.
*
* @param array $key
* @return array
*/
public function getData($key)
{
$keyString = self::makeKey($key);
$data = apc_fetch($keyString, $success);
return $success ? $data : false;
}
/**
* This function takes an array as its first argument and the expiration time as the second. This array contains two
* items, "createdOn" describing the first time the item was called and "return", which is the data that needs to be
* stored. This function needs to store that data in such a way that it can be retrieved exactly as it was sent. The
* expiration time needs to be stored with this data.
*
* @param array $key
* @param array $data
* @param int $expiration
* @return bool
*/
public function storeData($key, $data, $expiration)
{
$life = $this->getCacheTime($expiration);
return apc_store($this->makeKey($key), array('data' => $data, 'expiration' => $expiration), $life);
}
/**
* This function should clear the cache tree using the key array provided. If called with no arguments the entire
* cache needs to be cleared.
*
* @param null|array $key
* @return bool
*/
public function clear($key = null)
{
if (!isset($key)) {
return apc_clear_cache('user');
} else {
$keyRegex = '[' . $this->makeKey($key) . '*]';
$chunkSize = isset($this->chunkSize) && is_numeric($this->chunkSize) ? $this->chunkSize : 100;
$it = new \APCIterator('user', $keyRegex, \APC_ITER_KEY, $chunkSize);
foreach ($it as $key) {
apc_delete($key);
}
}
return true;
}
/**
* This function is used to remove expired items from the cache.
*
* @return bool
*/
public function purge()
{
$now = time();
$keyRegex = '[' . $this->makeKey(array()) . '*]';
$chunkSize = isset($this->chunkSize) && is_numeric($this->chunkSize) ? $this->chunkSize : 100;
$it = new \APCIterator('user', $keyRegex, \APC_ITER_KEY, $chunkSize);
foreach ($it as $key) {
$data = apc_fetch($key, $success);
$data = $data[$key['key']];
if ($success && is_array($data) && $data['expiration'] <= $now) {
apc_delete($key);
}
}
return true;
}
/**
* This driver is available iff the apc extension is present and loaded on the system.
*
* @return bool
*/
static public function isAvailable()
{
return extension_loaded('apc') && ini_get('apc.enabled');
}
protected function makeKey($key)
{
$keyString = md5(__FILE__) . '::'; // make it unique per install
if (isset($this->apcNamespace)) {
$keyString .= $this->apcNamespace . '::';
}
foreach ($key as $piece) {
$keyString .= $piece . '::';
}
return $keyString;
}
protected function getCacheTime($expiration)
{
$life = $expiration - time(true);
return $this->ttl > $life ? $this->ttl : $life;
}
}