Skip to content

Commit

Permalink
Fix UniversalClassLoader issues with leading slashes.
Browse files Browse the repository at this point in the history
This fixes a bug in UniversalClassLoader when attempting to autoload class names with leading slashes:

    $namespacedClass = "\\Foo\\Bar";
    $pearlikeClass   = "\\Foo_Bar";

    $namespaced = new $namespacedClass();
    $pearlike   = new $pearlikeClass();

`UniversalClassLoader::loadClass()` was unable to load PEAR-like classes with leading slashes because it found the slash and assumed that the requested class was namespaced. It was unable to load namespaced classes with leading slashes because it would look them up in the autoloader's registered namespaces, and was unable to match '\Foo' to 'Foo'. One (ugly) workaround for the namespaced classes was to register all namespaces twice:

    $loader->registerNamespaces(array(
        'Foo'  => __DIR__ . '/lib',
        '\Foo' => __DIR__ . '/lib',
    ));

But that's not very pretty, nor does it solve the bug with PEAR-like classes. Stripping the leading slash before trying to autoload allows UniversalClassLoader to load both namespaced and PEAR-like classes.
  • Loading branch information
bobthecow authored and fabpot committed Oct 20, 2010
1 parent dd7e33a commit 0ccc980
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Symfony/Component/HttpFoundation/UniversalClassLoader.php
Expand Up @@ -123,6 +123,10 @@ public function register()
*/
public function loadClass($class)
{
if ('\\' === $class[0]) {
$class = substr($class, 1);
}

if (false !== ($pos = strripos($class, '\\'))) {
// namespaced class name
$namespace = substr($class, 0, $pos);
Expand Down
@@ -0,0 +1,7 @@
<?php

namespace Namespaced;

class Bar {
public static $loaded = true;
}
@@ -0,0 +1,7 @@
<?php

namespace Namespaced;

class Foo {
public static $loaded = true;
}
@@ -0,0 +1,5 @@
<?php

class Pearlike_Bar {
public static $loaded = true;
}
@@ -0,0 +1,5 @@
<?php

class Pearlike_Foo {
public static $loaded = true;
}
@@ -0,0 +1,41 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Tests\Component\HttpFoundation;

use Symfony\Component\HttpFoundation\UniversalClassLoader;

class UniversalClassLoaderTest extends \PHPUnit_Framework_TestCase
{
/**
* @covers Symfony\Component\HttpFoundation\UniversalClassLoader::loadClass
* @dataProvider testClassProvider
*/
public function testLoadClass($className, $testClassName, $message)
{
$loader = new UniversalClassLoader();
$loader->registerNamespace('Namespaced', __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures');
$loader->registerPrefix('Pearlike_', __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures');
$loader->loadClass($testClassName);
$this->assertTrue(class_exists($className), $message);
}

public static function testClassProvider()
{
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'),
);
}
}

0 comments on commit 0ccc980

Please sign in to comment.