mirror of
https://github.com/symfony/class-loader.git
synced 2026-03-24 09:12:18 +01:00
Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a2ebedbc7 | ||
|
|
181f15a84f | ||
|
|
0a5217edb6 | ||
|
|
7bb58f990b | ||
|
|
e5f3ef7ebd | ||
|
|
77f69969b1 | ||
|
|
8478872572 | ||
|
|
c1ae3ba1b3 | ||
|
|
722013ba00 | ||
|
|
7809fd30ec | ||
|
|
73d1745306 | ||
|
|
7239180fee | ||
|
|
622d370a07 | ||
|
|
827c54ee98 | ||
|
|
5c9ded1bca | ||
|
|
4f3f111b0d | ||
|
|
7ffb15eeff | ||
|
|
0cea075c5e | ||
|
|
fa3394c6fd | ||
|
|
982a8ec292 | ||
|
|
5e53d66ce8 | ||
|
|
56d6c13a89 | ||
|
|
db283a5469 | ||
|
|
dcee47cd55 | ||
|
|
d1e0a27c9c | ||
|
|
aeef488005 | ||
|
|
44c1b7bb7c | ||
|
|
8bff32cf48 | ||
|
|
1c37a180ab | ||
|
|
1fe171b104 | ||
|
|
40585c3fec | ||
|
|
a474c6ead0 | ||
|
|
dc06308090 | ||
|
|
58cfa84f7d | ||
|
|
a61d4e81cd | ||
|
|
e69dbce5e1 | ||
|
|
d482b15c7a | ||
|
|
bcf4926ca7 | ||
|
|
f7c749435b | ||
|
|
66599a59d7 | ||
|
|
50b9d9501e | ||
|
|
e9e73907ef | ||
|
|
f75698ef2a | ||
|
|
5f9dc90230 | ||
|
|
0730d0f8f9 | ||
|
|
18fab536be | ||
|
|
c6d6082c7c | ||
|
|
329e3c07fd | ||
|
|
439c25836a | ||
|
|
cddda216d0 | ||
|
|
107c3efbd8 | ||
|
|
171fa40ebb | ||
|
|
5a119c3862 | ||
|
|
2d1cdaebc9 | ||
|
|
8a43fc467a | ||
|
|
1d40164f58 | ||
|
|
438613c948 | ||
|
|
969e077c5a | ||
|
|
f291c7b0a9 | ||
|
|
cd3c46b051 | ||
|
|
6d7411ecce | ||
|
|
10a8db6444 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
|
||||
@@ -42,28 +42,38 @@ namespace Symfony\Component\ClassLoader;
|
||||
class ApcClassLoader
|
||||
{
|
||||
private $prefix;
|
||||
private $classFinder;
|
||||
|
||||
/**
|
||||
* 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 A prefix to create a namespace in APC
|
||||
* @param object $classFinder An object that implements findFile() method.
|
||||
* @param string $prefix The APC namespace prefix to use.
|
||||
* @param object $decorated A class loader object that implements the findFile() method.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($prefix, $classFinder)
|
||||
public function __construct($prefix, $decorated)
|
||||
{
|
||||
if (!extension_loaded('apc')) {
|
||||
throw new \RuntimeException('Unable to use ApcClassLoader as APC is not enabled.');
|
||||
}
|
||||
|
||||
if (!method_exists($classFinder, 'findFile')) {
|
||||
if (!method_exists($decorated, 'findFile')) {
|
||||
throw new \InvalidArgumentException('The class finder must implement a "findFile" method.');
|
||||
}
|
||||
|
||||
$this->prefix = $prefix;
|
||||
$this->classFinder = $classFinder;
|
||||
$this->decorated = $decorated;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,9 +120,18 @@ class ApcClassLoader
|
||||
public function findFile($class)
|
||||
{
|
||||
if (false === $file = apc_fetch($this->prefix.$class)) {
|
||||
apc_store($this->prefix.$class, $file = $this->classFinder->findFile($class));
|
||||
apc_store($this->prefix.$class, $file = $this->decorated->findFile($class));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ class ApcUniversalClassLoader extends UniversalClassLoader
|
||||
*
|
||||
* @param string $prefix A prefix to create a namespace in APC
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($prefix)
|
||||
|
||||
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,6 +1,16 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.4.0
|
||||
-----
|
||||
|
||||
* deprecated the DebugClassLoader as it has been moved to the Debug component instead
|
||||
|
||||
2.3.0
|
||||
-----
|
||||
|
||||
* added a WinCacheClassLoader for WinCache
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ class ClassCollectionLoader
|
||||
$classes = array_diff($classes, $declared);
|
||||
|
||||
// the cache is different depending on which classes are already declared
|
||||
$name = $name.'-'.substr(md5(implode('|', $classes)), 0, 5);
|
||||
$name = $name.'-'.substr(hash('sha256', implode('|', $classes)), 0, 5);
|
||||
}
|
||||
|
||||
$classes = array_unique($classes);
|
||||
@@ -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 {
|
||||
@@ -104,14 +104,14 @@ class ClassCollectionLoader
|
||||
|
||||
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($class->getFileName()));
|
||||
|
||||
// add namespace declaration for global code
|
||||
// fakes namespace declaration for global code
|
||||
if (!$class->inNamespace()) {
|
||||
$c = "\nnamespace\n{\n".self::stripComments($c)."\n}\n";
|
||||
} else {
|
||||
$c = self::fixNamespaceDeclarations('<?php '.$c);
|
||||
$c = preg_replace('/^\s*<\?php/', '', $c);
|
||||
$c = "\nnamespace\n{\n".$c."\n}\n";
|
||||
}
|
||||
|
||||
$c = self::fixNamespaceDeclarations('<?php '.$c);
|
||||
$c = preg_replace('/^\s*<\?php/', '', $c);
|
||||
|
||||
$content .= $c;
|
||||
}
|
||||
|
||||
@@ -144,45 +144,79 @@ class ClassCollectionLoader
|
||||
return $source;
|
||||
}
|
||||
|
||||
$rawChunk = '';
|
||||
$output = '';
|
||||
$inNamespace = false;
|
||||
$tokens = token_get_all($source);
|
||||
|
||||
for ($i = 0, $max = count($tokens); $i < $max; $i++) {
|
||||
$token = $tokens[$i];
|
||||
for (reset($tokens); false !== $token = current($tokens); next($tokens)) {
|
||||
if (is_string($token)) {
|
||||
$output .= $token;
|
||||
$rawChunk .= $token;
|
||||
} elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
|
||||
// strip comments
|
||||
continue;
|
||||
} elseif (T_NAMESPACE === $token[0]) {
|
||||
if ($inNamespace) {
|
||||
$output .= "}\n";
|
||||
$rawChunk .= "}\n";
|
||||
}
|
||||
$output .= $token[1];
|
||||
$rawChunk .= $token[1];
|
||||
|
||||
// namespace name and whitespaces
|
||||
while (($t = $tokens[++$i]) && is_array($t) && in_array($t[0], array(T_WHITESPACE, T_NS_SEPARATOR, T_STRING))) {
|
||||
$output .= $t[1];
|
||||
while (($t = next($tokens)) && is_array($t) && in_array($t[0], array(T_WHITESPACE, T_NS_SEPARATOR, T_STRING))) {
|
||||
$rawChunk .= $t[1];
|
||||
}
|
||||
if (is_string($t) && '{' === $t) {
|
||||
if ('{' === $t) {
|
||||
$inNamespace = false;
|
||||
--$i;
|
||||
prev($tokens);
|
||||
} else {
|
||||
$output = rtrim($output);
|
||||
$output .= "\n{";
|
||||
$rawChunk = rtrim($rawChunk)."\n{";
|
||||
$inNamespace = true;
|
||||
}
|
||||
} elseif (T_START_HEREDOC === $token[0]) {
|
||||
$output .= self::compressCode($rawChunk).$token[1];
|
||||
do {
|
||||
$token = next($tokens);
|
||||
$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];
|
||||
$rawChunk = '';
|
||||
} else {
|
||||
$output .= $token[1];
|
||||
$rawChunk .= $token[1];
|
||||
}
|
||||
}
|
||||
|
||||
if ($inNamespace) {
|
||||
$output .= "}\n";
|
||||
$rawChunk .= "}\n";
|
||||
}
|
||||
|
||||
return $output;
|
||||
return $output.self::compressCode($rawChunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only useful for testing.
|
||||
*/
|
||||
public static function enableTokenizer($bool)
|
||||
{
|
||||
self::$useTokenizer = (Boolean) $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips leading & trailing ws, multiple EOL, multiple ws.
|
||||
*
|
||||
* @param string $code Original PHP code
|
||||
*
|
||||
* @return string compressed code
|
||||
*/
|
||||
private static function compressCode($code)
|
||||
{
|
||||
return preg_replace(
|
||||
array('/^\s+/m', '/\s+$/m', '/([\n\r]+ *[\n\r]+)+/', '/[ \t]+/'),
|
||||
array('', '', "\n", ' '),
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,43 +239,12 @@ class ClassCollectionLoader
|
||||
throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes comments from a PHP source string.
|
||||
*
|
||||
* We don't use the PHP php_strip_whitespace() function
|
||||
* as we want the content to be readable and well-formatted.
|
||||
*
|
||||
* @param string $source A PHP string
|
||||
*
|
||||
* @return string The PHP string with the comments removed
|
||||
*/
|
||||
private static function stripComments($source)
|
||||
{
|
||||
if (!function_exists('token_get_all')) {
|
||||
return $source;
|
||||
}
|
||||
|
||||
$output = '';
|
||||
foreach (token_get_all($source) as $token) {
|
||||
if (is_string($token)) {
|
||||
$output .= $token;
|
||||
} elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
|
||||
$output .= $token[1];
|
||||
}
|
||||
}
|
||||
|
||||
// replace multiple new lines with a single newline
|
||||
$output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an ordered array of passed classes including all their dependencies.
|
||||
*
|
||||
* @param array $classes
|
||||
*
|
||||
* @return array An array of sorted \ReflectionClass instances (dependencies added if needed)
|
||||
* @return \ReflectionClass[] An array of sorted \ReflectionClass instances (dependencies added if needed)
|
||||
*
|
||||
* @throws \InvalidArgumentException When a class can't be loaded
|
||||
*/
|
||||
@@ -278,17 +281,19 @@ class ClassCollectionLoader
|
||||
array_unshift($classes, $parent);
|
||||
}
|
||||
|
||||
$traits = array();
|
||||
|
||||
if (function_exists('get_declared_traits')) {
|
||||
foreach ($classes as $c) {
|
||||
foreach (self::getTraits($c) as $trait) {
|
||||
self::$seen[$trait->getName()] = true;
|
||||
|
||||
array_unshift($classes, $trait);
|
||||
foreach (self::resolveDependencies(self::computeTraitDeps($c), $c) as $trait) {
|
||||
if ($trait !== $c) {
|
||||
$traits[] = $trait;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge(self::getInterfaces($class), $classes);
|
||||
return array_merge(self::getInterfaces($class), $traits, $classes);
|
||||
}
|
||||
|
||||
private static function getInterfaces(\ReflectionClass $class)
|
||||
@@ -308,26 +313,55 @@ class ClassCollectionLoader
|
||||
return $classes;
|
||||
}
|
||||
|
||||
private static function getTraits(\ReflectionClass $class)
|
||||
private static function computeTraitDeps(\ReflectionClass $class)
|
||||
{
|
||||
$traits = $class->getTraits();
|
||||
$classes = array();
|
||||
$deps = array($class->getName() => $traits);
|
||||
while ($trait = array_pop($traits)) {
|
||||
if ($trait->isUserDefined() && !isset(self::$seen[$trait->getName()])) {
|
||||
$classes[] = $trait;
|
||||
|
||||
$traits = array_merge($traits, $trait->getTraits());
|
||||
self::$seen[$trait->getName()] = true;
|
||||
$traitDeps = $trait->getTraits();
|
||||
$deps[$trait->getName()] = $traitDeps;
|
||||
$traits = array_merge($traits, $traitDeps);
|
||||
}
|
||||
}
|
||||
|
||||
return $classes;
|
||||
return $deps;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only useful for testing.
|
||||
* Dependencies resolution.
|
||||
*
|
||||
* This function does not check for circular dependencies as it should never
|
||||
* occur with PHP traits.
|
||||
*
|
||||
* @param array $tree The dependency tree
|
||||
* @param \ReflectionClass $node The node
|
||||
* @param \ArrayObject $resolved An array of already resolved dependencies
|
||||
* @param \ArrayObject $unresolved An array of dependencies to be resolved
|
||||
*
|
||||
* @return \ArrayObject The dependencies for the given node
|
||||
*
|
||||
* @throws \RuntimeException if a circular dependency is detected
|
||||
*/
|
||||
public static function enableTokenizer($bool)
|
||||
private static function resolveDependencies(array $tree, $node, \ArrayObject $resolved = null, \ArrayObject $unresolved = null)
|
||||
{
|
||||
self::$useTokenizer = (Boolean) $bool;
|
||||
if (null === $resolved) {
|
||||
$resolved = new \ArrayObject();
|
||||
}
|
||||
if (null === $unresolved) {
|
||||
$unresolved = new \ArrayObject();
|
||||
}
|
||||
$nodeName = $node->getName();
|
||||
$unresolved[$nodeName] = $node;
|
||||
foreach ($tree[$nodeName] as $dependency) {
|
||||
if (!$resolved->offsetExists($dependency->getName())) {
|
||||
self::resolveDependencies($tree, $dependency, $resolved, $unresolved);
|
||||
}
|
||||
}
|
||||
$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)) {
|
||||
if ($class === strstr($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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class ClassMapGenerator
|
||||
/**
|
||||
* Iterate over all files in the given directory searching for classes
|
||||
*
|
||||
* @param Iterator|string $dir The directory to search in or an iterator
|
||||
* @param \Iterator|string $dir The directory to search in or an iterator
|
||||
*
|
||||
* @return array A class map array
|
||||
*/
|
||||
@@ -121,7 +121,7 @@ class ClassMapGenerator
|
||||
}
|
||||
}
|
||||
|
||||
$classes[] = ltrim($namespace . $class, '\\');
|
||||
$classes[] = ltrim($namespace.$class, '\\');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Symfony\Component\ClassLoader;
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated Deprecated since version 2.4, to be removed in 3.0. Use the DebugClassLoader provided by the Debug component instead.
|
||||
*/
|
||||
class DebugClassLoader
|
||||
{
|
||||
@@ -39,6 +41,16 @@ class DebugClassLoader
|
||||
$this->classFinder = $classFinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wrapped class loader.
|
||||
*
|
||||
* @return object a class loader instance
|
||||
*/
|
||||
public function getClassLoader()
|
||||
{
|
||||
return $this->classFinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all autoloaders implementing a findFile method by a DebugClassLoader wrapper.
|
||||
*/
|
||||
@@ -87,6 +99,8 @@ class DebugClassLoader
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return Boolean|null True, if loaded
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -64,9 +64,6 @@ Resources
|
||||
|
||||
You can run the unit tests with the following command:
|
||||
|
||||
phpunit
|
||||
|
||||
If you also want to run the unit tests that depend on other Symfony
|
||||
Components, install dev dependencies before running PHPUnit:
|
||||
|
||||
php composer.phar install --dev
|
||||
$ cd path/to/Symfony/Component/ClassLoader/
|
||||
$ composer.phar install
|
||||
$ phpunit
|
||||
|
||||
@@ -20,6 +20,35 @@ require_once __DIR__.'/Fixtures/ClassesWithParents/A.php';
|
||||
|
||||
class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testTraitDependencies()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4', '<')) {
|
||||
$this->markTestSkipped('Requires PHP > 5.4');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
require_once __DIR__.'/Fixtures/deps/traits.php';
|
||||
|
||||
$r = new \ReflectionClass('Symfony\Component\ClassLoader\ClassCollectionLoader');
|
||||
$m = $r->getMethod('getOrderedClasses');
|
||||
$m->setAccessible(true);
|
||||
|
||||
$ordered = $m->invoke('Symfony\Component\ClassLoader\ClassCollectionLoader', array('CTFoo'));
|
||||
|
||||
$this->assertEquals(
|
||||
array('TD', 'TC', 'TB', 'TA', 'TZ', 'CTFoo'),
|
||||
array_map(function ($class) { return $class->getName(); }, $ordered)
|
||||
);
|
||||
|
||||
$ordered = $m->invoke('Symfony\Component\ClassLoader\ClassCollectionLoader', array('CTBar'));
|
||||
|
||||
$this->assertEquals(
|
||||
array('TD', 'TZ', 'TC', 'TB', 'TA', 'CTBar'),
|
||||
array_map(function ($class) { return $class->getName(); }, $ordered)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getDifferentOrders
|
||||
*/
|
||||
@@ -71,8 +100,8 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testClassWithTraitsReordering(array $classes)
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '<')) {
|
||||
$this->markTestSkipped('Requires PHP > 5.4.0.');
|
||||
if (version_compare(phpversion(), '5.4', '<')) {
|
||||
$this->markTestSkipped('Requires PHP > 5.4');
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -86,9 +115,9 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$expected = array(
|
||||
'ClassesWithParents\\GInterface',
|
||||
'ClassesWithParents\\CInterface',
|
||||
'ClassesWithParents\\CTrait',
|
||||
'ClassesWithParents\\ATrait',
|
||||
'ClassesWithParents\\BTrait',
|
||||
'ClassesWithParents\\CTrait',
|
||||
'ClassesWithParents\\B',
|
||||
'ClassesWithParents\\A',
|
||||
'ClassesWithParents\\D',
|
||||
@@ -125,8 +154,20 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('<?php '.$expected, ClassCollectionLoader::fixNamespaceDeclarations('<?php '.$source));
|
||||
}
|
||||
|
||||
public function getFixNamespaceDeclarationsData()
|
||||
{
|
||||
return array(
|
||||
array("namespace;\nclass Foo {}\n", "namespace\n{\nclass Foo {}\n}"),
|
||||
array("namespace Foo;\nclass Foo {}\n", "namespace Foo\n{\nclass Foo {}\n}"),
|
||||
array("namespace Bar ;\nclass Foo {}\n", "namespace Bar\n{\nclass Foo {}\n}"),
|
||||
array("namespace Foo\Bar;\nclass Foo {}\n", "namespace Foo\Bar\n{\nclass Foo {}\n}"),
|
||||
array("namespace Foo\Bar\Bar\n{\nclass Foo {}\n}\n", "namespace Foo\Bar\Bar\n{\nclass Foo {}\n}"),
|
||||
array("namespace\n{\nclass Foo {}\n}\n", "namespace\n{\nclass Foo {}\n}"),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getFixNamespaceDeclarationsData
|
||||
* @dataProvider getFixNamespaceDeclarationsDataWithoutTokenizer
|
||||
*/
|
||||
public function testFixNamespaceDeclarationsWithoutTokenizer($source, $expected)
|
||||
{
|
||||
@@ -135,7 +176,7 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
ClassCollectionLoader::enableTokenizer(true);
|
||||
}
|
||||
|
||||
public function getFixNamespaceDeclarationsData()
|
||||
public function getFixNamespaceDeclarationsDataWithoutTokenizer()
|
||||
{
|
||||
return array(
|
||||
array("namespace;\nclass Foo {}\n", "namespace\n{\nclass Foo {}\n}\n"),
|
||||
@@ -148,16 +189,72 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testUnableToLoadClassException()
|
||||
{
|
||||
ClassCollectionLoader::load(array('SomeNotExistingClass'), '', 'foo', false);
|
||||
if (is_file($file = sys_get_temp_dir().'/foo.php')) {
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
ClassCollectionLoader::load(array('SomeNotExistingClass'), sys_get_temp_dir(), 'foo', false);
|
||||
}
|
||||
|
||||
public function testLoadTwiceClass()
|
||||
public function testCommentStripping()
|
||||
{
|
||||
ClassCollectionLoader::load(array('Foo'), '', 'foo', false);
|
||||
ClassCollectionLoader::load(array('Foo'), '', 'foo', false);
|
||||
if (is_file($file = sys_get_temp_dir().'/bar.php')) {
|
||||
unlink($file);
|
||||
}
|
||||
spl_autoload_register($r = function ($class) {
|
||||
if (0 === strpos($class, 'Namespaced') || 0 === strpos($class, 'Pearlike_')) {
|
||||
require_once __DIR__.'/Fixtures/'.str_replace(array('\\', '_'), '/', $class).'.php';
|
||||
}
|
||||
});
|
||||
|
||||
ClassCollectionLoader::load(
|
||||
array('Namespaced\\WithComments', 'Pearlike_WithComments'),
|
||||
sys_get_temp_dir(),
|
||||
'bar',
|
||||
false
|
||||
);
|
||||
|
||||
spl_autoload_unregister($r);
|
||||
|
||||
$this->assertEquals(<<<EOF
|
||||
namespace Namespaced
|
||||
{
|
||||
class WithComments
|
||||
{
|
||||
public static \$loaded = true;
|
||||
}
|
||||
\$string ='string shoult not be modified {\$string}';
|
||||
\$heredoc = (<<<HD
|
||||
|
||||
|
||||
Heredoc should not be modified {\$string}
|
||||
|
||||
|
||||
HD
|
||||
);
|
||||
\$nowdoc =<<<'ND'
|
||||
|
||||
|
||||
Nowdoc should not be modified {\$string}
|
||||
|
||||
|
||||
ND
|
||||
;
|
||||
}
|
||||
namespace
|
||||
{
|
||||
class Pearlike_WithComments
|
||||
{
|
||||
public static \$loaded = true;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
, str_replace("<?php \n", '', file_get_contents($file)));
|
||||
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -74,7 +72,7 @@ class ClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
public function getLoadNonexistentClassTests()
|
||||
{
|
||||
return array(
|
||||
array('\\Pearlike3_Bar', '\\Pearlike3_Bar', '->loadClass() loads non exising Pearlike3_Bar class with a leading slash'),
|
||||
array('\\Pearlike3_Bar', '\\Pearlike3_Bar', '->loadClass() loads non existing Pearlike3_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'));
|
||||
|
||||
|
||||
@@ -72,9 +72,10 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$data = array(
|
||||
array(__DIR__.'/Fixtures/Namespaced', array(
|
||||
'Namespaced\\Bar' => realpath(__DIR__).'/Fixtures/Namespaced/Bar.php',
|
||||
'Namespaced\\Foo' => realpath(__DIR__).'/Fixtures/Namespaced/Foo.php',
|
||||
'Namespaced\\Baz' => realpath(__DIR__).'/Fixtures/Namespaced/Baz.php',
|
||||
'Namespaced\\Bar' => realpath(__DIR__).'/Fixtures/Namespaced/Bar.php',
|
||||
'Namespaced\\Foo' => realpath(__DIR__).'/Fixtures/Namespaced/Foo.php',
|
||||
'Namespaced\\Baz' => realpath(__DIR__).'/Fixtures/Namespaced/Baz.php',
|
||||
'Namespaced\\WithComments' => realpath(__DIR__).'/Fixtures/Namespaced/WithComments.php',
|
||||
)
|
||||
),
|
||||
array(__DIR__.'/Fixtures/beta/NamespaceCollision', array(
|
||||
@@ -84,9 +85,10 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
'NamespaceCollision\\C\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/C/B/Foo.php',
|
||||
)),
|
||||
array(__DIR__.'/Fixtures/Pearlike', array(
|
||||
'Pearlike_Foo' => realpath(__DIR__).'/Fixtures/Pearlike/Foo.php',
|
||||
'Pearlike_Bar' => realpath(__DIR__).'/Fixtures/Pearlike/Bar.php',
|
||||
'Pearlike_Baz' => realpath(__DIR__).'/Fixtures/Pearlike/Baz.php',
|
||||
'Pearlike_Foo' => realpath(__DIR__).'/Fixtures/Pearlike/Foo.php',
|
||||
'Pearlike_Bar' => realpath(__DIR__).'/Fixtures/Pearlike/Bar.php',
|
||||
'Pearlike_Baz' => realpath(__DIR__).'/Fixtures/Pearlike/Baz.php',
|
||||
'Pearlike_WithComments' => realpath(__DIR__).'/Fixtures/Pearlike/WithComments.php',
|
||||
)),
|
||||
array(__DIR__.'/Fixtures/classmap', array(
|
||||
'Foo\\Bar\\A' => realpath(__DIR__).'/Fixtures/classmap/sameNsMultipleClasses.php',
|
||||
@@ -118,12 +120,8 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testCreateMapFinderSupport()
|
||||
{
|
||||
if (!class_exists('Symfony\\Component\\Finder\\Finder')) {
|
||||
$this->markTestSkipped('Finder component is not available');
|
||||
}
|
||||
|
||||
$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',
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
||||
37
Tests/Fixtures/Namespaced/WithComments.php
Normal file
37
Tests/Fixtures/Namespaced/WithComments.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?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 Namespaced;
|
||||
|
||||
class WithComments
|
||||
{
|
||||
/** @Boolean */
|
||||
public static $loaded = true;
|
||||
}
|
||||
|
||||
$string = 'string shoult not be modified {$string}';
|
||||
|
||||
$heredoc = (<<<HD
|
||||
|
||||
|
||||
Heredoc should not be modified {$string}
|
||||
|
||||
|
||||
HD
|
||||
);
|
||||
|
||||
$nowdoc = <<<'ND'
|
||||
|
||||
|
||||
Nowdoc should not be modified {$string}
|
||||
|
||||
|
||||
ND;
|
||||
16
Tests/Fixtures/Pearlike/WithComments.php
Normal file
16
Tests/Fixtures/Pearlike/WithComments.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?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.
|
||||
*/
|
||||
|
||||
class Pearlike_WithComments
|
||||
{
|
||||
/** @Boolean */
|
||||
public static $loaded = true;
|
||||
}
|
||||
36
Tests/Fixtures/deps/traits.php
Normal file
36
Tests/Fixtures/deps/traits.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
trait TD
|
||||
{}
|
||||
|
||||
trait TZ
|
||||
{
|
||||
use TD;
|
||||
}
|
||||
|
||||
trait TC
|
||||
{
|
||||
use TD;
|
||||
}
|
||||
|
||||
trait TB
|
||||
{
|
||||
use TC;
|
||||
}
|
||||
|
||||
trait TA
|
||||
{
|
||||
use TB;
|
||||
}
|
||||
|
||||
class CTFoo
|
||||
{
|
||||
use TA;
|
||||
use TZ;
|
||||
}
|
||||
|
||||
class CTBar
|
||||
{
|
||||
use TZ;
|
||||
use TA;
|
||||
}
|
||||
@@ -23,7 +23,7 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->loadClass($testClassName);
|
||||
$this->assertTrue($loader->loadClass($testClassName));
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
@@ -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'));
|
||||
|
||||
@@ -92,7 +90,7 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerNamespaceFallbacks(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'));
|
||||
$loader->registerPrefixFallbacks(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'));
|
||||
$loader->loadClass($testClassName);
|
||||
$this->assertTrue($loader->loadClass($testClassName));
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
@@ -128,7 +126,7 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerNamespaces($namespaces);
|
||||
|
||||
$loader->loadClass($className);
|
||||
$this->assertTrue($loader->loadClass($className));
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
@@ -178,7 +176,7 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerPrefixes($prefixes);
|
||||
|
||||
$loader->loadClass($className);
|
||||
$this->assertTrue($loader->loadClass($className));
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?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.
|
||||
*/
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\ClassLoader')) {
|
||||
if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\ClassLoader')).'.php')) {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (file_exists($loader = __DIR__.'/../vendor/autoload.php')) {
|
||||
require_once $loader;
|
||||
}
|
||||
@@ -242,11 +242,15 @@ class UniversalClassLoader
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,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);
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,9 @@ class XcacheClassLoader
|
||||
* @param string $prefix A prefix to create a namespace in Xcache
|
||||
* @param object $classFinder An object that implements findFile() method.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($prefix, $classFinder)
|
||||
|
||||
@@ -20,11 +20,15 @@
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/finder": "2.1.*"
|
||||
"symfony/finder": "~2.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Symfony\\Component\\ClassLoader": "" }
|
||||
"psr-0": { "Symfony\\Component\\ClassLoader\\": "" }
|
||||
},
|
||||
"target-dir": "Symfony/Component/ClassLoader",
|
||||
"minimum-stability": "dev"
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false"
|
||||
bootstrap="Tests/bootstrap.php"
|
||||
bootstrap="vendor/autoload.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Symfony ClassLoader Component Test Suite">
|
||||
|
||||
Reference in New Issue
Block a user