[ClassLoader] Add ClassCollectionLoader::inline() to generate inlined-classes files
This commit is contained in:
parent
36ec08563e
commit
88fdceadd4
@ -21,6 +21,13 @@ use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
|||||||
*/
|
*/
|
||||||
class ClassCacheCacheWarmer implements CacheWarmerInterface
|
class ClassCacheCacheWarmer implements CacheWarmerInterface
|
||||||
{
|
{
|
||||||
|
private $declaredClasses;
|
||||||
|
|
||||||
|
public function __construct(array $declaredClasses = null)
|
||||||
|
{
|
||||||
|
$this->declaredClasses = $declaredClasses;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Warms up the cache.
|
* Warms up the cache.
|
||||||
*
|
*
|
||||||
@ -37,8 +44,9 @@ class ClassCacheCacheWarmer implements CacheWarmerInterface
|
|||||||
if (file_exists($cacheDir.'/classes.php')) {
|
if (file_exists($cacheDir.'/classes.php')) {
|
||||||
return;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,15 +170,23 @@ class FrameworkExtension extends Extension
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->addClassesToCompile(array(
|
$this->addClassesToCompile(array(
|
||||||
|
'Symfony\\Component\\Config\\ConfigCache',
|
||||||
'Symfony\\Component\\Config\\FileLocator',
|
'Symfony\\Component\\Config\\FileLocator',
|
||||||
|
|
||||||
'Symfony\\Component\\Debug\\ErrorHandler',
|
'Symfony\\Component\\Debug\\ErrorHandler',
|
||||||
|
|
||||||
|
'Symfony\\Component\\DependencyInjection\\ContainerAwareInterface',
|
||||||
|
'Symfony\\Component\\DependencyInjection\\Container',
|
||||||
|
|
||||||
'Symfony\\Component\\EventDispatcher\\Event',
|
'Symfony\\Component\\EventDispatcher\\Event',
|
||||||
'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher',
|
'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher',
|
||||||
|
|
||||||
|
'Symfony\\Component\\HttpFoundation\\Response',
|
||||||
|
'Symfony\\Component\\HttpFoundation\\ResponseHeaderBag',
|
||||||
|
|
||||||
'Symfony\\Component\\HttpKernel\\EventListener\\ResponseListener',
|
'Symfony\\Component\\HttpKernel\\EventListener\\ResponseListener',
|
||||||
'Symfony\\Component\\HttpKernel\\EventListener\\RouterListener',
|
'Symfony\\Component\\HttpKernel\\EventListener\\RouterListener',
|
||||||
|
'Symfony\\Component\\HttpKernel\\Bundle\\Bundle',
|
||||||
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver',
|
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver',
|
||||||
'Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver',
|
'Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver',
|
||||||
'Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata',
|
'Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata',
|
||||||
@ -189,13 +197,18 @@ class FrameworkExtension extends Extension
|
|||||||
'Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent',
|
'Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent',
|
||||||
'Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent',
|
'Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent',
|
||||||
'Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent',
|
'Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent',
|
||||||
|
'Symfony\\Component\\HttpKernel\\HttpKernel',
|
||||||
'Symfony\\Component\\HttpKernel\\KernelEvents',
|
'Symfony\\Component\\HttpKernel\\KernelEvents',
|
||||||
'Symfony\\Component\\HttpKernel\\Config\\FileLocator',
|
'Symfony\\Component\\HttpKernel\\Config\\FileLocator',
|
||||||
|
|
||||||
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerNameParser',
|
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerNameParser',
|
||||||
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver',
|
'Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver',
|
||||||
|
|
||||||
// Cannot be included because annotations will parse the big compiled class file
|
// Cannot be included because annotations will parse the big compiled class file
|
||||||
// 'Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller',
|
// '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',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,17 @@
|
|||||||
|
|
||||||
<service id="kernel.class_cache.cache_warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\ClassCacheCacheWarmer">
|
<service id="kernel.class_cache.cache_warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\ClassCacheCacheWarmer">
|
||||||
<tag name="kernel.cache_warmer" />
|
<tag name="kernel.cache_warmer" />
|
||||||
|
<argument type="collection">
|
||||||
|
<argument>Doctrine\Common\Annotations\AnnotationRegistry</argument>
|
||||||
|
<argument>Symfony\Component\HttpFoundation\ParameterBag</argument>
|
||||||
|
<argument>Symfony\Component\HttpFoundation\HeaderBag</argument>
|
||||||
|
<argument>Symfony\Component\HttpFoundation\FileBag</argument>
|
||||||
|
<argument>Symfony\Component\HttpFoundation\ServerBag</argument>
|
||||||
|
<argument>Symfony\Component\HttpFoundation\Request</argument>
|
||||||
|
<argument>Symfony\Component\HttpKernel\Kernel</argument>
|
||||||
|
<argument>Symfony\Component\ClassLoader\ClassCollectionLoader</argument>
|
||||||
|
<argument>Symfony\Component\ClassLoader\ApcClassLoader</argument>
|
||||||
|
</argument>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="cache_clearer" class="Symfony\Component\HttpKernel\CacheClearer\ChainCacheClearer">
|
<service id="cache_clearer" class="Symfony\Component\HttpKernel\CacheClearer\ChainCacheClearer">
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* 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('<?php return %s;', var_export(array(WarmedClass::class), true)));
|
||||||
|
|
||||||
|
$warmer = new ClassCacheCacheWarmer(array(DeclaredClass::class));
|
||||||
|
|
||||||
|
$warmer->warmUp($dir);
|
||||||
|
|
||||||
|
$this->assertSame(<<<'EOTXT'
|
||||||
|
<?php
|
||||||
|
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures
|
||||||
|
{
|
||||||
|
class WarmedClass extends DeclaredClass
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOTXT
|
||||||
|
, file_get_contents($dir.'/classes.php')
|
||||||
|
);
|
||||||
|
|
||||||
|
@unlink($dir.'/classes.map');
|
||||||
|
@unlink($dir.'/classes.php');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures;
|
||||||
|
|
||||||
|
class DeclaredClass
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures;
|
||||||
|
|
||||||
|
class WarmedClass extends DeclaredClass
|
||||||
|
{
|
||||||
|
}
|
@ -19,7 +19,7 @@
|
|||||||
"php": ">=5.5.9",
|
"php": ">=5.5.9",
|
||||||
"symfony/asset": "~2.8|~3.0",
|
"symfony/asset": "~2.8|~3.0",
|
||||||
"symfony/cache": "~3.1",
|
"symfony/cache": "~3.1",
|
||||||
"symfony/class-loader": "~2.8|~3.0",
|
"symfony/class-loader": "~3.2",
|
||||||
"symfony/dependency-injection": "~3.2",
|
"symfony/dependency-injection": "~3.2",
|
||||||
"symfony/config": "~2.8|~3.0",
|
"symfony/config": "~2.8|~3.0",
|
||||||
"symfony/event-dispatcher": "~2.8|~3.0",
|
"symfony/event-dispatcher": "~2.8|~3.0",
|
||||||
|
@ -93,14 +93,41 @@ class ClassCollectionLoader
|
|||||||
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
|
$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();
|
$files = array();
|
||||||
$content = '';
|
$content = '';
|
||||||
foreach (self::getOrderedClasses($classes) as $class) {
|
foreach (self::getOrderedClasses($classes) as $class) {
|
||||||
if (in_array($class->getName(), $declared)) {
|
if (isset($declared[$class->getName()])) {
|
||||||
continue;
|
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()));
|
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($class->getFileName()));
|
||||||
|
|
||||||
@ -116,15 +143,13 @@ class ClassCollectionLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cache the core classes
|
// cache the core classes
|
||||||
|
$cacheDir = dirname($cache);
|
||||||
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
|
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));
|
throw new \RuntimeException(sprintf('Class Collection Loader was not able to create directory "%s"', $cacheDir));
|
||||||
}
|
}
|
||||||
self::writeCacheFile($cache, '<?php '.$content);
|
self::writeCacheFile($cache, '<?php '.$content);
|
||||||
|
|
||||||
if ($autoReload) {
|
return $files;
|
||||||
// save the resources
|
|
||||||
self::writeCacheFile($metadata, serialize(array($files, $classes)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
namespace Symfony\Component\ClassLoader\Tests;
|
namespace Symfony\Component\ClassLoader\Tests;
|
||||||
|
|
||||||
use Symfony\Component\ClassLoader\ClassCollectionLoader;
|
use Symfony\Component\ClassLoader\ClassCollectionLoader;
|
||||||
|
use Symfony\Component\ClassLoader\Tests\Fixtures\DeclaredClass;
|
||||||
|
use Symfony\Component\ClassLoader\Tests\Fixtures\WarmedClass;
|
||||||
|
|
||||||
require_once __DIR__.'/Fixtures/ClassesWithParents/GInterface.php';
|
require_once __DIR__.'/Fixtures/ClassesWithParents/GInterface.php';
|
||||||
require_once __DIR__.'/Fixtures/ClassesWithParents/CInterface.php';
|
require_once __DIR__.'/Fixtures/ClassesWithParents/CInterface.php';
|
||||||
@ -271,4 +273,36 @@ EOF
|
|||||||
|
|
||||||
unlink($file);
|
unlink($file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testInline()
|
||||||
|
{
|
||||||
|
$this->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'
|
||||||
|
<?php
|
||||||
|
namespace Symfony\Component\ClassLoader\Tests\Fixtures
|
||||||
|
{
|
||||||
|
interface WarmedInterface
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Symfony\Component\ClassLoader\Tests\Fixtures
|
||||||
|
{
|
||||||
|
class WarmedClass extends DeclaredClass implements WarmedInterface
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOTXT
|
||||||
|
, file_get_contents($cache)
|
||||||
|
);
|
||||||
|
|
||||||
|
unlink($cache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\ClassLoader\Tests\Fixtures;
|
||||||
|
|
||||||
|
class DeclaredClass implements DeclaredInterface
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\ClassLoader\Tests\Fixtures;
|
||||||
|
|
||||||
|
interface DeclaredInterface
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\ClassLoader\Tests\Fixtures;
|
||||||
|
|
||||||
|
class WarmedClass extends DeclaredClass implements WarmedInterface
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\ClassLoader\Tests\Fixtures;
|
||||||
|
|
||||||
|
interface WarmedInterface
|
||||||
|
{
|
||||||
|
}
|
Reference in New Issue
Block a user