<?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 5
INF
<?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 5
INF
很久很久以前,PHP只有Error没有Exception,PHP5才引入Exception的异常概念,可以手动throw让try/catch捕获
所以在PHP5时代,你有两个选择处理这个Warning错误
<?php
$a = 1;
$b = 0;
try{
if($b==0){
throw new Exception("手动抛出异常,0不能作为除数");
}
$result = $a / $b;
}catch(Exception $e){
var_dump($e);
}
输出结果
object(Exception)#1 (7) {
["message":protected]=>
string(40) "手动抛出异常,0不能作为除数"
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(0)
["file":protected]=>
string(28) "/Users/charles/Desktop/b.php"
["line":protected]=>
int(6)
["trace":"Exception":private]=>
array(0) {
}
["previous":"Exception":private]=>
NULL
}
而在PHP7时代,引入了全新的Throwable来处理Error和Exception,因为Error和Exception都继承自Throwable,所以Throwable终于可以同时处理错误和异常,示例代码如下
<?php
try{
$result = 1 / 0;
}catch(Throwable $t){
var_dump($t);
}
输出结果
object(DivisionByZeroError)#1 (7) {
["message":protected]=>
string(16) "Division by zero"
["string":"Error":private]=>
string(0) ""
["code":protected]=>
int(0)
["file":protected]=>
string(28) "/Users/charles/Desktop/a.php"
["line":protected]=>
int(4)
["trace":"Error":private]=>
array(0) {
}
["previous":"Error":private]=>
NULL
}
2 回答3.1k 阅读✓ 已解决
1 回答1.4k 阅读✓ 已解决
1 回答1k 阅读✓ 已解决
1 回答1.3k 阅读✓ 已解决
3 回答1.2k 阅读
2 回答1.2k 阅读
1 回答1.2k 阅读
简单的说,因为这个在这里目前是一个 Warning 而不是一个 Exception。
而 Warning 属于 Error 的一部分,虽然 PHP 7 错误处理 的介绍中提到了。
没错,只是大多数的被作为 Error 异常抛出了,但是除零这种情况并不包含在内(其实还有很多情况都不会转为异常抛出)。
其他答主已经介绍过, PHP 7 开始 Throwable 可以捕获来自 Error 的异常并进行处理。
看到上图,你应该注意到了 DivisionByZeroError 这一个属于错误下的类,但是如果你在 PHP 7 版本中运行这段代码。
你就会发现,也并没有捕获到这个异常,满头问号吧 ❓❓❓。
好吧,在 PHP 7 中,只是将
%
(取模)在模0
的时候会触发DivisionByZeroError
这个异常类。不信你把上面代码改一下。你会发现,现在就可以捕获到这个 DivisionByZeroError 异常了。
那,就没有办法来处理这个 Error 了吗?
当然可以,要在 PHP 7 及以前的版本中处理这个可以使用 set_error_handler 这个函数,来注册一个错误处理函数,这样当发生错误时,就会把错信息传递到这个函数来。
你可以在这个函数中什么也不做(那么将当作无事发生,代码将继续运行)
上面的代码则会打印:
你可以在这个处理函数中抛出一个异常,这样你就能在 catch 里面捕获到了。
上面的代码将会一次打印
但,自 PHP 8 起,PHP RFC: Reclassifying engine warnings 这个 RFC 通过后,除零也改为了抛出
DivisionByZeroError
异常,所以,自 PHP 8 开始,你就可以直接捕获到这个异常了。