merged branch henrikbjorn/autoload (PR #1857)

Commits
-------

ae3b128 [ClassLoader] Support for autoloading include_path incl. tests.

Discussion
----------

Autoload

GH Issue #1823

---------------------------------------------------------------------------

by stof at 2011/07/29 00:42:10 -0700

note that another fix was proposed in #1852 but this implementation is cleaner IMO

---------------------------------------------------------------------------

by henrikbjorn at 2011/08/12 01:57:45 -0700

@fabpot @stof any suggestions? need this kind of badly

---------------------------------------------------------------------------

by stof at 2011/08/12 02:06:54 -0700

for me it is fine. I guess you need to wait the end of @fabpot's holydays to see it merged.

---------------------------------------------------------------------------

by henrikbjorn at 2011/08/25 02:24:13 -0700

Added tests in the hope it will make it in soon :)

---------------------------------------------------------------------------

by henrikbjorn at 2011/08/29 03:31:08 -0700

Any other requests / suggestions ?

---------------------------------------------------------------------------

by stof at 2011/08/29 03:36:15 -0700

could you rebase the PR ? Github says that it conflicts.

---------------------------------------------------------------------------

by henrikbjorn at 2011/08/29 04:11:43 -0700

Should be rebased now or that is what git cli says :)

---------------------------------------------------------------------------

by henrikbjorn at 2011/08/29 04:16:28 -0700

And squashed.
This commit is contained in:
Fabien Potencier 2011-08-29 15:37:03 +02:00
commit 93ea745397
4 changed files with 64 additions and 5 deletions

View File

@ -38,6 +38,7 @@ class DebugUniversalClassLoader extends UniversalClassLoader
$loader->registerPrefixFallbacks($function[0]->getPrefixFallbacks()); $loader->registerPrefixFallbacks($function[0]->getPrefixFallbacks());
$loader->registerNamespaces($function[0]->getNamespaces()); $loader->registerNamespaces($function[0]->getNamespaces());
$loader->registerPrefixes($function[0]->getPrefixes()); $loader->registerPrefixes($function[0]->getPrefixes());
$loader->useIncludePath($function[0]->getUseIncludePath());
$function[0] = $loader; $function[0] = $loader;
} }

View File

@ -41,6 +41,10 @@ namespace Symfony\Component\ClassLoader;
* 'Swift_' => __DIR__.'/Swift', * 'Swift_' => __DIR__.'/Swift',
* )); * ));
* *
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->useIncludePath(true);
*
* // activate the autoloader * // activate the autoloader
* $loader->register(); * $loader->register();
* *
@ -60,6 +64,29 @@ class UniversalClassLoader
private $prefixes = array(); private $prefixes = array();
private $namespaceFallbacks = array(); private $namespaceFallbacks = array();
private $prefixFallbacks = array(); private $prefixFallbacks = array();
private $useIncludePath = false;
/**
* Turns on searching the include for class files. Allows easy loading
* of installed PEAR packages
*
* @param Boolean $useIncludePath
*/
public function useIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return Boolean
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/** /**
* Gets the configured namespaces. * Gets the configured namespaces.
@ -219,14 +246,15 @@ class UniversalClassLoader
if (false !== $pos = strrpos($class, '\\')) { if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name // namespaced class name
$namespace = substr($class, 0, $pos); $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) { foreach ($this->namespaces as $ns => $dirs) {
if (0 !== strpos($namespace, $ns)) { if (0 !== strpos($namespace, $ns)) {
continue; continue;
} }
foreach ($dirs as $dir) { foreach ($dirs as $dir) {
$className = substr($class, $pos + 1); $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass;
$file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
if (is_file($file)) { if (is_file($file)) {
return $file; return $file;
} }
@ -234,20 +262,22 @@ class UniversalClassLoader
} }
foreach ($this->namespaceFallbacks as $dir) { foreach ($this->namespaceFallbacks as $dir) {
$file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'; $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass;
if (is_file($file)) { if (is_file($file)) {
return $file; return $file;
} }
} }
} else { } else {
// PEAR-like class name // PEAR-like class name
$normalizedClass = str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
foreach ($this->prefixes as $prefix => $dirs) { foreach ($this->prefixes as $prefix => $dirs) {
if (0 !== strpos($class, $prefix)) { if (0 !== strpos($class, $prefix)) {
continue; continue;
} }
foreach ($dirs as $dir) { foreach ($dirs as $dir) {
$file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php'; $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass;
if (is_file($file)) { if (is_file($file)) {
return $file; return $file;
} }
@ -255,11 +285,15 @@ class UniversalClassLoader
} }
foreach ($this->prefixFallbacks as $dir) { foreach ($this->prefixFallbacks as $dir) {
$file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php'; $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass;
if (is_file($file)) { if (is_file($file)) {
return $file; return $file;
} }
} }
} }
if ($this->useIncludePath && $file = stream_resolve_include_path($normalizedClass)) {
return $file;
}
} }
} }

View File

@ -0,0 +1,5 @@
<?php
class Foo
{
}

View File

@ -37,6 +37,25 @@ class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
); );
} }
public function testUseIncludePath()
{
$loader = new UniversalClassLoader();
$this->assertFalse($loader->getUseIncludePath());
$this->assertEquals(null, $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__.'/Fixtures/includepath/Foo.php', $loader->findFile('Foo'));
set_include_path($includePath);
}
/** /**
* @dataProvider getLoadClassFromFallbackTests * @dataProvider getLoadClassFromFallbackTests
*/ */