我正在为类加载器编写一些单元测试,第一个测试是断言尝试引用类而不先加载它确实会失败。
测试如下:
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testInstantiateUnloadedClass() {
$foo = new Foo();
}
可悲的是,运行测试会产生以下消息:
PHP致命错误:第7行的/Users/jfvaren/workspace/classloader/ClassLoaderTest.php中找不到类'Foo'
我必须接受这是不可行的吗?
答案 0 :(得分:4)
调用class_exists(),这会尝试自动加载类,如果不能,则返回布尔值假。
答案 1 :(得分:2)
要测试该类是否已被实例化,您可以简单地执行以下操作:
try {
if( !class_exists( "Foo" ) )
throw new Exception( "Foo does not exist." );
}catch( Exception $e ){
$e->showMessage();
}
此外,如果要在实际引用时测试它是否存在(并且您不想先执行class_exists),则可以在AutoLoader中执行此操作。我在下面列出了更多内容,以及一个示例模具声明。
有关AutoLoader的说明
现在,可能是偏离主题的,如果你想能够动态地包含一个类而不明确地引用它,你可以通过实例化一个AutoLoader。引用类时,AutoLoaders会查找类文件,然后在尝试使用它之前将其包含在内。
因此,例如,您需要在Test.php文件中包含AutoLoader.php,以及使用该类的所有其他文件。然后,该文件将根据需要包含其他文件。
为此,您需要设置AutoLoader.php文件。它需要看起来像这样:
// This tells PHP what to use to load the functions
ini_set( 'unserialize_callback_func', '__autoload' );
// Create an array pairing class names to their file include path
$myClasses = array( "Foo" => "Foo.php", "Bar" => "Bar.php" );
class AutoLoader {
static function autoload( $class ){
if( !in_array( $class, $myClasses ) )
die( "The class {$class} doesn't exist!" );
require( $myClasses[$class] );
}
}
if( function_exists( 'spl_autoload_register' ) ) {
spl_autoload_register( array( 'AutoLoader', 'autoload' ) );
} else {
function __autoload( $className ){
# When called, load a previously unloaded class
AutoLoader::autoload( $className );
}
}
答案 2 :(得分:1)
似乎无法捕捉致命错误。因此,不要在__autoload中使用require,而是可以使用include with if语句并生成特定的异常。