当我的__autoload()函数加载文件失败时试图实现某种错误处理我偶然发现了这个小小的“怪异”。__autoload无法在静态方法调用中加载类时抛出异常
根据http://nl.php.net/autoload从PHP 5.3+版本开始,在__autoload()函数中抛出的异常可以在catch块中捕获。
Note: Prior to 5.3.0, exceptions thrown in the __autoload function could not be caught in the catch block and would result in a fatal error. From 5.3.0+ exceptions thrown in the __autoload function can be caught in the catch block, with 1 provision. If throwing a custom exception, then the custom exception class must be available. The __autoload function may be used recursively to autoload the custom exception class.
这对我所考虑的错误处理类型来说是完美的。就像我想让它下面的作品的例子(它抛出一个异常,它抓住了):
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被捕获也是有趣的,因为它似乎是在Exception被处理之前发生的致命错误,如果它甚至被抛在第一位。
我认为第一个例子的工作原理是因为你实例化了一个新对象,'__autoload()'触发了一个新的实例,同时在第二个例子中你调用了一个类的静态方法,没有对象被实例化,所以'__autoload ()'不被调用。 – Galled
@Galled如果我添加'echo $ class;'在我的__autoload()函数中。它会输出2次UndefinedClass,验证是否调用了__autoload(),但在第二种情况下不引发Exception。 – Willem
你得到的致命错误是什么? – Galled