当我的__autoload()函数无法加载文件时,尝试实现某种错误处理时,我偶然发现了这个“古怪”。
根据http://nl.php.net/autoload自PHP版本5.3 +以来,__ autoload()函数内引发的异常可以在catch块中捕获。
注意: 在5.3.0之前,__ autoload函数中抛出的异常无法在catch块中捕获,并且会导致致命错误。从5.3.0+中可以在catch块中捕获__autoload函数中抛出的异常,并提供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()函数中包含的每个类,以便能够避免所述致命错误。知道没有异常被捕获也很有趣,因为在处理Exception之前似乎发生致命错误,如果它甚至被抛出则首先出现。
答案 0 :(得分:1)
我有点设法通过扩展Galled的建议来解决问题。经过一些阅读,特别是在这里:http://nl.php.net/manual/en/function.spl-autoload-register.php#84086我写了以下内容。
function __autoload($class) {
...
/* if something and/or everything fails */
eval('
class ' . $class . ' {
public function __construct() {
throw new Exception(\'Im an Exception!\');
}
public static function __callstatic($method, $arguments) {
throw new Exception(\'Im an Exception!\');
}
};
');
}
此变体现在会在两个用例上抛出Exceptions
。无论一个类中是否存在方法。
虽然上述工作正常,但我希望有人可以提供一个不触及eval()
功能的解决方案。因为某些原因,我觉得我只是骚扰PHP。