diff --git a/UPGRADE-3.1.md b/UPGRADE-3.1.md
index 4355a80939657..fffb06bad9354 100644
--- a/UPGRADE-3.1.md
+++ b/UPGRADE-3.1.md
@@ -93,25 +93,8 @@ FrameworkBundle
cache service. If you are using `serializer.mapping.cache.apc`, use
`serializer.mapping.cache.doctrine.apc` instead.
- * The `framework.serializer.cache` option has been deprecated. Configure the
- `cache.serializer` service under `framework.cache.pools` instead.
-
- Before:
-
- ```yaml
- framework:
- serializer:
- cache: serializer.mapping.cache.apc
- ```
-
- After:
-
- ```yaml
- framework:
- cache:
- pools:
- cache.serializer:
- adapter: cache.adapter.apcu
+ * The `framework.serializer.cache` option has been deprecated. APCu should now
+ be automatically used when available so you can remove this configuration key.
HttpKernel
----------
diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md
index 1f5a00bbf9306..35e2471d9033a 100644
--- a/UPGRADE-4.0.md
+++ b/UPGRADE-4.0.md
@@ -80,26 +80,8 @@ FrameworkBundle
* The service `serializer.mapping.cache.apc` has been removed; use
`serializer.mapping.cache.doctrine.apc` instead.
- * The `framework.serializer.cache` option has been removed. Configure the
- `cache.serializer` service under `framework.cache.pools` instead.
-
- Before:
-
- ```yaml
- framework:
- serializer:
- cache: serializer.mapping.cache.apc
- ```
-
- After:
-
- ```yaml
- framework:
- cache:
- pools:
- cache.serializer:
- adapter: cache.adapter.apcu
- ```
+ * The `framework.serializer.cache` option has been removed. APCu should now
+ be automatically used when available so you can remove this configuration key.
HttpKernel
----------
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index ed56b03911dcf..f38a6dd638507 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -564,7 +564,7 @@ private function addCacheSection(ArrayNodeDefinition $rootNode)
->end()
->scalarNode('system')
->info('System related cache pools configuration')
- ->defaultValue('cache.adapter.filesystem')
+ ->defaultValue('cache.adapter.system')
->end()
->scalarNode('directory')->defaultValue('%kernel.cache_dir%/pools')->end()
->scalarNode('default_doctrine_provider')->end()
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index a62024fd07118..84a5e3d0946d7 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -1039,6 +1039,7 @@ private function registerCacheConfiguration(array $config, ContainerBuilder $con
{
$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.system')->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 7ca9443d7af53..931b74a58d7fc 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml
@@ -10,7 +10,7 @@
-
+
@@ -22,6 +22,17 @@
+
+
+
+
+
+
+
+ %kernel.cache_dir%/pools
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
index b948d22f11f76..e1a677daa73a5 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
@@ -269,7 +269,7 @@ protected static function getBundleDefaultConfig()
'cache' => array(
'pools' => array(),
'app' => 'cache.adapter.filesystem',
- 'system' => 'cache.adapter.filesystem',
+ 'system' => 'cache.adapter.system',
'directory' => '%kernel.cache_dir%/pools',
'default_redis_provider' => 'redis://localhost',
),
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index b6662a05a957f..f0d5692d62863 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -14,6 +14,7 @@
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
use Symfony\Component\Cache\Adapter\ApcuAdapter;
+use Symfony\Component\Cache\Adapter\ChainAdapter;
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\ProxyAdapter;
@@ -728,6 +729,9 @@ private function assertCachePoolServiceDefinitionIsCreated(ContainerBuilder $con
$this->assertSame(DoctrineAdapter::class, $parentDefinition->getClass());
break;
case 'cache.app':
+ if (ChainAdapter::class === $parentDefinition->getClass()) {
+ break;
+ }
case 'cache.adapter.filesystem':
$this->assertSame(FilesystemAdapter::class, $parentDefinition->getClass());
break;
diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json
index 2570b6c40bb49..f6f66eeb113e4 100644
--- a/src/Symfony/Bundle/FrameworkBundle/composer.json
+++ b/src/Symfony/Bundle/FrameworkBundle/composer.json
@@ -58,6 +58,7 @@
"phpdocumentor/reflection-docblock": "<3.0"
},
"suggest": {
+ "ext-apcu": "For best performance of the system caches",
"symfony/console": "For using the console commands",
"symfony/form": "For using forms",
"symfony/serializer": "For using the serializer service",
diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php
index b0c989e717ecf..8c753fb814301 100644
--- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php
@@ -14,6 +14,7 @@
use Psr\Cache\CacheItemInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
+use Psr\Log\LoggerInterface;
use Symfony\Component\Cache\CacheItem;
/**
@@ -67,6 +68,24 @@ function ($deferred, $namespace, &$expiredIds) {
);
}
+ public static function createSystemCache($namespace, $defaultLifetime, $nonce, $directory, LoggerInterface $logger = null)
+ {
+ $fs = new FilesystemAdapter($namespace, $defaultLifetime, $directory);
+ if (null !== $logger) {
+ $fs->setLogger($logger);
+ }
+ if (!ApcuAdapter::isSupported()) {
+ return $fs;
+ }
+
+ $apcu = new ApcuAdapter($namespace, $defaultLifetime / 5, $nonce);
+ if (null !== $logger) {
+ $apcu->setLogger($logger);
+ }
+
+ return new ChainAdapter(array($apcu, $fs));
+ }
+
/**
* Fetches several cache items.
*
diff --git a/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php b/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php
index cdd2c1e5b4d7f..35a4d987e338c 100644
--- a/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php
+++ b/src/Symfony/Component/Cache/Adapter/ApcuAdapter.php
@@ -19,9 +19,14 @@
*/
class ApcuAdapter extends AbstractAdapter
{
+ public static function isSupported()
+ {
+ return function_exists('apcu_fetch') && ini_get('apc.enabled') && !('cli' === PHP_SAPI && !ini_get('apc.enable_cli'));
+ }
+
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'))) {
+ if (!static::isSupported()) {
throw new CacheException('APCu is not enabled');
}
if ('cli' === PHP_SAPI) {