[Debug] fix #10771 DebugClassLoader can't load PSR4 libs

This commit is contained in:
Nicolas Grekas 2014-04-24 14:55:37 +02:00
parent aa5d62d8bc
commit e3566c27b7
2 changed files with 37 additions and 28 deletions

View File

@ -176,30 +176,35 @@ class DebugClassLoader
$class = substr($class, 1);
}
$i = 0;
$tail = DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
$len = strlen($tail);
do {
$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));
}
}
if (preg_match('#([/\\\\][a-zA-Z_\x7F-\xFF][a-zA-Z0-9_\x7F-\xFF]*)+\.(php|hh)$#', $file, $tail)) {
$tail = $tail[0];
$real = realpath($file);
if (false !== stripos(PHP_OS, 'darwin')) {
// realpath() on MacOSX doesn't normalize the case of characters,
// let's do it ourselves. This is tricky.
$cwd = getcwd();
$basename = strrpos($real, '/');
chdir(substr($real, 0, $basename));
$basename = substr($real, $basename + 1);
$real = getcwd().'/';
$h = opendir('.');
while (false !== $f = readdir($h)) {
if (0 === strcasecmp($f, $basename)) {
$real .= $f;
break;
}
} while (false !== $i = strpos($tail, DIRECTORY_SEPARATOR, 1));
}
closedir($h);
chdir($cwd);
}
if ( 0 === substr_compare($real, $tail, -strlen($tail), strlen($tail), true)
&& 0 !== substr_compare($real, $tail, -strlen($tail), strlen($tail), false)
) {
throw new \RuntimeException(sprintf('Case mismatch between class and source file names: %s vs %s', $class, $real));
}
}
if (!$exists) {
if (false !== strpos($class, '/')) {

View File

@ -27,7 +27,7 @@ class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase
{
$this->errorReporting = error_reporting(E_ALL | E_STRICT);
$this->loader = new ClassLoader();
spl_autoload_register(array($this->loader, 'loadClass'));
spl_autoload_register(array($this->loader, 'loadClass'), true, true);
DebugClassLoader::enable();
}
@ -138,6 +138,10 @@ class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase
*/
public function testFileCaseMismatch()
{
if (!file_exists(__DIR__.'/Fixtures/CaseMismatch.php')) {
$this->markTestSkipped('Can only be run on case insensitive filesystems');
}
class_exists(__NAMESPACE__.'\Fixtures\CaseMismatch', true);
}
@ -180,7 +184,7 @@ class ClassLoader
} elseif (__NAMESPACE__.'\TestingCaseMismatch' === $class) {
eval('namespace '.__NAMESPACE__.'; class TestingCaseMisMatch {}');
} elseif (__NAMESPACE__.'\Fixtures\CaseMismatch' === $class) {
return __DIR__ . '/Fixtures/casemismatch.php';
return __DIR__.'/Fixtures/CaseMismatch.php';
} elseif (__NAMESPACE__.'\Fixtures\Psr4CaseMismatch' === $class) {
return __DIR__.'/Fixtures/psr4/Psr4CaseMismatch.php';
} elseif (__NAMESPACE__.'\Fixtures\NotPSR0' === $class) {