diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 3f15d20699..a62024fd07 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1037,6 +1037,8 @@ class FrameworkExtension extends Extension private function registerCacheConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) { + $nonce = substr(str_replace('/', '-', base64_encode(md5(uniqid(mt_rand(), true), true))), 0, -2); + $container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $nonce); $container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']); foreach (array('doctrine', 'psr6', 'redis') as $name) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml index 6a2e147483..7ca9443d7a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml @@ -27,6 +27,7 @@ + diff --git a/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php b/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php index 96f76ac05e..cdd2c1e5b4 100644 --- a/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Cache\Adapter; +use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\Exception\CacheException; /** @@ -18,7 +19,7 @@ use Symfony\Component\Cache\Exception\CacheException; */ class ApcuAdapter extends AbstractAdapter { - public function __construct($namespace = '', $defaultLifetime = 0) + public function __construct($namespace = '', $defaultLifetime = 0, $nonce = null) { if (!function_exists('apcu_fetch') || !ini_get('apc.enabled') || ('cli' === PHP_SAPI && !ini_get('apc.enable_cli'))) { throw new CacheException('APCu is not enabled'); @@ -27,6 +28,15 @@ class ApcuAdapter extends AbstractAdapter ini_set('apc.use_request_time', 0); } parent::__construct($namespace, $defaultLifetime); + + if (null !== $nonce) { + CacheItem::validateKey($nonce); + + if (!apcu_exists($nonce.':nonce'.$namespace)) { + $this->clear($namespace); + apcu_add($nonce.':nonce'.$namespace, null); + } + } } /** diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php index 5e510e7f8a..9dcbb5ba9d 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php @@ -43,4 +43,29 @@ class ApcuAdapterTest extends CachePoolTest $item = $pool->getItem('foo'); $this->assertFalse($item->isHit()); } + + public function testNonce() + { + $namespace = str_replace('\\', '.', __CLASS__); + + $pool1 = new ApcuAdapter($namespace, 0, 'p1'); + + $item = $pool1->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertTrue($pool1->save($item->set('bar'))); + + $item = $pool1->getItem('foo'); + $this->assertTrue($item->isHit()); + $this->assertSame('bar', $item->get()); + + $pool2 = new ApcuAdapter($namespace, 0, 'p2'); + + $item = $pool2->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get()); + + $item = $pool1->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get()); + } }