PHP:命名空间类、类加载和异常会导致奇怪的行为


PHP: Namespaced classes, class loading and exceptions causes weird behaviour

在最近的一个项目中,我目睹了一些关于PHP异常处理的奇怪行为。情况如下:

在我的应用程序中,我使用命名空间。所有的类都在单独的源代码文件中。与此特殊情况相关的代码分布在3个类中。

最外层的类是一个分派器(或路由器),它将分派调用封装在try-catch块中。被分派的请求调用第三个类中的方法,该类运行代码(封装在try-catch块中),从而导致异常。

因为我在发生错误的类中省略了一个use Exception;语句,抛出的异常会一直流回最外层(调度程序),在那里它被捕获——这让我挠头,为什么导致错误的代码周围的捕获不起作用。

对我来说这似乎很奇怪。从逻辑上讲,PHP在这种情况下(IMO)应该抛出Class not found异常/错误,导致我的代码中出现实际错误,而不是试图尽可能长时间地"保持活力"。

这应该被归档为一个bug,还是这是预期的行为?

编辑:代码示例

File: class-a.php

<?php 
namespace hello'world;
class classA {
    protected $b;
    public function __construct() {
        $this->b = new 'hello'world'classB();
    }
    public function doSomething() {
        try {
            $this->b->throwException();
        } catch (Exception $e) {
        }
    }
}

File: class-b.php

<?php 
namespace hello'world;
class classB
{
    public function throwException() {
        throw new 'Exception("bar closed");
    }
}

文件:run.php

<?php 
include 'class-a.php';
include 'class-b.php';
$a = new 'hello'world'classA();
$a->doSomething();

类b throwClassB::doSomething()中的'Exception, ClassAcatch -子句,但由于ClassA没有声明use Exceptioncatch ('Exception),因此catch不匹配,执行以Uncaught exception错误1结束。但在我看来,它应该导致Class not found错误。

我可能对允许的PHP编译器期望过高,但它将有助于跟踪愚蠢的错误,这些错误应该很容易被编译器发现。

1如果run.php中的$a->doSomething()try..catch子句包围,那么Exception将(或至少可能)在那里被捕获,因为它沿着堆栈向下滴入。

PHP的异常捕获机制并不验证所捕获的类是否确实存在。

在函数中使用类型提示时表现出相同的行为,因此我怀疑它只是将异常/函数类型提示转换为字符串或其他东西,并将其与相关对象的类型进行比较。

这是否是一个bug是值得怀疑的。我个人认为它应该被归类为bug,但是PHP有各种各样的不稳定行为:D