当无法在静态方法调用上加载类时,__ autoload无法引发异常 [英] __autoload fails to throw an Exception when it fails to load a class on a static method call

查看:113
本文介绍了当无法在静态方法调用上加载类时,__ autoload无法引发异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当__autoload()函数无法加载文件时尝试实现某种错误处理时,我偶然发现了这个小奇怪之处。



a href = http://nl.php.net/autoload rel = nofollow> http://nl.php.net/autoload __autoload()函数中引发的异常可以捕获自PHP版本5.3+起一个catch块。


注意:
在5.3.0之前,__ autoload函数中引发的异常可能不会被捕获到捕获块中,并可能导致致命错误。从5.3.0+起,__autoload函数中引发的异常可以在catch块中捕获,有1个配置。如果抛出自定义异常,则自定义异常类必须可用。可以递归使用__autoload函数自动加载自定义异常类。


这非常适合我所想到的错误处理类型。下面的示例就像我想要的那样工作(它引发异常并被捕获):

  function __autoload($ class) {
抛出new Exception();
}

试试{
new UndefinedClass();
}
catch(Exception $ e){
回声该死,没有用!
}

输出:该死,没有用! / p>

但是,如果我尝试通过未定义类的静态方法调用相同的概念,则不会引发异常,而是会引发致命错误。

  try {
$ a = UndefinedClass :: someRandomStaticMethod();
}
catch(Exception $ e){
echo‘meh,it work!’;
}

输出:致命错误:类'UndefinedClass'在第16行的 * ** * * 中找不到



上面的代码起作用。没有抛出异常。 (使用相同的__autoload()函数)。



http: //nl.php.net/autoload 对此用例没有提及,这让我想知道我在这里是否做错了什么?如何使我的__autoload()函数在不存在的类的静态方法调用上引发异常?



如果使用__autoload()函数根本无法做到这一点, spl_autoload()是否允许这种异常抛出?






@Galled



根据您提供的链接,我将__autoload()函数更改为:

 功能__autoload($ class){
eval('
class'。$ class。'{
};
');
抛出新异常(我是异常!);
}

使用此版本,存在问题的致命错误不再反馈给我的监视器。但是,它现在将给我带来另一个致命错误:someRandomStaticMethod()不存在。



我当然可以包括方法的声明在eval()调用中。但这不是可行的解决方案,因为我必须重新声明我的项目在__autoload()函数中包含的每个类,以便能够避免上述致命错误。知道没有捕获到任何异常也很有趣,因为致命的错误似乎是在处理异常之前发生的,即使它一开始就被抛出。

解决方案

我通过扩展Galled的建议来设法解决了这个问题。经过更多阅读后,尤其是在这里: http:// nl .php.net / manual / en / function.spl-autoload-register.php#84086 我写了以下内容。

  function __autoload($ class){

...

/ *如果某事和/或一切失败* /
eval('
class'。$ class。'{

公共函数__construct(){
抛出new Exception(\'Im an Exception!\');
}

公共静态函数__callstatic($ method,$ arguments){
throw new Exception(\Im an Exception!\');
}

};
');
}

此变化现在将引发例外在两个用例上。



尽管上述方法可行,但我希望有人能提供一种不会触及 eval()函数。因为某种原因,我觉得我只是在调侃PHP。


While attempting to implement some kind of error handling when my __autoload() function fails to load a file I stumbled upon this little 'oddity'.

According to http://nl.php.net/autoload Exceptions thrown from within the __autoload() function can be caught in a catch block since PHP version 5.3+.

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.

This works perfectly for the type of error handling I had in mind. The example below works just like I want it to (It throws an exception and it's caught):

function __autoload($class) {
    throw new Exception();
}

try {
    new UndefinedClass();
}
catch (Exception $e) {
    echo 'damnit, it no work!';
}

Output: damnit, it no work!

If however I try the same concept with a static method call from a undefined class, Exceptions are not thrown, instead I get fed a fatal error.

try {
    $a = UndefinedClass::someRandomStaticMethod();
}
catch (Exception $e) {
    echo 'meh, it no work!';
}

Output: Fatal error: Class 'UndefinedClass' not found in ***** on line 16

The code above does not work. No Exception is thrown. ( same __autoload() function is used ).

http://nl.php.net/autoload mentions nothing about this usecase and this leaves me wondering if I'm doing something terribly wrong here? How can I make my __autoload() function throw exceptions on static method calls of a non-existent class?

If this is simply not possible with the __autoload() function, does spl_autoload() allow this kind of Exception throwing?


@Galled

Based on the link you provided I changed the __autoload() function to this:

function __autoload($class) {
    eval('
            class ' . $class . ' {
            };
        ');
    throw new Exception('Im an Exception!');
}

Using this version the fatal error in question is no longer fed to my monitor. However, it will now feed me with a different fatal error: the fact that the someRandomStaticMethod() doesn't exist.

I could of course include the declaration of the method within the eval() call. But this is not workable solution, as I would have to redeclare every class my project contains within the __autoload() function just to be able to avoid said fatal error. It's also interesting to know that no Exception is caught, as it seems the fatal error occurs before the Exception is handled, if it is even thrown in the first place.

解决方案

I somewhat managed to solve the problem by expanding on the suggestions from Galled. After some more reading, especially here: http://nl.php.net/manual/en/function.spl-autoload-register.php#84086 I wrote the following.

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!\');
                }

            };
        ');
}

This variation will now throw Exceptions on both use-cases. regardless on the existence of methods within a class.

While the above works, I'm hoping someone can provide a solution that doesn't touch the eval() function. As, for some reason, I feel like I just molested PHP.

这篇关于当无法在静态方法调用上加载类时,__ autoload无法引发异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆