当__autoload无法在静态方法调用上加载类时,它无法抛出异常

时间:2011-11-21 14:35:14

标签: php exception autoload

当我的__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之前似乎发生致命错误,如果它甚至被抛出则首先出现。

1 个答案:

答案 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。