diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ClassCacheCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ClassCacheCacheWarmer.php
index 54b9b3395eace..b235c65136555 100644
--- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ClassCacheCacheWarmer.php
+++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ClassCacheCacheWarmer.php
@@ -21,6 +21,13 @@
*/
class ClassCacheCacheWarmer implements CacheWarmerInterface
{
+ private $declaredClasses;
+
+ public function __construct(array $declaredClasses = null)
+ {
+ $this->declaredClasses = $declaredClasses;
+ }
+
/**
* Warms up the cache.
*
@@ -37,8 +44,9 @@ public function warmUp($cacheDir)
if (file_exists($cacheDir.'/classes.php')) {
return;
}
+ $declared = null !== $this->declaredClasses ? $this->declaredClasses : array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
- ClassCollectionLoader::load(include($classmap), $cacheDir, 'classes', false);
+ ClassCollectionLoader::inline(include($classmap), $cacheDir.'/classes.php', $declared);
}
/**
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 8cd1fea64a0fa..d0751c095d165 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -170,15 +170,23 @@ public function load(array $configs, ContainerBuilder $container)
}
$this->addClassesToCompile(array(
+ 'Symfony\\Component\\Config\\ConfigCache',
'Symfony\\Component\\Config\\FileLocator',
'Symfony\\Component\\Debug\\ErrorHandler',
+ 'Symfony\\Component\\DependencyInjection\\ContainerAwareInterface',
+ 'Symfony\\Component\\DependencyInjection\\Container',
+
'Symfony\\Component\\EventDispatcher\\Event',
'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher',
+ 'Symfony\\Component\\HttpFoundation\\Response',
+ 'Symfony\\Component\\HttpFoundation\\ResponseHeaderBag',
+
'Symfony\\Component\\HttpKernel\\EventListener\\ResponseListener',
'Symfony\\Component\\HttpKernel\\EventListener\\RouterListener',
+ 'Symfony\\Component\\HttpKernel\\Bundle\\Bundle',
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver',
'Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver',
'Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata',
@@ -189,13 +197,18 @@ public function load(array $configs, ContainerBuilder $container)
'Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent',
'Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent',
'Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent',
+ 'Symfony\\Component\\HttpKernel\\HttpKernel',
'Symfony\\Component\\HttpKernel\\KernelEvents',
'Symfony\\Component\\HttpKernel\\Config\\FileLocator',
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerNameParser',
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver',
+
// Cannot be included because annotations will parse the big compiled class file
// 'Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller',
+
+ // cannot be included as commands are discovered based on the path to this class via Reflection
+ // 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle',
));
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml
index a5c0baba1b053..71acb1bca2274 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml
@@ -24,6 +24,17 @@
+
+ Doctrine\Common\Annotations\AnnotationRegistry
+ Symfony\Component\HttpFoundation\ParameterBag
+ Symfony\Component\HttpFoundation\HeaderBag
+ Symfony\Component\HttpFoundation\FileBag
+ Symfony\Component\HttpFoundation\ServerBag
+ Symfony\Component\HttpFoundation\Request
+ Symfony\Component\HttpKernel\Kernel
+ Symfony\Component\ClassLoader\ClassCollectionLoader
+ Symfony\Component\ClassLoader\ApcClassLoader
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ClassCacheCacheWarmerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ClassCacheCacheWarmerTest.php
new file mode 100644
index 0000000000000..889601b01fa6f
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ClassCacheCacheWarmerTest.php
@@ -0,0 +1,48 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Tests\CacheWarmer;
+
+use Symfony\Bundle\FrameworkBundle\CacheWarmer\ClassCacheCacheWarmer;
+use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\DeclaredClass;
+use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\WarmedClass;
+use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
+
+class ClassCacheCacheWarmerTest extends TestCase
+{
+ public function testWithDeclaredClasses()
+ {
+ $this->assertTrue(class_exists(WarmedClass::class, true));
+
+ $dir = sys_get_temp_dir();
+ @unlink($dir.'/classes.php');
+ file_put_contents($dir.'/classes.map', sprintf('warmUp($dir);
+
+ $this->assertSame(<<<'EOTXT'
+=5.5.9",
"symfony/asset": "~2.8|~3.0",
"symfony/cache": "~3.1",
- "symfony/class-loader": "~2.8|~3.0",
+ "symfony/class-loader": "~3.2",
"symfony/dependency-injection": "~3.2",
"symfony/config": "~2.8|~3.0",
"symfony/event-dispatcher": "~2.8|~3.0",
diff --git a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php
index 3ec68c6b5eecc..3f7b4a639cabb 100644
--- a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php
+++ b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php
@@ -93,14 +93,41 @@ public static function load($classes, $cacheDir, $name, $autoReload, $adaptive =
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
}
+ $files = self::inline($classes, $cache, $declared);
+
+ if ($autoReload) {
+ // save the resources
+ self::writeCacheFile($metadata, serialize(array(array_values($files), $classes)));
+ }
+ }
+
+ /**
+ * Generates a file where classes and their parents are inlined.
+ *
+ * @param array $classes An array of classes to load
+ * @param string $cache The file where classes are inlined
+ * @param array $excluded An array of classes that won't be inlined
+ *
+ * @return array The source map of inlined classes, with classes as keys and files as values
+ *
+ * @throws \RuntimeException When class can't be loaded
+ */
+ public static function inline($classes, $cache, array $excluded)
+ {
+ $declared = array();
+ foreach (self::getOrderedClasses($excluded) as $class) {
+ $declared[$class->getName()] = true;
+ }
+
$files = array();
$content = '';
foreach (self::getOrderedClasses($classes) as $class) {
- if (in_array($class->getName(), $declared)) {
+ if (isset($declared[$class->getName()])) {
continue;
}
+ $declared[$class->getName()] = true;
- $files[] = $class->getFileName();
+ $files[$class->getName()] = $class->getFileName();
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($class->getFileName()));
@@ -116,15 +143,13 @@ public static function load($classes, $cacheDir, $name, $autoReload, $adaptive =
}
// cache the core classes
+ $cacheDir = dirname($cache);
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
throw new \RuntimeException(sprintf('Class Collection Loader was not able to create directory "%s"', $cacheDir));
}
self::writeCacheFile($cache, 'assertTrue(class_exists(WarmedClass::class, true));
+
+ @unlink($cache = sys_get_temp_dir().'/inline.php');
+
+ $classes = array(WarmedClass::class);
+ $excluded = array(DeclaredClass::class);
+
+ ClassCollectionLoader::inline($classes, $cache, $excluded);
+
+ $this->assertSame(<<<'EOTXT'
+