请问php异常处理为何无效 `Warning: Division by zero`?
<?php
$a = 1;
$b =0;
try{
echo $a/$b;
}catch(Exception $e){
echo '发送错误:被除数不能为0';
}
输出结果如下
Warning: Division by zero in D:\phpstudy_pro\WWW\demo.php on line 5INF
回复
1个回答

test
2024-06-28
简单的说,因为这个在这里目前是一个 Warning 而不是一个 Exception。
而 Warning 属于 Error 的一部分,虽然 PHP 7 错误处理 的介绍中提到了。
PHP 7 改变了大多数错误的报告方式。不同于传统(PHP 5)的错误报告机制,现在大多数错误被作为 Error 异常抛出。
没错,只是大多数的被作为 Error 异常抛出了,但是除零这种情况并不包含在内(其实还有很多情况都不会转为异常抛出)。
其他答主已经介绍过, PHP 7 开始 Throwable 可以捕获来自 Error 的异常并进行处理。
看到上图,你应该注意到了 DivisionByZeroError 这一个属于错误下的类,但是如果你在 PHP 7 版本中运行这段代码。
<?php
try{
$result = 1 / 0;
}catch(Throwable $t){
var_dump($t);
}
你就会发现,也并没有捕获到这个异常,满头问号吧 ❓❓❓。
好吧,在 PHP 7 中,只是将 %
(取模)在模 0
的时候会触发 DivisionByZeroError
这个异常类。不信你把上面代码改一下。
<?php
try{
$result = 1 % 0;
}catch(Throwable $t){
var_dump($t);
}
你会发现,现在就可以捕获到这个 DivisionByZeroError 异常了。
那,就没有办法来处理这个 Error 了吗?
当然可以,要在 PHP 7 及以前的版本中处理这个可以使用 set_error_handler 这个函数,来注册一个错误处理函数,这样当发生错误时,就会把错信息传递到这个函数来。
你可以在这个函数中什么也不做(那么将当作无事发生,代码将继续运行)
<?php
set_error_handler(function () {
var_dump('发生错误啦!');
});
try {
$result = 1 / 0;
var_dump('我会显示。');
} catch (Throwable $t) {
var_dump('我不会显示。');
}
var_dump('可以运行到这里喔');
上面的代码则会打印:
发生错误啦!
我会显示。
可以运行到这里喔!
你可以在这个处理函数中抛出一个异常,这样你就能在 catch 里面捕获到了。
<?php
set_error_handler(function ($code, $msg) {
throw new DivisionByZeroError($msg, $code);
});
try {
$result = 1 / 0;
var_dump('我不会显示!');
} catch (Throwable $t) {
var_dump('捕获到啦!');
}
var_dump('我会显示!');
上面的代码将会一次打印
捕获到啦!
我会显示!
但,自 PHP 8 起,PHP RFC: Reclassifying engine warnings 这个 RFC 通过后,除零也改为了抛出 DivisionByZeroError
异常,所以,自 PHP 8 开始,你就可以直接捕获到这个异常了。
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容