Skip to content

Commit 7057b71

Browse files
committed
Add APCu support
Support for the APCu extension (through sfAPCuCache) as an alternative to APC which longer works with recent versions of PHP.
1 parent c5c5155 commit 7057b71

File tree

4 files changed

+234
-3
lines changed

4 files changed

+234
-3
lines changed

data/bin/check_configuration.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ function get_ini_path()
8484
check(function_exists('posix_isatty'), 'The posix_isatty() is available', 'Install and enable the php_posix extension (used to colorized the CLI output)', false);
8585

8686
$accelerator =
87-
(function_exists('apc_store') && ini_get('apc.enabled'))
87+
((function_exists('apc_store') || function_exists('apcu_store')) && ini_get('apc.enabled'))
8888
||
8989
function_exists('eaccelerator_put') && ini_get('eaccelerator.enable')
9090
||

lib/autoload/sfCoreAutoload.class.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ static public function make()
194194
'sfcoreautoload' => 'autoload/sfCoreAutoload.class.php',
195195
'sfsimpleautoload' => 'autoload/sfSimpleAutoload.class.php',
196196
'sfapccache' => 'cache/sfAPCCache.class.php',
197+
'sfapcucache' => 'cache/sfAPCuCache.class.php',
197198
'sfcache' => 'cache/sfCache.class.php',
198199
'sfeacceleratorcache' => 'cache/sfEAcceleratorCache.class.php',
199200
'sffilecache' => 'cache/sfFileCache.class.php',

lib/cache/sfAPCuCache.class.php

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the symfony package.
5+
* (c) 2004-2006 Fabien Potencier <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
/**
12+
* Cache class that stores cached content in APCu.
13+
*
14+
* @package symfony
15+
* @subpackage cache
16+
* @author Fabien Potencier <[email protected]>
17+
* @author Paulo M
18+
* @version SVN: $Id$
19+
*/
20+
class sfAPCuCache extends sfCache
21+
{
22+
protected $enabled;
23+
24+
/**
25+
* Initializes this sfCache instance.
26+
*
27+
* Available options:
28+
*
29+
* * see sfCache for options available for all drivers
30+
*
31+
* @see sfCache
32+
* @inheritdoc
33+
*/
34+
public function initialize($options = array())
35+
{
36+
parent::initialize($options);
37+
38+
$this->enabled = function_exists('apcu_store') && ini_get('apc.enabled');
39+
}
40+
41+
/**
42+
* @see sfCache
43+
* @inheritdoc
44+
*/
45+
public function get($key, $default = null)
46+
{
47+
if (!$this->enabled)
48+
{
49+
return $default;
50+
}
51+
52+
$value = $this->fetch($this->getOption('prefix').$key, $has);
53+
54+
return $has ? $value : $default;
55+
}
56+
57+
/**
58+
* @see sfCache
59+
* @inheritdoc
60+
*/
61+
public function has($key)
62+
{
63+
if (!$this->enabled)
64+
{
65+
return false;
66+
}
67+
68+
$this->fetch($this->getOption('prefix').$key, $has);
69+
70+
return $has;
71+
}
72+
73+
private function fetch($key, &$success)
74+
{
75+
$has = null;
76+
$value = apcu_fetch($key, $has);
77+
// the second argument was added in APC 3.0.17. If it is still null we fall back to the value returned
78+
if (null !== $has)
79+
{
80+
$success = $has;
81+
}
82+
else
83+
{
84+
$success = $value !== false;
85+
}
86+
87+
return $value;
88+
}
89+
90+
91+
/**
92+
* @see sfCache
93+
* @inheritdoc
94+
*/
95+
public function set($key, $data, $lifetime = null)
96+
{
97+
if (!$this->enabled)
98+
{
99+
return true;
100+
}
101+
102+
return apcu_store($this->getOption('prefix').$key, $data, $this->getLifetime($lifetime));
103+
}
104+
105+
/**
106+
* @see sfCache
107+
* @inheritdoc
108+
*/
109+
public function remove($key)
110+
{
111+
if (!$this->enabled)
112+
{
113+
return true;
114+
}
115+
116+
return apcu_delete($this->getOption('prefix').$key);
117+
}
118+
119+
/**
120+
* @see sfCache
121+
* @inheritdoc
122+
*/
123+
public function clean($mode = sfCache::ALL)
124+
{
125+
if (!$this->enabled)
126+
{
127+
return true;
128+
}
129+
130+
if (sfCache::ALL === $mode)
131+
{
132+
return apcu_clear_cache();
133+
}
134+
}
135+
136+
/**
137+
* @see sfCache
138+
* @inheritdoc
139+
*/
140+
public function getLastModified($key)
141+
{
142+
if ($info = $this->getCacheInfo($key))
143+
{
144+
return $info['creation_time'] + $info['ttl'] > time() ? $info['mtime'] : 0;
145+
}
146+
147+
return 0;
148+
}
149+
150+
/**
151+
* @see sfCache
152+
* @inheritdoc
153+
*/
154+
public function getTimeout($key)
155+
{
156+
if ($info = $this->getCacheInfo($key))
157+
{
158+
return $info['creation_time'] + $info['ttl'] > time() ? $info['creation_time'] + $info['ttl'] : 0;
159+
}
160+
161+
return 0;
162+
}
163+
164+
/**
165+
* @see sfCache
166+
* @inheritdoc
167+
*/
168+
public function removePattern($pattern)
169+
{
170+
if (!$this->enabled)
171+
{
172+
return true;
173+
}
174+
175+
$infos = apcu_cache_info();
176+
if (!is_array($infos['cache_list']))
177+
{
178+
return;
179+
}
180+
181+
$regexp = self::patternToRegexp($this->getOption('prefix').$pattern);
182+
183+
foreach ($infos['cache_list'] as $info)
184+
{
185+
if (preg_match($regexp, $info['info']))
186+
{
187+
apcu_delete($info['info']);
188+
}
189+
}
190+
}
191+
192+
/**
193+
* Gets the cache info
194+
*
195+
* @param string $key The cache key
196+
*
197+
* @return string
198+
*/
199+
protected function getCacheInfo($key)
200+
{
201+
if (!$this->enabled)
202+
{
203+
return false;
204+
}
205+
206+
$infos = apcu_cache_info();
207+
208+
if (is_array($infos['cache_list']))
209+
{
210+
foreach ($infos['cache_list'] as $info)
211+
{
212+
if ($this->getOption('prefix').$key == $info['info'])
213+
{
214+
return $info;
215+
}
216+
}
217+
}
218+
219+
return null;
220+
}
221+
}

test/unit/cache/sfAPCCacheTest.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,18 @@
1313
$plan = 64;
1414
$t = new lime_test($plan);
1515

16+
if (extension_loaded('apc')) {
17+
$cacheClass = 'sfAPCCache';
18+
} elseif (extension_loaded('apcu')) {
19+
$cacheClass = 'sfAPCuCache';
20+
} else {
21+
$t->skip('APC or APCu must be loaded to run these tests', $plan);
22+
return;
23+
}
24+
1625
try
1726
{
18-
new sfAPCCache();
27+
new $cacheClass();
1928
}
2029
catch (sfInitializationException $e)
2130
{
@@ -36,7 +45,7 @@
3645

3746
// ->initialize()
3847
$t->diag('->initialize()');
39-
$cache = new sfAPCCache();
48+
$cache = new $cacheClass();
4049
$cache->initialize();
4150

4251
// make sure expired keys are dropped

0 commit comments

Comments
 (0)