mirror of
https://github.com/symfony/class-loader.git
synced 2026-03-24 09:12:18 +01:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb2590d94c | ||
|
|
5d77753a96 | ||
|
|
f4278d53d1 | ||
|
|
9ae87e8c34 | ||
|
|
f8843095b2 | ||
|
|
2c4235602f | ||
|
|
8bfdaa2e7a | ||
|
|
fdb4806d2e | ||
|
|
b6e2bb88a8 | ||
|
|
64d2af707a | ||
|
|
44816c55e9 | ||
|
|
1108382429 | ||
|
|
2e19afbcc7 | ||
|
|
65ac4dbf59 | ||
|
|
c060834942 | ||
|
|
886fe1940b | ||
|
|
8ec0c38b8d | ||
|
|
df77b1499c |
@@ -16,8 +16,8 @@ namespace Symfony\Component\ClassLoader;
|
||||
*
|
||||
* It expects an object implementing a findFile method to find the file. This
|
||||
* allows using it as a wrapper around the other loaders of the component (the
|
||||
* ClassLoader for instance) but also around any other autoloaders following
|
||||
* this convention (the Composer one for instance).
|
||||
* ClassLoader and the UniversalClassLoader for instance) but also around any
|
||||
* other autoloaders following this convention (the Composer one for instance).
|
||||
*
|
||||
* // with a Symfony autoloader
|
||||
* use Symfony\Component\ClassLoader\ClassLoader;
|
||||
@@ -57,8 +57,6 @@ class ApcClassLoader
|
||||
protected $decorated;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $prefix The APC namespace prefix to use
|
||||
* @param object $decorated A class loader object that implements the findFile() method
|
||||
*
|
||||
|
||||
101
ApcUniversalClassLoader.php
Normal file
101
ApcUniversalClassLoader.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?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;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\ApcUniversalClassLoader class is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Component\ClassLoader\ApcClassLoader class instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* ApcUniversalClassLoader implements a "universal" autoloader cached in APC for PHP 5.3.
|
||||
*
|
||||
* It is able to load classes that use either:
|
||||
*
|
||||
* * The technical interoperability standards for PHP 5.3 namespaces and
|
||||
* class names (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md);
|
||||
*
|
||||
* * The PEAR naming convention for classes (http://pear.php.net/).
|
||||
*
|
||||
* Classes from a sub-namespace or a sub-hierarchy of PEAR classes can be
|
||||
* looked for in a list of locations to ease the vendoring of a sub-set of
|
||||
* classes for large projects.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* require 'vendor/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
|
||||
* require 'vendor/symfony/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php';
|
||||
*
|
||||
* use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
|
||||
*
|
||||
* $loader = new ApcUniversalClassLoader('apc.prefix.');
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->registerNamespaces(array(
|
||||
* 'Symfony\Component' => __DIR__.'/component',
|
||||
* 'Symfony' => __DIR__.'/framework',
|
||||
* 'Sensio' => array(__DIR__.'/src', __DIR__.'/vendor'),
|
||||
* ));
|
||||
*
|
||||
* // register a library using the PEAR naming convention
|
||||
* $loader->registerPrefixes(array(
|
||||
* 'Swift_' => __DIR__.'/Swift',
|
||||
* ));
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*
|
||||
* @deprecated since version 2.4, to be removed in 3.0.
|
||||
* Use the {@link ClassLoader} class instead.
|
||||
*/
|
||||
class ApcUniversalClassLoader extends UniversalClassLoader
|
||||
{
|
||||
private $prefix;
|
||||
|
||||
/**
|
||||
* @param string $prefix A prefix to create a namespace in APC
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($prefix)
|
||||
{
|
||||
if (!function_exists('apcu_fetch')) {
|
||||
throw new \RuntimeException('Unable to use ApcUniversalClassLoader as APC is not enabled.');
|
||||
}
|
||||
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a file by class name while caching lookups to APC.
|
||||
*
|
||||
* @param string $class A class name to resolve to file
|
||||
*
|
||||
* @return string|null The path, if found
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
$file = apcu_fetch($this->prefix.$class, $success);
|
||||
|
||||
if (!$success) {
|
||||
apcu_store($this->prefix.$class, $file = parent::findFile($class) ?: null);
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,6 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
3.0.0
|
||||
-----
|
||||
|
||||
* The DebugClassLoader class has been removed
|
||||
* The DebugUniversalClassLoader class has been removed
|
||||
* The UniversalClassLoader class has been removed
|
||||
* The ApcUniversalClassLoader class has been removed
|
||||
|
||||
2.4.0
|
||||
-----
|
||||
|
||||
|
||||
@@ -44,7 +44,10 @@ class ClassCollectionLoader
|
||||
self::$loaded[$name] = true;
|
||||
|
||||
if ($adaptive) {
|
||||
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
|
||||
$declared = array_merge(get_declared_classes(), get_declared_interfaces());
|
||||
if (function_exists('get_declared_traits')) {
|
||||
$declared = array_merge($declared, get_declared_traits());
|
||||
}
|
||||
|
||||
// don't include already declared classes
|
||||
$classes = array_diff($classes, $declared);
|
||||
@@ -55,6 +58,11 @@ class ClassCollectionLoader
|
||||
|
||||
$classes = array_unique($classes);
|
||||
|
||||
// cache the core classes
|
||||
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));
|
||||
}
|
||||
$cacheDir = rtrim(realpath($cacheDir) ?: $cacheDir, '/'.DIRECTORY_SEPARATOR);
|
||||
$cache = $cacheDir.'/'.$name.$extension;
|
||||
|
||||
// auto-reload
|
||||
@@ -90,9 +98,23 @@ class ClassCollectionLoader
|
||||
return;
|
||||
}
|
||||
if (!$adaptive) {
|
||||
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
|
||||
$declared = array_merge(get_declared_classes(), get_declared_interfaces());
|
||||
if (function_exists('get_declared_traits')) {
|
||||
$declared = array_merge($declared, get_declared_traits());
|
||||
}
|
||||
}
|
||||
|
||||
$spacesRegex = '(?:\s*+(?:(?:\#|//)[^\n]*+\n|/\*(?:(?<!\*/).)++)?+)*+';
|
||||
$dontInlineRegex = <<<REGEX
|
||||
'(?:
|
||||
^<\?php\s.declare.\(.strict_types.=.1.\).;
|
||||
| \b__halt_compiler.\(.\)
|
||||
| \b__(?:DIR|FILE)__\b
|
||||
)'isx
|
||||
REGEX;
|
||||
$dontInlineRegex = str_replace('.', $spacesRegex, $dontInlineRegex);
|
||||
|
||||
$cacheDir = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $cacheDir));
|
||||
$files = array();
|
||||
$content = '';
|
||||
foreach (self::getOrderedClasses($classes) as $class) {
|
||||
@@ -100,25 +122,40 @@ class ClassCollectionLoader
|
||||
continue;
|
||||
}
|
||||
|
||||
$files[] = $class->getFileName();
|
||||
$files[] = $file = $class->getFileName();
|
||||
$c = file_get_contents($file);
|
||||
|
||||
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($class->getFileName()));
|
||||
if (preg_match($dontInlineRegex, $c)) {
|
||||
$file = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $file));
|
||||
|
||||
// fakes namespace declaration for global code
|
||||
if (!$class->inNamespace()) {
|
||||
$c = "\nnamespace\n{\n".$c."\n}\n";
|
||||
for ($i = 0; isset($file[$i], $cacheDir[$i]); ++$i) {
|
||||
if ($file[$i] !== $cacheDir[$i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (1 >= $i) {
|
||||
$file = var_export(implode('/', $file), true);
|
||||
} else {
|
||||
$file = array_slice($file, $i);
|
||||
$file = str_repeat('../', count($cacheDir) - $i).implode('/', $file);
|
||||
$file = '__DIR__.'.var_export('/'.$file, true);
|
||||
}
|
||||
|
||||
$c = "\nnamespace {require $file;}";
|
||||
} else {
|
||||
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', $c);
|
||||
|
||||
// fakes namespace declaration for global code
|
||||
if (!$class->inNamespace()) {
|
||||
$c = "\nnamespace\n{\n".$c."\n}\n";
|
||||
}
|
||||
|
||||
$c = self::fixNamespaceDeclarations('<?php '.$c);
|
||||
$c = preg_replace('/^\s*<\?php/', '', $c);
|
||||
}
|
||||
|
||||
$c = self::fixNamespaceDeclarations('<?php '.$c);
|
||||
$c = preg_replace('/^\s*<\?php/', '', $c);
|
||||
|
||||
$content .= $c;
|
||||
}
|
||||
|
||||
// cache the core classes
|
||||
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, '<?php '.$content);
|
||||
|
||||
if ($autoReload) {
|
||||
@@ -178,7 +215,7 @@ class ClassCollectionLoader
|
||||
do {
|
||||
$token = $tokens[++$i];
|
||||
$output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token;
|
||||
} while ($token[0] !== T_END_HEREDOC);
|
||||
} while (T_END_HEREDOC !== $token[0]);
|
||||
$output .= "\n";
|
||||
$rawChunk = '';
|
||||
} elseif (T_CONSTANT_ENCAPSED_STRING === $token[0]) {
|
||||
@@ -195,7 +232,7 @@ class ClassCollectionLoader
|
||||
|
||||
$output .= self::compressCode($rawChunk);
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
|
||||
unset($tokens, $rawChunk);
|
||||
gc_mem_caches();
|
||||
@@ -238,7 +275,13 @@ class ClassCollectionLoader
|
||||
*/
|
||||
private static function writeCacheFile($file, $content)
|
||||
{
|
||||
$tmpFile = tempnam(dirname($file), basename($file));
|
||||
$dir = dirname($file);
|
||||
if (!is_writable($dir)) {
|
||||
throw new \RuntimeException(sprintf('Cache directory "%s" is not writable.', $dir));
|
||||
}
|
||||
|
||||
$tmpFile = tempnam($dir, basename($file));
|
||||
|
||||
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
|
||||
@chmod($file, 0666 & ~umask());
|
||||
|
||||
@@ -251,8 +294,6 @@ class ClassCollectionLoader
|
||||
/**
|
||||
* Gets an ordered array of passed classes including all their dependencies.
|
||||
*
|
||||
* @param array $classes
|
||||
*
|
||||
* @return \ReflectionClass[] An array of sorted \ReflectionClass instances (dependencies added if needed)
|
||||
*
|
||||
* @throws \InvalidArgumentException When a class can't be loaded
|
||||
@@ -292,10 +333,12 @@ class ClassCollectionLoader
|
||||
|
||||
$traits = array();
|
||||
|
||||
foreach ($classes as $c) {
|
||||
foreach (self::resolveDependencies(self::computeTraitDeps($c), $c) as $trait) {
|
||||
if ($trait !== $c) {
|
||||
$traits[] = $trait;
|
||||
if (method_exists('ReflectionClass', 'getTraits')) {
|
||||
foreach ($classes as $c) {
|
||||
foreach (self::resolveDependencies(self::computeTraitDeps($c), $c) as $trait) {
|
||||
if ($trait !== $c) {
|
||||
$traits[] = $trait;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\ClassLoader;
|
||||
|
||||
if (!defined('SYMFONY_TRAIT')) {
|
||||
if (\PHP_VERSION_ID >= 50400) {
|
||||
define('SYMFONY_TRAIT', T_TRAIT);
|
||||
} else {
|
||||
define('SYMFONY_TRAIT', 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ClassMapGenerator.
|
||||
*
|
||||
@@ -56,15 +64,15 @@ class ClassMapGenerator
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = $file->getRealPath();
|
||||
$path = $file->getRealPath() ?: $file->getPathname();
|
||||
|
||||
if (pathinfo($path, PATHINFO_EXTENSION) !== 'php') {
|
||||
if ('php' !== pathinfo($path, PATHINFO_EXTENSION)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$classes = self::findClasses($path);
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
|
||||
gc_mem_caches();
|
||||
}
|
||||
@@ -114,7 +122,7 @@ class ClassMapGenerator
|
||||
break;
|
||||
case T_CLASS:
|
||||
case T_INTERFACE:
|
||||
case T_TRAIT:
|
||||
case SYMFONY_TRAIT:
|
||||
// Skip usage of ::class constant
|
||||
$isClassConstant = false;
|
||||
for ($j = $i - 1; $j > 0; --$j) {
|
||||
|
||||
118
DebugClassLoader.php
Normal file
118
DebugClassLoader.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?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;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\DebugClassLoader class is deprecated since version 2.4 and will be removed in 3.0. Use the Symfony\Component\Debug\DebugClassLoader class instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Autoloader checking if the class is really defined in the file found.
|
||||
*
|
||||
* The DebugClassLoader will wrap all registered autoloaders providing a
|
||||
* findFile method and will throw an exception if a file is found but does
|
||||
* not declare the class.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*
|
||||
* @deprecated since version 2.4, to be removed in 3.0.
|
||||
* Use {@link \Symfony\Component\Debug\DebugClassLoader} instead.
|
||||
*/
|
||||
class DebugClassLoader
|
||||
{
|
||||
private $classFinder;
|
||||
|
||||
/**
|
||||
* @param object $classFinder
|
||||
*/
|
||||
public function __construct($classFinder)
|
||||
{
|
||||
$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.
|
||||
*/
|
||||
public static function enable()
|
||||
{
|
||||
if (!is_array($functions = spl_autoload_functions())) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($functions as $function) {
|
||||
spl_autoload_unregister($function);
|
||||
}
|
||||
|
||||
foreach ($functions as $function) {
|
||||
if (is_array($function) && !$function[0] instanceof self && method_exists($function[0], 'findFile')) {
|
||||
$function = array(new static($function[0]), 'loadClass');
|
||||
}
|
||||
|
||||
spl_autoload_register($function);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a file by class name.
|
||||
*
|
||||
* @param string $class A class name to resolve to file
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
return $this->classFinder->findFile($class) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return bool|null True, if loaded
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->classFinder->findFile($class)) {
|
||||
require $file;
|
||||
|
||||
if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) {
|
||||
if (false !== strpos($class, '/')) {
|
||||
throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
68
DebugUniversalClassLoader.php
Normal file
68
DebugUniversalClassLoader.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?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;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\DebugUniversalClassLoader class is deprecated since version 2.4 and will be removed in 3.0. Use the Symfony\Component\Debug\DebugClassLoader class instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Checks that the class is actually declared in the included file.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated since version 2.4, to be removed in 3.0.
|
||||
* Use the {@link \Symfony\Component\Debug\DebugClassLoader} class instead.
|
||||
*/
|
||||
class DebugUniversalClassLoader extends UniversalClassLoader
|
||||
{
|
||||
/**
|
||||
* Replaces all regular UniversalClassLoader instances by a DebugUniversalClassLoader ones.
|
||||
*/
|
||||
public static function enable()
|
||||
{
|
||||
if (!is_array($functions = spl_autoload_functions())) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($functions as $function) {
|
||||
spl_autoload_unregister($function);
|
||||
}
|
||||
|
||||
foreach ($functions as $function) {
|
||||
if (is_array($function) && $function[0] instanceof UniversalClassLoader) {
|
||||
$loader = new static();
|
||||
$loader->registerNamespaceFallbacks($function[0]->getNamespaceFallbacks());
|
||||
$loader->registerPrefixFallbacks($function[0]->getPrefixFallbacks());
|
||||
$loader->registerNamespaces($function[0]->getNamespaces());
|
||||
$loader->registerPrefixes($function[0]->getPrefixes());
|
||||
$loader->useIncludePath($function[0]->getUseIncludePath());
|
||||
|
||||
$function[0] = $loader;
|
||||
}
|
||||
|
||||
spl_autoload_register($function);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
require $file;
|
||||
|
||||
if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) {
|
||||
throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2004-2016 Fabien Potencier
|
||||
Copyright (c) 2004-2017 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -21,8 +21,6 @@ class MapClassLoader
|
||||
private $map = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $map A map where keys are classes and values the absolute file path
|
||||
*/
|
||||
public function __construct(array $map)
|
||||
|
||||
@@ -20,9 +20,6 @@ namespace Symfony\Component\ClassLoader;
|
||||
*/
|
||||
class Psr4ClassLoader
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $prefixes = array();
|
||||
|
||||
/**
|
||||
@@ -45,7 +42,8 @@ class Psr4ClassLoader
|
||||
{
|
||||
$class = ltrim($class, '\\');
|
||||
|
||||
foreach ($this->prefixes as list($currentPrefix, $currentBaseDir)) {
|
||||
foreach ($this->prefixes as $current) {
|
||||
list($currentPrefix, $currentBaseDir) = $current;
|
||||
if (0 === strpos($class, $currentPrefix)) {
|
||||
$classWithoutPrefix = substr($class, strlen($currentPrefix));
|
||||
$file = $currentBaseDir.str_replace('\\', DIRECTORY_SEPARATOR, $classWithoutPrefix).'.php';
|
||||
|
||||
@@ -11,10 +11,11 @@
|
||||
|
||||
namespace Symfony\Component\ClassLoader\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\ClassLoader\ApcClassLoader;
|
||||
use Symfony\Component\ClassLoader\ClassLoader;
|
||||
|
||||
class ApcClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
class ApcClassLoaderTest extends TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\ClassLoader\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\ClassLoader\ClassCollectionLoader;
|
||||
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/GInterface.php';
|
||||
@@ -18,8 +19,11 @@ require_once __DIR__.'/Fixtures/ClassesWithParents/CInterface.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/B.php';
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/A.php';
|
||||
|
||||
class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
class ClassCollectionLoaderTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @requires PHP 5.4
|
||||
*/
|
||||
public function testTraitDependencies()
|
||||
{
|
||||
require_once __DIR__.'/Fixtures/deps/traits.php';
|
||||
@@ -28,14 +32,14 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$m = $r->getMethod('getOrderedClasses');
|
||||
$m->setAccessible(true);
|
||||
|
||||
$ordered = $m->invoke('Symfony\Component\ClassLoader\ClassCollectionLoader', array('CTFoo'));
|
||||
$ordered = $m->invoke(null, 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'));
|
||||
$ordered = $m->invoke(null, array('CTBar'));
|
||||
|
||||
$this->assertEquals(
|
||||
array('TD', 'TZ', 'TC', 'TB', 'TA', 'CTBar'),
|
||||
@@ -59,7 +63,7 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$m = $r->getMethod('getOrderedClasses');
|
||||
$m->setAccessible(true);
|
||||
|
||||
$ordered = $m->invoke('Symfony\Component\ClassLoader\ClassCollectionLoader', $classes);
|
||||
$ordered = $m->invoke(null, $classes);
|
||||
|
||||
$this->assertEquals($expected, array_map(function ($class) { return $class->getName(); }, $ordered));
|
||||
}
|
||||
@@ -91,6 +95,7 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @dataProvider getDifferentOrdersForTraits
|
||||
* @requires PHP 5.4
|
||||
*/
|
||||
public function testClassWithTraitsReordering(array $classes)
|
||||
{
|
||||
@@ -116,7 +121,7 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$m = $r->getMethod('getOrderedClasses');
|
||||
$m->setAccessible(true);
|
||||
|
||||
$ordered = $m->invoke('Symfony\Component\ClassLoader\ClassCollectionLoader', $classes);
|
||||
$ordered = $m->invoke(null, $classes);
|
||||
|
||||
$this->assertEquals($expected, array_map(function ($class) { return $class->getName(); }, $ordered));
|
||||
}
|
||||
@@ -134,6 +139,9 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 5.4
|
||||
*/
|
||||
public function testFixClassWithTraitsOrdering()
|
||||
{
|
||||
require_once __DIR__.'/Fixtures/ClassesWithParents/CTrait.php';
|
||||
@@ -155,7 +163,7 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$m = $r->getMethod('getOrderedClasses');
|
||||
$m->setAccessible(true);
|
||||
|
||||
$ordered = $m->invoke('Symfony\Component\ClassLoader\ClassCollectionLoader', $classes);
|
||||
$ordered = $m->invoke(null, $classes);
|
||||
|
||||
$this->assertEquals($expected, array_map(function ($class) { return $class->getName(); }, $ordered));
|
||||
}
|
||||
@@ -216,18 +224,20 @@ class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testCommentStripping()
|
||||
{
|
||||
if (is_file($file = sys_get_temp_dir().'/bar.php')) {
|
||||
if (is_file($file = __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';
|
||||
@require_once __DIR__.'/Fixtures/'.str_replace(array('\\', '_'), '/', $class).'.php';
|
||||
}
|
||||
});
|
||||
|
||||
$strictTypes = defined('HHVM_VERSION') ? '' : "\nnamespace {require __DIR__.'/Fixtures/Namespaced/WithStrictTypes.php';}";
|
||||
|
||||
ClassCollectionLoader::load(
|
||||
array('Namespaced\\WithComments', 'Pearlike_WithComments'),
|
||||
sys_get_temp_dir(),
|
||||
array('Namespaced\\WithComments', 'Pearlike_WithComments', 'Namespaced\\WithDirMagic', 'Namespaced\\WithFileMagic', 'Namespaced\\WithHaltCompiler', $strictTypes ? 'Namespaced\\WithStrictTypes' : 'Namespaced\\WithComments'),
|
||||
__DIR__,
|
||||
'bar',
|
||||
false
|
||||
);
|
||||
@@ -266,8 +276,13 @@ class Pearlike_WithComments
|
||||
public static $loaded = true;
|
||||
}
|
||||
}
|
||||
namespace {require __DIR__.'/Fixtures/Namespaced/WithDirMagic.php';}
|
||||
namespace {require __DIR__.'/Fixtures/Namespaced/WithFileMagic.php';}
|
||||
namespace {require __DIR__.'/Fixtures/Namespaced/WithHaltCompiler.php';}
|
||||
EOF
|
||||
, str_replace("<?php \n", '', file_get_contents($file)));
|
||||
.$strictTypes,
|
||||
str_replace(array("<?php \n", '\\\\'), array('', '/'), file_get_contents($file))
|
||||
);
|
||||
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
|
||||
namespace Symfony\Component\ClassLoader\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\ClassLoader\ClassLoader;
|
||||
|
||||
class ClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
class ClassLoaderTest extends TestCase
|
||||
{
|
||||
public function testGetPrefixes()
|
||||
{
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
|
||||
namespace Symfony\Component\ClassLoader\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\ClassLoader\ClassMapGenerator;
|
||||
|
||||
class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
class ClassMapGeneratorTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
@@ -76,8 +77,11 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
'Namespaced\\Foo' => realpath(__DIR__).'/Fixtures/Namespaced/Foo.php',
|
||||
'Namespaced\\Baz' => realpath(__DIR__).'/Fixtures/Namespaced/Baz.php',
|
||||
'Namespaced\\WithComments' => realpath(__DIR__).'/Fixtures/Namespaced/WithComments.php',
|
||||
),
|
||||
),
|
||||
'Namespaced\\WithStrictTypes' => realpath(__DIR__).'/Fixtures/Namespaced/WithStrictTypes.php',
|
||||
'Namespaced\\WithHaltCompiler' => realpath(__DIR__).'/Fixtures/Namespaced/WithHaltCompiler.php',
|
||||
'Namespaced\\WithDirMagic' => realpath(__DIR__).'/Fixtures/Namespaced/WithDirMagic.php',
|
||||
'Namespaced\\WithFileMagic' => realpath(__DIR__).'/Fixtures/Namespaced/WithFileMagic.php',
|
||||
)),
|
||||
array(__DIR__.'/Fixtures/beta/NamespaceCollision', array(
|
||||
'NamespaceCollision\\A\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Bar.php',
|
||||
'NamespaceCollision\\A\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Foo.php',
|
||||
@@ -102,18 +106,24 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||
'ClassMap\\SomeParent' => realpath(__DIR__).'/Fixtures/classmap/SomeParent.php',
|
||||
'ClassMap\\SomeClass' => realpath(__DIR__).'/Fixtures/classmap/SomeClass.php',
|
||||
)),
|
||||
array(__DIR__.'/Fixtures/php5.4', array(
|
||||
);
|
||||
|
||||
if (\PHP_VERSION_ID >= 50400) {
|
||||
$data[] = array(__DIR__.'/Fixtures/php5.4', array(
|
||||
'TFoo' => __DIR__.'/Fixtures/php5.4/traits.php',
|
||||
'CFoo' => __DIR__.'/Fixtures/php5.4/traits.php',
|
||||
'Foo\\TBar' => __DIR__.'/Fixtures/php5.4/traits.php',
|
||||
'Foo\\IBar' => __DIR__.'/Fixtures/php5.4/traits.php',
|
||||
'Foo\\TFooBar' => __DIR__.'/Fixtures/php5.4/traits.php',
|
||||
'Foo\\CBar' => __DIR__.'/Fixtures/php5.4/traits.php',
|
||||
)),
|
||||
array(__DIR__.'/Fixtures/php5.5', array(
|
||||
));
|
||||
}
|
||||
|
||||
if (\PHP_VERSION_ID >= 50500) {
|
||||
$data[] = array(__DIR__.'/Fixtures/php5.5', array(
|
||||
'ClassCons\\Foo' => __DIR__.'/Fixtures/php5.5/class_cons.php',
|
||||
)),
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
17
Tests/Fixtures/LegacyApc/Namespaced/Bar.php
Normal file
17
Tests/Fixtures/LegacyApc/Namespaced/Bar.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?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 LegacyApc\Namespaced;
|
||||
|
||||
class Bar
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
17
Tests/Fixtures/LegacyApc/Namespaced/Baz.php
Normal file
17
Tests/Fixtures/LegacyApc/Namespaced/Baz.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?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 LegacyApc\Namespaced;
|
||||
|
||||
class Baz
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
17
Tests/Fixtures/LegacyApc/Namespaced/Foo.php
Normal file
17
Tests/Fixtures/LegacyApc/Namespaced/Foo.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?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 LegacyApc\Namespaced;
|
||||
|
||||
class Foo
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
17
Tests/Fixtures/LegacyApc/Namespaced/FooBar.php
Normal file
17
Tests/Fixtures/LegacyApc/Namespaced/FooBar.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?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 LegacyApc\Namespaced;
|
||||
|
||||
class FooBar
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
6
Tests/Fixtures/LegacyApc/Pearlike/Bar.php
Normal file
6
Tests/Fixtures/LegacyApc/Pearlike/Bar.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
class LegacyApc_Pearlike_Bar
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
6
Tests/Fixtures/LegacyApc/Pearlike/Baz.php
Normal file
6
Tests/Fixtures/LegacyApc/Pearlike/Baz.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
class LegacyApc_Pearlike_Baz
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
6
Tests/Fixtures/LegacyApc/Pearlike/Foo.php
Normal file
6
Tests/Fixtures/LegacyApc/Pearlike/Foo.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
class LegacyApc_Pearlike_Foo
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
class LegacyApcPrefixCollision_A_Bar
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
class LegacyApcPrefixCollision_A_Foo
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?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 LegacyApc\NamespaceCollision\A;
|
||||
|
||||
class Bar
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?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 LegacyApc\NamespaceCollision\A;
|
||||
|
||||
class Foo
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
class LegacyApcPrefixCollision_A_B_Bar
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
class LegacyApcPrefixCollision_A_B_Foo
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?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 LegacyApc\NamespaceCollision\A\B;
|
||||
|
||||
class Bar
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?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 LegacyApc\NamespaceCollision\A\B;
|
||||
|
||||
class Foo
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
class LegacyApc_Pearlike_FooBar
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
17
Tests/Fixtures/LegacyApc/fallback/Namespaced/FooBar.php
Normal file
17
Tests/Fixtures/LegacyApc/fallback/Namespaced/FooBar.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?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 LegacyApc\Namespaced;
|
||||
|
||||
class FooBar
|
||||
{
|
||||
public static $loaded = true;
|
||||
}
|
||||
15
Tests/Fixtures/Namespaced/WithDirMagic.php
Normal file
15
Tests/Fixtures/Namespaced/WithDirMagic.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* foo
|
||||
*/
|
||||
|
||||
namespace Namespaced;
|
||||
|
||||
class WithDirMagic
|
||||
{
|
||||
public function getDir()
|
||||
{
|
||||
return __DIR__;
|
||||
}
|
||||
}
|
||||
15
Tests/Fixtures/Namespaced/WithFileMagic.php
Normal file
15
Tests/Fixtures/Namespaced/WithFileMagic.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* foo
|
||||
*/
|
||||
|
||||
namespace Namespaced;
|
||||
|
||||
class WithFileMagic
|
||||
{
|
||||
public function getFile()
|
||||
{
|
||||
return __FILE__;
|
||||
}
|
||||
}
|
||||
18
Tests/Fixtures/Namespaced/WithHaltCompiler.php
Normal file
18
Tests/Fixtures/Namespaced/WithHaltCompiler.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* foo
|
||||
*/
|
||||
|
||||
namespace Namespaced;
|
||||
|
||||
class WithHaltCompiler
|
||||
{
|
||||
}
|
||||
|
||||
// the end of the script execution
|
||||
__halt_compiler(); data
|
||||
data
|
||||
data
|
||||
data
|
||||
...
|
||||
13
Tests/Fixtures/Namespaced/WithStrictTypes.php
Normal file
13
Tests/Fixtures/Namespaced/WithStrictTypes.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* foo
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Namespaced;
|
||||
|
||||
class WithStrictTypes
|
||||
{
|
||||
}
|
||||
190
Tests/LegacyApcUniversalClassLoaderTest.php
Normal file
190
Tests/LegacyApcUniversalClassLoaderTest.php
Normal file
@@ -0,0 +1,190 @@
|
||||
<?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 PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
class LegacyApcUniversalClassLoaderTest extends TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
if (ini_get('apc.enabled') && ini_get('apc.enable_cli')) {
|
||||
apcu_clear_cache();
|
||||
} else {
|
||||
$this->markTestSkipped('APC is not enabled.');
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
if (ini_get('apc.enabled') && ini_get('apc.enable_cli')) {
|
||||
apcu_clear_cache();
|
||||
}
|
||||
}
|
||||
|
||||
public function testConstructor()
|
||||
{
|
||||
$loader = new ApcUniversalClassLoader('test.prefix.');
|
||||
$loader->registerNamespace('LegacyApc\Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
|
||||
$this->assertEquals($loader->findFile('\LegacyApc\Namespaced\FooBar'), apcu_fetch('test.prefix.\LegacyApc\Namespaced\FooBar'), '__construct() takes a prefix as its first argument');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getLoadClassTests
|
||||
*/
|
||||
public function testLoadClass($className, $testClassName, $message)
|
||||
{
|
||||
$loader = new ApcUniversalClassLoader('test.prefix.');
|
||||
$loader->registerNamespace('LegacyApc\Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerPrefix('LegacyApc_Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->loadClass($testClassName);
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
public function getLoadClassTests()
|
||||
{
|
||||
return array(
|
||||
array('\\LegacyApc\\Namespaced\\Foo', 'LegacyApc\\Namespaced\\Foo', '->loadClass() loads LegacyApc\Namespaced\Foo class'),
|
||||
array('LegacyApc_Pearlike_Foo', 'LegacyApc_Pearlike_Foo', '->loadClass() loads LegacyApc_Pearlike_Foo class'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getLoadClassFromFallbackTests
|
||||
*/
|
||||
public function testLoadClassFromFallback($className, $testClassName, $message)
|
||||
{
|
||||
$loader = new ApcUniversalClassLoader('test.prefix.fallback');
|
||||
$loader->registerNamespace('LegacyApc\Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerPrefix('LegacyApc_Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerNamespaceFallbacks(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/fallback'));
|
||||
$loader->registerPrefixFallbacks(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/fallback'));
|
||||
$loader->loadClass($testClassName);
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
public function getLoadClassFromFallbackTests()
|
||||
{
|
||||
return array(
|
||||
array('\\LegacyApc\\Namespaced\\Baz', 'LegacyApc\\Namespaced\\Baz', '->loadClass() loads LegacyApc\Namespaced\Baz class'),
|
||||
array('LegacyApc_Pearlike_Baz', 'LegacyApc_Pearlike_Baz', '->loadClass() loads LegacyApc_Pearlike_Baz class'),
|
||||
array('\\LegacyApc\\Namespaced\\FooBar', 'LegacyApc\\Namespaced\\FooBar', '->loadClass() loads LegacyApc\Namespaced\Baz class from fallback dir'),
|
||||
array('LegacyApc_Pearlike_FooBar', 'LegacyApc_Pearlike_FooBar', '->loadClass() loads LegacyApc_Pearlike_Baz class from fallback dir'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getLoadClassNamespaceCollisionTests
|
||||
*/
|
||||
public function testLoadClassNamespaceCollision($namespaces, $className, $message)
|
||||
{
|
||||
$loader = new ApcUniversalClassLoader('test.prefix.collision.');
|
||||
$loader->registerNamespaces($namespaces);
|
||||
|
||||
$loader->loadClass($className);
|
||||
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
public function getLoadClassNamespaceCollisionTests()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array(
|
||||
'LegacyApc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/alpha',
|
||||
'LegacyApc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/beta',
|
||||
),
|
||||
'LegacyApc\NamespaceCollision\A\Foo',
|
||||
'->loadClass() loads NamespaceCollision\A\Foo from alpha.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'LegacyApc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/beta',
|
||||
'LegacyApc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/alpha',
|
||||
),
|
||||
'LegacyApc\NamespaceCollision\A\Bar',
|
||||
'->loadClass() loads NamespaceCollision\A\Bar from alpha.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'LegacyApc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/alpha',
|
||||
'LegacyApc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/beta',
|
||||
),
|
||||
'LegacyApc\NamespaceCollision\A\B\Foo',
|
||||
'->loadClass() loads NamespaceCollision\A\B\Foo from beta.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'LegacyApc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/beta',
|
||||
'LegacyApc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/alpha',
|
||||
),
|
||||
'LegacyApc\NamespaceCollision\A\B\Bar',
|
||||
'->loadClass() loads NamespaceCollision\A\B\Bar from beta.',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getLoadClassPrefixCollisionTests
|
||||
*/
|
||||
public function testLoadClassPrefixCollision($prefixes, $className, $message)
|
||||
{
|
||||
$loader = new ApcUniversalClassLoader('test.prefix.collision.');
|
||||
$loader->registerPrefixes($prefixes);
|
||||
|
||||
$loader->loadClass($className);
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
public function getLoadClassPrefixCollisionTests()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array(
|
||||
'LegacyApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/alpha/LegacyApc',
|
||||
'LegacyApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/beta/LegacyApc',
|
||||
),
|
||||
'LegacyApcPrefixCollision_A_Foo',
|
||||
'->loadClass() loads LegacyApcPrefixCollision_A_Foo from alpha.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'LegacyApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/beta/LegacyApc',
|
||||
'LegacyApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/alpha/LegacyApc',
|
||||
),
|
||||
'LegacyApcPrefixCollision_A_Bar',
|
||||
'->loadClass() loads LegacyApcPrefixCollision_A_Bar from alpha.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'LegacyApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/alpha/LegacyApc',
|
||||
'LegacyApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/beta/LegacyApc',
|
||||
),
|
||||
'LegacyApcPrefixCollision_A_B_Foo',
|
||||
'->loadClass() loads LegacyApcPrefixCollision_A_B_Foo from beta.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'LegacyApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/beta/LegacyApc',
|
||||
'LegacyApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/LegacyApc/alpha/LegacyApc',
|
||||
),
|
||||
'LegacyApcPrefixCollision_A_B_Bar',
|
||||
'->loadClass() loads LegacyApcPrefixCollision_A_B_Bar from beta.',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
224
Tests/LegacyUniversalClassLoaderTest.php
Normal file
224
Tests/LegacyUniversalClassLoaderTest.php
Normal file
@@ -0,0 +1,224 @@
|
||||
<?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 PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\ClassLoader\UniversalClassLoader;
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
class LegacyUniversalClassLoaderTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider getLoadClassTests
|
||||
*/
|
||||
public function testLoadClass($className, $testClassName, $message)
|
||||
{
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$this->assertTrue($loader->loadClass($testClassName));
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
public function getLoadClassTests()
|
||||
{
|
||||
return array(
|
||||
array('\\Namespaced\\Foo', 'Namespaced\\Foo', '->loadClass() loads Namespaced\Foo class'),
|
||||
array('\\Pearlike_Foo', 'Pearlike_Foo', '->loadClass() loads Pearlike_Foo class'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testUseIncludePath()
|
||||
{
|
||||
$loader = new UniversalClassLoader();
|
||||
$this->assertFalse($loader->getUseIncludePath());
|
||||
|
||||
$this->assertNull($loader->findFile('Foo'));
|
||||
|
||||
$includePath = get_include_path();
|
||||
|
||||
$loader->useIncludePath(true);
|
||||
$this->assertTrue($loader->getUseIncludePath());
|
||||
|
||||
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'));
|
||||
|
||||
set_include_path($includePath);
|
||||
}
|
||||
|
||||
public function testGetNamespaces()
|
||||
{
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerNamespace('Foo', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerNamespace('Bar', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerNamespace('Bas', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$namespaces = $loader->getNamespaces();
|
||||
$this->assertArrayHasKey('Foo', $namespaces);
|
||||
$this->assertArrayNotHasKey('Foo1', $namespaces);
|
||||
$this->assertArrayHasKey('Bar', $namespaces);
|
||||
$this->assertArrayHasKey('Bas', $namespaces);
|
||||
}
|
||||
|
||||
public function testGetPrefixes()
|
||||
{
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerPrefix('Foo', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerPrefix('Bar', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerPrefix('Bas', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$prefixes = $loader->getPrefixes();
|
||||
$this->assertArrayHasKey('Foo', $prefixes);
|
||||
$this->assertArrayNotHasKey('Foo1', $prefixes);
|
||||
$this->assertArrayHasKey('Bar', $prefixes);
|
||||
$this->assertArrayHasKey('Bas', $prefixes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getLoadClassFromFallbackTests
|
||||
*/
|
||||
public function testLoadClassFromFallback($className, $testClassName, $message)
|
||||
{
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$loader->registerNamespaceFallbacks(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'));
|
||||
$loader->registerPrefixFallbacks(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'));
|
||||
$this->assertTrue($loader->loadClass($testClassName));
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
public function getLoadClassFromFallbackTests()
|
||||
{
|
||||
return array(
|
||||
array('\\Namespaced\\Baz', 'Namespaced\\Baz', '->loadClass() loads Namespaced\Baz class'),
|
||||
array('\\Pearlike_Baz', 'Pearlike_Baz', '->loadClass() loads Pearlike_Baz class'),
|
||||
array('\\Namespaced\\FooBar', 'Namespaced\\FooBar', '->loadClass() loads Namespaced\Baz class from fallback dir'),
|
||||
array('\\Pearlike_FooBar', 'Pearlike_FooBar', '->loadClass() loads Pearlike_Baz class from fallback dir'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testRegisterPrefixFallback()
|
||||
{
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerPrefixFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback');
|
||||
$this->assertEquals(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'), $loader->getPrefixFallbacks());
|
||||
}
|
||||
|
||||
public function testRegisterNamespaceFallback()
|
||||
{
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerNamespaceFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/Namespaced/fallback');
|
||||
$this->assertEquals(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/Namespaced/fallback'), $loader->getNamespaceFallbacks());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getLoadClassNamespaceCollisionTests
|
||||
*/
|
||||
public function testLoadClassNamespaceCollision($namespaces, $className, $message)
|
||||
{
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerNamespaces($namespaces);
|
||||
|
||||
$this->assertTrue($loader->loadClass($className));
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
public function getLoadClassNamespaceCollisionTests()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array(
|
||||
'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
|
||||
'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
|
||||
),
|
||||
'NamespaceCollision\A\Foo',
|
||||
'->loadClass() loads NamespaceCollision\A\Foo from alpha.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
|
||||
'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
|
||||
),
|
||||
'NamespaceCollision\A\Bar',
|
||||
'->loadClass() loads NamespaceCollision\A\Bar from alpha.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
|
||||
'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
|
||||
),
|
||||
'NamespaceCollision\A\B\Foo',
|
||||
'->loadClass() loads NamespaceCollision\A\B\Foo from beta.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
|
||||
'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
|
||||
),
|
||||
'NamespaceCollision\A\B\Bar',
|
||||
'->loadClass() loads NamespaceCollision\A\B\Bar from beta.',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getLoadClassPrefixCollisionTests
|
||||
*/
|
||||
public function testLoadClassPrefixCollision($prefixes, $className, $message)
|
||||
{
|
||||
$loader = new UniversalClassLoader();
|
||||
$loader->registerPrefixes($prefixes);
|
||||
|
||||
$this->assertTrue($loader->loadClass($className));
|
||||
$this->assertTrue(class_exists($className), $message);
|
||||
}
|
||||
|
||||
public function getLoadClassPrefixCollisionTests()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array(
|
||||
'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
|
||||
'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
|
||||
),
|
||||
'PrefixCollision_A_Foo',
|
||||
'->loadClass() loads PrefixCollision_A_Foo from alpha.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
|
||||
'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
|
||||
),
|
||||
'PrefixCollision_A_Bar',
|
||||
'->loadClass() loads PrefixCollision_A_Bar from alpha.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
|
||||
'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
|
||||
),
|
||||
'PrefixCollision_A_B_Foo',
|
||||
'->loadClass() loads PrefixCollision_A_B_Foo from beta.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta',
|
||||
'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha',
|
||||
),
|
||||
'PrefixCollision_A_B_Bar',
|
||||
'->loadClass() loads PrefixCollision_A_B_Bar from beta.',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,10 @@
|
||||
|
||||
namespace Symfony\Component\ClassLoader\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\ClassLoader\Psr4ClassLoader;
|
||||
|
||||
class Psr4ClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
class Psr4ClassLoaderTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @param string $className
|
||||
|
||||
307
UniversalClassLoader.php
Normal file
307
UniversalClassLoader.php
Normal file
@@ -0,0 +1,307 @@
|
||||
<?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;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\UniversalClassLoader class is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Component\ClassLoader\ClassLoader class instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* UniversalClassLoader implements a "universal" autoloader for PHP 5.3.
|
||||
*
|
||||
* It is able to load classes that use either:
|
||||
*
|
||||
* * The technical interoperability standards for PHP 5.3 namespaces and
|
||||
* class names (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md);
|
||||
*
|
||||
* * The PEAR naming convention for classes (http://pear.php.net/).
|
||||
*
|
||||
* Classes from a sub-namespace or a sub-hierarchy of PEAR classes can be
|
||||
* looked for in a list of locations to ease the vendoring of a sub-set of
|
||||
* classes for large projects.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* $loader = new UniversalClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->registerNamespaces(array(
|
||||
* 'Symfony\Component' => __DIR__.'/component',
|
||||
* 'Symfony' => __DIR__.'/framework',
|
||||
* 'Sensio' => array(__DIR__.'/src', __DIR__.'/vendor'),
|
||||
* ));
|
||||
*
|
||||
* // register a library using the PEAR naming convention
|
||||
* $loader->registerPrefixes(array(
|
||||
* 'Swift_' => __DIR__.'/Swift',
|
||||
* ));
|
||||
*
|
||||
*
|
||||
* // to enable searching the include path (e.g. for PEAR packages)
|
||||
* $loader->useIncludePath(true);
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated since version 2.4, to be removed in 3.0.
|
||||
* Use the {@link ClassLoader} class instead.
|
||||
*/
|
||||
class UniversalClassLoader
|
||||
{
|
||||
private $namespaces = array();
|
||||
private $prefixes = array();
|
||||
private $namespaceFallbacks = array();
|
||||
private $prefixFallbacks = array();
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* Turns on searching the include for class files. Allows easy loading
|
||||
* of installed PEAR packages.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*/
|
||||
public function useIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = (bool) $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configured namespaces.
|
||||
*
|
||||
* @return array A hash with namespaces as keys and directories as values
|
||||
*/
|
||||
public function getNamespaces()
|
||||
{
|
||||
return $this->namespaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configured class prefixes.
|
||||
*
|
||||
* @return array A hash with class prefixes as keys and directories as values
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
return $this->prefixes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the directory(ies) to use as a fallback for namespaces.
|
||||
*
|
||||
* @return array An array of directories
|
||||
*/
|
||||
public function getNamespaceFallbacks()
|
||||
{
|
||||
return $this->namespaceFallbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the directory(ies) to use as a fallback for class prefixes.
|
||||
*
|
||||
* @return array An array of directories
|
||||
*/
|
||||
public function getPrefixFallbacks()
|
||||
{
|
||||
return $this->prefixFallbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the directory to use as a fallback for namespaces.
|
||||
*
|
||||
* @param array $dirs An array of directories
|
||||
*/
|
||||
public function registerNamespaceFallbacks(array $dirs)
|
||||
{
|
||||
$this->namespaceFallbacks = $dirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a directory to use as a fallback for namespaces.
|
||||
*
|
||||
* @param string $dir A directory
|
||||
*/
|
||||
public function registerNamespaceFallback($dir)
|
||||
{
|
||||
$this->namespaceFallbacks[] = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers directories to use as a fallback for class prefixes.
|
||||
*
|
||||
* @param array $dirs An array of directories
|
||||
*/
|
||||
public function registerPrefixFallbacks(array $dirs)
|
||||
{
|
||||
$this->prefixFallbacks = $dirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a directory to use as a fallback for class prefixes.
|
||||
*
|
||||
* @param string $dir A directory
|
||||
*/
|
||||
public function registerPrefixFallback($dir)
|
||||
{
|
||||
$this->prefixFallbacks[] = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an array of namespaces.
|
||||
*
|
||||
* @param array $namespaces An array of namespaces (namespaces as keys and locations as values)
|
||||
*/
|
||||
public function registerNamespaces(array $namespaces)
|
||||
{
|
||||
foreach ($namespaces as $namespace => $locations) {
|
||||
$this->namespaces[$namespace] = (array) $locations;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a namespace.
|
||||
*
|
||||
* @param string $namespace The namespace
|
||||
* @param array|string $paths The location(s) of the namespace
|
||||
*/
|
||||
public function registerNamespace($namespace, $paths)
|
||||
{
|
||||
$this->namespaces[$namespace] = (array) $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an array of classes using the PEAR naming convention.
|
||||
*
|
||||
* @param array $classes An array of classes (prefixes as keys and locations as values)
|
||||
*/
|
||||
public function registerPrefixes(array $classes)
|
||||
{
|
||||
foreach ($classes as $prefix => $locations) {
|
||||
$this->prefixes[$prefix] = (array) $locations;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of classes using the PEAR naming convention.
|
||||
*
|
||||
* @param string $prefix The classes prefix
|
||||
* @param array|string $paths The location(s) of the classes
|
||||
*/
|
||||
public function registerPrefix($prefix, $paths)
|
||||
{
|
||||
$this->prefixes[$prefix] = (array) $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return bool|null True, if loaded
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
require $file;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|null The path, if found
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$namespace = substr($class, 0, $pos);
|
||||
$className = substr($class, $pos + 1);
|
||||
$normalizedClass = str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
|
||||
foreach ($this->namespaces as $ns => $dirs) {
|
||||
if (0 !== strpos($namespace, $ns)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($dirs as $dir) {
|
||||
$file = $dir.DIRECTORY_SEPARATOR.$normalizedClass;
|
||||
if (is_file($file)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->namespaceFallbacks as $dir) {
|
||||
$file = $dir.DIRECTORY_SEPARATOR.$normalizedClass;
|
||||
if (is_file($file)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$normalizedClass = str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
|
||||
foreach ($this->prefixes as $prefix => $dirs) {
|
||||
if (0 !== strpos($class, $prefix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($dirs as $dir) {
|
||||
$file = $dir.DIRECTORY_SEPARATOR.$normalizedClass;
|
||||
if (is_file($file)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->prefixFallbacks as $dir) {
|
||||
$file = $dir.DIRECTORY_SEPARATOR.$normalizedClass;
|
||||
if (is_file($file)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($normalizedClass)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,12 @@ namespace Symfony\Component\ClassLoader;
|
||||
*
|
||||
* 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 for instance) but also around any other autoloaders following
|
||||
* this convention (the Composer one for instance).
|
||||
* ClassLoader and the UniversalClassLoader for instance) but also around any
|
||||
* other autoloaders following this convention (the Composer one for instance).
|
||||
*
|
||||
* // with a Symfony autoloader
|
||||
* use Symfony\Component\ClassLoader\ClassLoader;
|
||||
*
|
||||
* $loader = new ClassLoader();
|
||||
* $loader->addPrefix('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->addPrefix('Symfony', __DIR__.'/framework');
|
||||
@@ -56,8 +58,6 @@ class WinCacheClassLoader
|
||||
protected $decorated;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $prefix The WinCache namespace prefix to use
|
||||
* @param object $decorated A class loader object that implements the findFile() method
|
||||
*
|
||||
|
||||
@@ -16,10 +16,12 @@ namespace Symfony\Component\ClassLoader;
|
||||
*
|
||||
* It expects an object implementing a findFile method to find the file. This
|
||||
* allows using it as a wrapper around the other loaders of the component (the
|
||||
* ClassLoader for instance) but also around any other autoloaders following
|
||||
* this convention (the Composer one for instance).
|
||||
* ClassLoader and the UniversalClassLoader for instance) but also around any
|
||||
* other autoloaders following this convention (the Composer one for instance).
|
||||
*
|
||||
* // with a Symfony autoloader
|
||||
* use Symfony\Component\ClassLoader\ClassLoader;
|
||||
*
|
||||
* $loader = new ClassLoader();
|
||||
* $loader->addPrefix('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->addPrefix('Symfony', __DIR__.'/framework');
|
||||
@@ -47,17 +49,9 @@ namespace Symfony\Component\ClassLoader;
|
||||
class XcacheClassLoader
|
||||
{
|
||||
private $prefix;
|
||||
|
||||
/**
|
||||
* A class loader object that implements the findFile() method.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private $decorated;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $prefix The XCache namespace prefix to use
|
||||
* @param object $decorated A class loader object that implements the findFile() method
|
||||
*
|
||||
|
||||
@@ -17,14 +17,11 @@
|
||||
],
|
||||
"minimum-stability": "dev",
|
||||
"require": {
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/finder": "~2.8|~3.0",
|
||||
"php": ">=5.3.9",
|
||||
"symfony/polyfill-apcu": "~1.1"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/polyfill-apcu": "For using ApcClassLoader on HHVM"
|
||||
"require-dev": {
|
||||
"symfony/finder": "^2.0.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Component\\ClassLoader\\": "" },
|
||||
@@ -34,7 +31,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0-dev"
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
bootstrap="vendor/autoload.php"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1" />
|
||||
|
||||
Reference in New Issue
Block a user