在最近的一个项目中,我目睹了一些关于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 throw
是ClassB::doSomething()
中的'Exception
, ClassA
有catch
-子句,但由于ClassA
没有声明use Exception
或catch ('Exception)
,因此catch
不匹配,执行以Uncaught exception
错误1结束。但在我看来,它应该导致Class not found
错误。
我可能对允许的PHP编译器期望过高,但它将有助于跟踪愚蠢的错误,这些错误应该很容易被编译器发现。
1如果run.php
中的$a->doSomething()
被try..catch
子句包围,那么Exception
将(或至少可能)在那里被捕获,因为它沿着堆栈向下滴入。
PHP的异常捕获机制并不验证所捕获的类是否确实存在。
在函数中使用类型提示时表现出相同的行为,因此我怀疑它只是将异常/函数类型提示转换为字符串或其他东西,并将其与相关对象的类型进行比较。
这是否是一个bug是值得怀疑的。我个人认为它应该被归类为bug,但是PHP有各种各样的不稳定行为:D