Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix bug in classExists when using multiple autoloaders (i.e. ZF2) #183

Closed
wants to merge 1 commit into from

1 participant

@bramstroker

The autoloading routine in the classExists method makes the assumption the autoload method always returns a value (i.e. no void) when the autoloading of a class is succesfull. When you have multiple autoloaders registered to the spl stack this can lead to problems. In my case I'm using ZF2 ClassmapAutoloader and StandardAutoloader as fallback. The classmapAutoloader returns nothing so the autoload method in the StandardAutoloader is called as well, because the for loop is continued. This results in a second include, and a fatal error "Cannot redeclare class" is triggered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 17, 2012
This page is out of date. Refresh to see the latest.
View
5 lib/Doctrine/Common/ClassLoader.php
@@ -235,9 +235,12 @@ public static function classExists($className)
} else if (is_string($loader) && $loader($className)) { // "MyClass::loadClass"
return true;
}
+ if (class_exists($className, false) || interface_exists($className, false)) {
+ return true;
+ }
}
- return class_exists($className, false) || interface_exists($className, false);
+ return false;
}
/**
View
19 tests/Doctrine/Tests/Common/ClassLoaderTest.php
@@ -33,7 +33,26 @@ public function testClassExists()
$this->assertTrue(ClassLoader::classExists('ClassLoaderTest\ClassD'));
spl_autoload_unregister($badLoader);
}
+
+ public function testClassExistsWithMultipleNonReturningAutoloaders()
+ {
+ $this->assertFalse(ClassLoader::classExists('ClassLoaderTest\ClassE'));
+ $nonReturnLoader = function($className) {
+ if (class_exists($className, false)) {
+ \PHPUnit_Framework_Assert::fail('Class load called twice for same class.');
+ }
+ require __DIR__ . '/ClassLoaderTest/ClassE.php';
+ };
+ $nonReturnLoader2 = clone $nonReturnLoader;
+ spl_autoload_register($nonReturnLoader);
+ spl_autoload_register($nonReturnLoader2);
+
+ $this->assertTrue(ClassLoader::classExists('ClassLoaderTest\ClassE'));
+ spl_autoload_unregister($nonReturnLoader);
+ spl_autoload_unregister($nonReturnLoader2);
+ }
+
public function testGetClassLoader()
{
$cl = new ClassLoader('ClassLoaderTest', __DIR__);
View
5 tests/Doctrine/Tests/Common/ClassLoaderTest/ClassE.php
@@ -0,0 +1,5 @@
+<?php
+
+namespace ClassLoaderTest;
+
+class ClassE {}
Something went wrong with that request. Please try again.