【发布时间】:2011-11-21 14:35:13
【问题描述】:
当我的 __autoload() 函数无法加载文件时尝试执行某种错误处理时,我偶然发现了这个小“怪事”。
根据http://nl.php.net/autoload,从 PHP 5.3+ 版本开始,从 __autoload() 函数中抛出的异常可以在 catch 块中捕获。
注意: 在 5.3.0 之前,在 __autoload 函数中抛出的异常无法在 catch 块中捕获,并会导致致命错误。从 5.3.0+ 开始,在 __autoload 函数中抛出的异常可以在 catch 块中捕获,有 1 个规定。如果抛出自定义异常,则自定义异常类必须可用。 __autoload 函数可用于递归地自动加载自定义异常类。
这非常适合我想到的错误处理类型。下面的例子就像我想要的那样工作(它抛出一个异常并被捕获):
function __autoload($class) {
throw new Exception();
}
try {
new UndefinedClass();
}
catch (Exception $e) {
echo 'damnit, it no work!';
}
输出:该死,没用!
但是,如果我使用未定义类的静态方法调用尝试相同的概念,则不会引发异常,而是会收到致命错误。
try {
$a = UndefinedClass::someRandomStaticMethod();
}
catch (Exception $e) {
echo 'meh, it no work!';
}
输出: 致命错误:在线 ***** 中找不到类“UndefinedClass” 16
上面的代码不起作用。不抛出异常。 (使用相同的 __autoload() 函数)。
http://nl.php.net/autoload 没有提到这个用例,这让我想知道我是否在这里做错了什么?如何让我的 __autoload() 函数在不存在的类的静态方法调用上引发异常?
如果 __autoload() 函数根本无法做到这一点,那么 spl_autoload() 是否允许这种异常抛出?
@Galled
根据您提供的链接,我将 __autoload() 函数更改为:
function __autoload($class) {
eval('
class ' . $class . ' {
};
');
throw new Exception('Im an Exception!');
}
使用此版本时,我的显示器不再会出现有问题的致命错误。但是,它现在会给我一个不同的致命错误:someRandomStaticMethod() 不存在这一事实。
我当然可以在 eval() 调用中包含方法的声明。但这不是可行的解决方案,因为我必须重新声明我的项目在 __autoload() 函数中包含的每个类,才能避免上述致命错误。知道没有捕获到任何异常也很有趣,因为它似乎在处理异常之前发生了致命错误,如果它甚至首先被抛出的话。
【问题讨论】:
-
我认为第一个示例有效,因为您实例化了一个新对象,
__autoload()触发了一个新实例,同时在第二个示例中,您正在调用类的静态方法并且没有实例化对象所以__autoload()不会被调用。 -
@Galled 如果我添加 'echo $class;'在我的 __autoload() 函数中。会输出UndefinedClass 2次,验证调用了__autoload(),但是第二种情况没有抛出异常。
-
你得到的致命错误是什么?
-
Fatal error: Class 'UndefinedClass' not found in ************* on line 16使用静态方法调用时。 -
你复习过this
__autoload-exception的方法吗??