Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/245.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php __当autoload无法在静态方法调用上加载类时,它无法引发异常_Php_Exception_Autoload - Fatal编程技术网

Php __当autoload无法在静态方法调用上加载类时,它无法引发异常

Php __当autoload无法在静态方法调用上加载类时,它无法引发异常,php,exception,autoload,Php,Exception,Autoload,当我试图在我的_autoload()函数无法加载文件时实现某种错误处理时,我偶然发现了这个小小的“奇怪之处” 根据PHP版本5.3+以来从_autoload()函数中抛出的异常可以在catch块中捕获 注: 在5.3.0之前,无法在catch块中捕获uu autoload函数中抛出的异常,这将导致致命错误。从5.3.0开始,_autoload函数中抛出的+异常可以在catch块中捕获,具有1个规定。如果引发自定义异常,则自定义异常类必须可用。_u_autoload函数可以递归地用于自动加载自定义

当我试图在我的_autoload()函数无法加载文件时实现某种错误处理时,我偶然发现了这个小小的“奇怪之处”

根据PHP版本5.3+以来从_autoload()函数中抛出的异常可以在catch块中捕获

注: 在5.3.0之前,无法在catch块中捕获uu autoload函数中抛出的异常,这将导致致命错误。从5.3.0开始,_autoload函数中抛出的+异常可以在catch块中捕获,具有1个规定。如果引发自定义异常,则自定义异常类必须可用。_u_autoload函数可以递归地用于自动加载自定义异常类

这非常适合我所想到的错误处理类型。下面的示例的工作原理与我所希望的一样(它抛出一个异常,然后被捕获):

输出:该死,没用

但是,如果我尝试从未定义的类调用静态方法时使用相同的概念,则不会抛出异常,而是会收到致命错误

try {
    $a = UndefinedClass::someRandomStaticMethod();
}
catch (Exception $e) {
    echo 'meh, it no work!';
}
输出:致命错误:在第16行的***中未找到类“UndefinedClass”

上述代码不起作用。没有抛出异常。(使用相同的自动加载()函数)

没有提到这个用例,这让我怀疑我是否在做一些非常错误的事情?如何使我的uu autoload()函数对不存在的类的静态方法调用抛出异常

如果使用uu autoload()函数无法实现这一点,那么spl_autoload()是否允许此类异常抛出


@Galled

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

function __autoload($class) {
    eval('
            class ' . $class . ' {
            };
        ');
    throw new Exception('Im an Exception!');
}
使用此版本,问题中的致命错误不再反馈到我的监视器。但是,它现在会给我一个不同的致命错误:someRandomStaticMethod()不存在


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

我通过扩展Galled的建议,设法解决了这个问题。经过一些阅读,特别是在这里:我写了以下

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

            };
        ');
}
这个变体现在将在两个用例上抛出
异常
。不管类中是否存在方法


虽然上述方法有效,但我希望有人能提供一个不涉及
eval()
函数的解决方案。由于某种原因,我觉得我只是在骚扰PHP。

通过扩展Galled的建议,我多少解决了这个问题。经过一些阅读,特别是在这里:我写了以下

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

            };
        ');
}
这个变体现在将在两个用例上抛出
异常
。不管类中是否存在方法


虽然上述方法有效,但我希望有人能提供一个不涉及
eval()
函数的解决方案。由于某种原因,我觉得我只是在骚扰PHP。

我认为第一个示例是有效的,因为您实例化了一个新对象,并且
\uu autoload()
触发了一个新实例,而在第二个示例中,您调用了一个类的静态方法,并且没有对象实例化,所以
\uu autoload()
未被调用。@如果我添加“echo$class;”将被删除在my _autoload()函数中。它将输出UndefinedClass 2次,验证是否调用了uu autoload(),但是在第二种情况下不会引发异常。那么您会遇到什么致命错误?
致命错误:在使用静态方法调用时,在第16行的**********中找不到类“UndefinedClass”。您是否查看了
\u autoload-Exception
的方法?我认为第一个示例之所以有效,是因为您实例化了一个新对象,并且
\uuuu autoload()
使用一个新实例触发,同时在第二个示例中,您正在调用一个类的静态方法,并且没有对象被实例化,因此不会调用
\uuuu autoload()
。@Galled如果我添加了'echo$class;'在my _autoload()函数中。它将输出UndefinedClass 2次,验证是否调用了uu autoload(),但是在第二种情况下没有抛出异常。那么您得到的致命错误是什么?
致命错误:在使用静态方法调用时,在第16行的*************中找不到类“UndefinedClass”。您是否查看了
\u autoload-Exception
的方法?这对我来说似乎非常棘手,如果您的项目跨越几十个左右的类,那么在自动加载程序中使用eval将真正影响应用程序的性能。我建议找到一种方法来减少或消除静态方法的使用。或者干脆放弃在自动加载器中抛出异常。我不认为这是推荐的。Willem,你能解释一下这是否真的损害了应用程序的性能吗?我不这么认为,因为eval()只是偶尔被调用。。。我仍然认为这是一个非常糟糕的攻击,但似乎没有其他选择…@Lex虽然我还没有实际测试此实现的性能影响,但我怀疑它是否会对性能产生任何影响,eval+异常抛出应该只在应用程序的php文件因某种原因被破坏时发生,这是不应该发生的。这个实现只是一个安全网,非常罕见地允许你的应用程序在用户眼中优雅地“消亡”。不,到目前为止我还没有找到一个可行的替代方案。这对我来说真的很难,而且有一个