diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index 2080944792f01..847cd009280ac 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -176,18 +176,30 @@ public function loadClass($class) $class = substr($class, 1); } - $i = -1; - $tail = str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'; + $i = 0; + $tail = DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'; $len = strlen($tail); do { - $tail = substr($tail, $i+1); - $len -= $i+1; - - if (! substr_compare($file, $tail, -$len, $len, true) && substr_compare($file, $tail, -$len, $len, false)) { - throw new \RuntimeException(sprintf('Case mismatch between class and source file names: %s vs %s', $class, $file)); + $tail = substr($tail, $i); + $len -= $i; + + if (0 === substr_compare($file, $tail, -$len, $len, true)) { + if (0 !== substr_compare($file, $tail, -$len, $len, false)) { + if (method_exists($this->classLoader[0], 'getClassMap')) { + $map = $this->classLoader[0]->getClassMap(); + } else { + $map = array(); + } + + if (! isset($map[$class])) { + throw new \RuntimeException(sprintf('Case mismatch between class and source file names: %s vs %s', $class, $file)); + } + } + + break; } - } while (false !== $i = strpos($tail, '\\')); + } while (false !== $i = strpos($tail, DIRECTORY_SEPARATOR, 1)); if (! $exists) { if (false !== strpos($class, '/')) { diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php index 573869b63b60c..0c071414f7723 100644 --- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php @@ -140,6 +140,24 @@ public function testFileCaseMismatch() { class_exists(__NAMESPACE__.'\Fixtures\CaseMismatch', true); } + + /** + * @expectedException \RuntimeException + */ + public function testPsr4CaseMismatch() + { + class_exists(__NAMESPACE__.'\Fixtures\Psr4CaseMismatch', true); + } + + public function testNotPsr0() + { + $this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\NotPSR0', true)); + } + + public function testNotPsr0Bis() + { + $this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\NotPSR0bis', true)); + } } class ClassLoader @@ -148,6 +166,11 @@ public function loadClass($class) { } + public function getClassMap() + { + return array(__NAMESPACE__.'\Fixtures\NotPSR0bis' => __DIR__ . '/Fixtures/notPsr0Bis.php'); + } + public function findFile($class) { if (__NAMESPACE__.'\TestingUnsilencing' === $class) { @@ -158,6 +181,12 @@ public function findFile($class) eval('namespace '.__NAMESPACE__.'; class TestingCaseMisMatch {}'); } elseif (__NAMESPACE__.'\Fixtures\CaseMismatch' === $class) { return __DIR__ . '/Fixtures/casemismatch.php'; + } elseif (__NAMESPACE__.'\Fixtures\Psr4CaseMismatch' === $class) { + return __DIR__ . '/Fixtures/psr4/Psr4CaseMismatch.php'; + } elseif (__NAMESPACE__.'\Fixtures\NotPSR0' === $class) { + return __DIR__ . '/Fixtures/reallyNotPsr0.php'; + } elseif (__NAMESPACE__.'\Fixtures\NotPSR0bis' === $class) { + return __DIR__ . '/Fixtures/notPsr0Bis.php'; } } } diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/notPsr0Bis.php b/src/Symfony/Component/Debug/Tests/Fixtures/notPsr0Bis.php new file mode 100644 index 0000000000000..4cf526719a6e6 --- /dev/null +++ b/src/Symfony/Component/Debug/Tests/Fixtures/notPsr0Bis.php @@ -0,0 +1,7 @@ +