mirror of
https://github.com/symfony/class-loader.git
synced 2026-03-24 09:12:18 +01:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ffb15eeff | ||
|
|
fa3394c6fd | ||
|
|
5e53d66ce8 | ||
|
|
db283a5469 | ||
|
|
dcee47cd55 | ||
|
|
0e9d7c1215 | ||
|
|
d1e0a27c9c | ||
|
|
aeef488005 | ||
|
|
44c1b7bb7c | ||
|
|
8bff32cf48 | ||
|
|
1c37a180ab | ||
|
|
1fe171b104 | ||
|
|
40585c3fec | ||
|
|
05639e1018 | ||
|
|
4288c63972 | ||
|
|
bdb7ba2680 | ||
|
|
a474c6ead0 | ||
|
|
dc06308090 | ||
|
|
58cfa84f7d | ||
|
|
e69dbce5e1 | ||
|
|
d482b15c7a | ||
|
|
f7c749435b | ||
|
|
50b9d9501e |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,3 @@
|
||||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.3.0
|
||||
-----
|
||||
|
||||
* added a WinCacheClassLoader for WinCache
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class ClassCollectionLoader
|
||||
// auto-reload
|
||||
$reload = false;
|
||||
if ($autoReload) {
|
||||
$metadata = $cacheDir.'/'.$name.$extension.'.meta';
|
||||
$metadata = $cache.'.meta';
|
||||
if (!is_file($metadata) || !is_file($cache)) {
|
||||
$reload = true;
|
||||
} else {
|
||||
@@ -169,18 +169,19 @@ class ClassCollectionLoader
|
||||
$inNamespace = false;
|
||||
prev($tokens);
|
||||
} else {
|
||||
$rawChunk = rtrim($rawChunk) . "\n{";
|
||||
$rawChunk = rtrim($rawChunk)."\n{";
|
||||
$inNamespace = true;
|
||||
}
|
||||
} elseif (T_START_HEREDOC === $token[0]) {
|
||||
$output .= self::compressCode($rawChunk) . $token[1];
|
||||
$output .= self::compressCode($rawChunk).$token[1];
|
||||
do {
|
||||
$token = next($tokens);
|
||||
$output .= $token[1];
|
||||
$output .= is_string($token) ? $token : $token[1];
|
||||
} while ($token[0] !== T_END_HEREDOC);
|
||||
$output .= "\n";
|
||||
$rawChunk = '';
|
||||
} elseif (T_CONSTANT_ENCAPSED_STRING === $token[0]) {
|
||||
$output .= self::compressCode($rawChunk) . $token[1];
|
||||
$output .= self::compressCode($rawChunk).$token[1];
|
||||
$rawChunk = '';
|
||||
} else {
|
||||
$rawChunk .= $token[1];
|
||||
@@ -191,7 +192,7 @@ class ClassCollectionLoader
|
||||
$rawChunk .= "}\n";
|
||||
}
|
||||
|
||||
return $output . self::compressCode($rawChunk);
|
||||
return $output.self::compressCode($rawChunk);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -360,6 +361,7 @@ class ClassCollectionLoader
|
||||
}
|
||||
$resolved[$nodeName] = $node;
|
||||
unset($unresolved[$nodeName]);
|
||||
|
||||
return $resolved;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,13 +164,9 @@ class ClassLoader
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
if ('\\' == $class[0]) {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR;
|
||||
$classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)).DIRECTORY_SEPARATOR;
|
||||
$className = substr($class, $pos + 1);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
@@ -178,21 +174,21 @@ class ClassLoader
|
||||
$className = $class;
|
||||
}
|
||||
|
||||
$classPath .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
|
||||
$classPath .= str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
|
||||
|
||||
foreach ($this->prefixes as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
|
||||
return $dir . DIRECTORY_SEPARATOR . $classPath;
|
||||
if (file_exists($dir.DIRECTORY_SEPARATOR.$classPath)) {
|
||||
return $dir.DIRECTORY_SEPARATOR.$classPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->fallbackDirs as $dir) {
|
||||
if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
|
||||
return $dir . DIRECTORY_SEPARATOR . $classPath;
|
||||
if (file_exists($dir.DIRECTORY_SEPARATOR.$classPath)) {
|
||||
return $dir.DIRECTORY_SEPARATOR.$classPath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ class ClassMapGenerator
|
||||
}
|
||||
}
|
||||
|
||||
$classes[] = ltrim($namespace . $class, '\\');
|
||||
$classes[] = ltrim($namespace.$class, '\\');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -53,7 +53,7 @@ class DebugClassLoader
|
||||
}
|
||||
|
||||
foreach ($functions as $function) {
|
||||
if (is_array($function) && method_exists($function[0], 'findFile')) {
|
||||
if (is_array($function) && !$function[0] instanceof self && method_exists($function[0], 'findFile')) {
|
||||
$function = array(new static($function[0]), 'loadClass');
|
||||
}
|
||||
|
||||
|
||||
@@ -47,10 +47,6 @@ class MapClassLoader
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ('\\' === $class[0]) {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
if (isset($this->map[$class])) {
|
||||
require $this->map[$class];
|
||||
}
|
||||
@@ -65,10 +61,6 @@ class MapClassLoader
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
if ('\\' === $class[0]) {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
if (isset($this->map[$class])) {
|
||||
return $this->map[$class];
|
||||
}
|
||||
|
||||
@@ -206,7 +206,9 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
unlink($file);
|
||||
}
|
||||
spl_autoload_register($r = function ($class) {
|
||||
require_once __DIR__.'/Fixtures/'.str_replace(array('\\', '_'), '/', $class).'.php';
|
||||
if (0 === strpos($class, 'Namespaced') || 0 === strpos($class, 'Pearlike_')) {
|
||||
require_once __DIR__.'/Fixtures/'.str_replace(array('\\', '_'), '/', $class).'.php';
|
||||
}
|
||||
});
|
||||
|
||||
ClassCollectionLoader::load(
|
||||
@@ -225,21 +227,23 @@ class WithComments
|
||||
{
|
||||
public static \$loaded = true;
|
||||
}
|
||||
\$string ='string shoult not be modified';
|
||||
\$heredoc =<<<HD
|
||||
\$string ='string shoult not be modified {\$string}';
|
||||
\$heredoc = (<<<HD
|
||||
|
||||
|
||||
Heredoc should not be modified
|
||||
Heredoc should not be modified {\$string}
|
||||
|
||||
|
||||
HD;
|
||||
HD
|
||||
);
|
||||
\$nowdoc =<<<'ND'
|
||||
|
||||
|
||||
Nowdoc should not be modified
|
||||
Nowdoc should not be modified {\$string}
|
||||
|
||||
|
||||
ND;
|
||||
ND
|
||||
;
|
||||
}
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -54,8 +54,6 @@ class ClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
return array(
|
||||
array('\\Namespaced2\\Foo', 'Namespaced2\\Foo', '->loadClass() loads Namespaced2\Foo class'),
|
||||
array('\\Pearlike2_Foo', 'Pearlike2_Foo', '->loadClass() loads Pearlike2_Foo class'),
|
||||
array('\\Namespaced2\\Bar', '\\Namespaced2\\Bar', '->loadClass() loads Namespaced2\Bar class with a leading slash'),
|
||||
array('\\Pearlike2_Bar', '\\Pearlike2_Bar', '->loadClass() loads Pearlike2_Bar class with a leading slash'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -100,7 +98,7 @@ class ClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$loader->setUseIncludePath(true);
|
||||
$this->assertTrue($loader->getUseIncludePath());
|
||||
|
||||
set_include_path(__DIR__.'/Fixtures/includepath' . PATH_SEPARATOR . $includePath);
|
||||
set_include_path(__DIR__.'/Fixtures/includepath'.PATH_SEPARATOR.$includePath);
|
||||
|
||||
$this->assertEquals(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'includepath'.DIRECTORY_SEPARATOR.'Foo.php', $loader->findFile('Foo'));
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
$finder = new \Symfony\Component\Finder\Finder();
|
||||
$finder->files()->in(__DIR__ . '/Fixtures/beta/NamespaceCollision');
|
||||
$finder->files()->in(__DIR__.'/Fixtures/beta/NamespaceCollision');
|
||||
|
||||
$this->assertEqualsNormalized(array(
|
||||
'NamespaceCollision\\A\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Bar.php',
|
||||
|
||||
52
Tests/DebugClassLoaderTest.php
Normal file
52
Tests/DebugClassLoaderTest.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?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\Component\ClassLoader\Tests;
|
||||
|
||||
use Symfony\Component\ClassLoader\ClassLoader;
|
||||
use Symfony\Component\ClassLoader\DebugClassLoader;
|
||||
|
||||
class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $loader;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->loader = new ClassLoader();
|
||||
spl_autoload_register(array($this->loader, 'loadClass'));
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
spl_autoload_unregister(array($this->loader, 'loadClass'));
|
||||
}
|
||||
|
||||
public function testIdempotence()
|
||||
{
|
||||
DebugClassLoader::enable();
|
||||
DebugClassLoader::enable();
|
||||
|
||||
$functions = spl_autoload_functions();
|
||||
foreach ($functions as $function) {
|
||||
if (is_array($function) && $function[0] instanceof DebugClassLoader) {
|
||||
$reflClass = new \ReflectionClass($function[0]);
|
||||
$reflProp = $reflClass->getProperty('classFinder');
|
||||
$reflProp->setAccessible(true);
|
||||
|
||||
$this->assertNotInstanceOf('Symfony\Component\ClassLoader\DebugClassLoader', $reflProp->getValue($function[0]));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \Exception('DebugClassLoader did not register');
|
||||
}
|
||||
}
|
||||
@@ -17,21 +17,21 @@ class WithComments
|
||||
public static $loaded = true;
|
||||
}
|
||||
|
||||
$string = 'string shoult not be modified';
|
||||
$string = 'string shoult not be modified {$string}';
|
||||
|
||||
$heredoc = (<<<HD
|
||||
|
||||
|
||||
$heredoc = <<<HD
|
||||
Heredoc should not be modified {$string}
|
||||
|
||||
|
||||
Heredoc should not be modified
|
||||
|
||||
|
||||
HD;
|
||||
HD
|
||||
);
|
||||
|
||||
$nowdoc = <<<'ND'
|
||||
|
||||
|
||||
Nowdoc should not be modified
|
||||
Nowdoc should not be modified {$string}
|
||||
|
||||
|
||||
ND;
|
||||
|
||||
@@ -32,8 +32,6 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
return array(
|
||||
array('\\Namespaced\\Foo', 'Namespaced\\Foo', '->loadClass() loads Namespaced\Foo class'),
|
||||
array('\\Pearlike_Foo', 'Pearlike_Foo', '->loadClass() loads Pearlike_Foo class'),
|
||||
array('\\Namespaced\\Bar', '\\Namespaced\\Bar', '->loadClass() loads Namespaced\Bar class with a leading slash'),
|
||||
array('\\Pearlike_Bar', '\\Pearlike_Bar', '->loadClass() loads Pearlike_Bar class with a leading slash'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -49,7 +47,7 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$loader->useIncludePath(true);
|
||||
$this->assertTrue($loader->getUseIncludePath());
|
||||
|
||||
set_include_path(__DIR__.'/Fixtures/includepath' . PATH_SEPARATOR . $includePath);
|
||||
set_include_path(__DIR__.'/Fixtures/includepath'.PATH_SEPARATOR.$includePath);
|
||||
|
||||
$this->assertEquals(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'includepath'.DIRECTORY_SEPARATOR.'Foo.php', $loader->findFile('Foo'));
|
||||
|
||||
|
||||
@@ -263,10 +263,6 @@ class UniversalClassLoader
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
if ('\\' == $class[0]) {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$namespace = substr($class, 0, $pos);
|
||||
|
||||
133
WinCacheClassLoader.php
Normal file
133
WinCacheClassLoader.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?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\Component\ClassLoader;
|
||||
|
||||
/**
|
||||
* WinCacheClassLoader implements a wrapping autoloader cached in WinCache.
|
||||
*
|
||||
* It expects an object implementing a findFile method to find the file. This
|
||||
* allow using it as a wrapper around the other loaders of the component (the
|
||||
* ClassLoader and the UniversalClassLoader for instance) but also around any
|
||||
* other autoloader following this convention (the Composer one for instance)
|
||||
*
|
||||
* $loader = new ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* $cachedLoader = new WinCacheClassLoader('my_prefix', $loader);
|
||||
*
|
||||
* // activate the cached autoloader
|
||||
* $cachedLoader->register();
|
||||
*
|
||||
* // eventually deactivate the non-cached loader if it was registered previously
|
||||
* // to be sure to use the cached one.
|
||||
* $loader->unregister();
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
* @author Artem Ryzhkov <artem@smart-core.org>
|
||||
*/
|
||||
class WinCacheClassLoader
|
||||
{
|
||||
private $prefix;
|
||||
|
||||
/**
|
||||
* The class loader object being decorated.
|
||||
*
|
||||
* @var \Symfony\Component\ClassLoader\ClassLoader
|
||||
* A class loader object that implements the findFile() method.
|
||||
*/
|
||||
protected $decorated;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $prefix The WinCache namespace prefix to use.
|
||||
* @param object $decorated A class loader object that implements the findFile() method.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($prefix, $decorated)
|
||||
{
|
||||
if (!extension_loaded('wincache')) {
|
||||
throw new \RuntimeException('Unable to use WinCacheClassLoader as WinCache is not enabled.');
|
||||
}
|
||||
|
||||
if (!method_exists($decorated, 'findFile')) {
|
||||
throw new \InvalidArgumentException('The class finder must implement a "findFile" method.');
|
||||
}
|
||||
|
||||
$this->prefix = $prefix;
|
||||
$this->decorated = $decorated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param Boolean $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return Boolean|null True, if loaded
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
require $file;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a file by class name while caching lookups to WinCache.
|
||||
*
|
||||
* @param string $class A class name to resolve to file
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
if (false === $file = wincache_ucache_get($this->prefix.$class)) {
|
||||
wincache_ucache_set($this->prefix.$class, $file = $this->decorated->findFile($class), 0);
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes through all unknown calls onto the decorated object.
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
return call_user_func_array(array($this->decorated, $method), $args);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
"target-dir": "Symfony/Component/ClassLoader",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.2-dev"
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user