我目前正在尝试理解PHP 7中新错误处理的行为。
在DivisionByZeroError
的PHP文档中,它声明:
尝试分割a时抛出DivisionByZeroError 数字为零。
足够公平,但在使用/运算符时它不会抛出DivisionByZeroError。
在这个例子中,我希望能捕获到两个错误:
declare(strict_types=1);
function usesIntDiv(int $a, int $b) {
return intdiv($a,$b);
}
function divide(int $a, int $b) {
return $a / $b;
}
try {
echo usesIntDiv(2,0);
} catch (DivisionByZeroError $e) {
echo "Caught DivisionByZeroError!\n";
}
echo "\n";
try {
echo divide(2,0);
} catch (DivisionByZeroError $e) {
echo "Caught DivisionByZeroError!\n";
}
而只是抓住了第一个:
抓住了DivisionByZeroError!
PHP警告:在第9行的TypeError.php中除以零...
为什么呢?还有其他这样的情况吗?我的理解是,如果你捕获Throwable
,你将捕获任何可以引发的东西,这将使PHP错误处理更易于管理。但在这种情况下,如果我使用/
运算符,那就是无法捕获的PHP警告。
这是否特定于此错误(可能是因为它是由操作员触发的),还是我误解了错误处理的变化?
答案 0 :(得分:1)
使用算术运算符/
不会在php 7中引发异常,而在php 8中会引发异常。
<?php
try {
echo intdiv(2, 0);
} catch (DivisionByZeroError $e) {
echo "caught division by zero for intdiv()\n";
}
try {
echo (2 / 0);
} catch (DivisionByZeroError $e) {
echo "caught division by zero for /\n";
}
# php 7
$ php test.php
caught division by zero for intdiv()
PHP Warning: Division by zero in test.php on line 10
PHP Stack trace:
PHP 1. {main}() test.php:0
Warning: Division by zero in test.php on line 10
Call Stack:
0.0740 417272 1. {main}() test.php:0
# php 8
$ php test.php
caught division by zero for intdiv()
caught division by zero for /
答案 1 :(得分:0)
我不认为这样做是为了向后兼容。相反,我觉得它是通过这种方式实现的,以便与其他语言保持一致:除法运算符符合浮点除法的IEEE-754 definition。 circumstance在一个且只有一个的情况下将执行整数除法,等效于intdiv
:
除法运算符(“ /”)会返回浮点值,除非两个操作数是整数(或转换为整数的字符串)并且数字可以被整除,在这种情况下,将返回整数值。有关整数除法,请参见intdiv()。
重要的是,并且仅在执行 integer 除法时,DivisionByZeroError doc中没有提到它。如果开发人员打算进行整数除法,则需要使用intdiv
或%
。否则,开发人员仍必须检查股息是否接近零,并进行相应处理(所有其他浮点操作都是这种情况)。
从这个问题尚不清楚Throwable
发生了什么问题,但是Throwable
确实抓住了DivisionByZeroError
:
try {
intdiv(2, 0);
} catch (\Throwable $t) {
echo 'caught' . PHP_EOL;
}
但是,它不会被警告警告除以零,恰恰是因为这是一个警告,而不是例外。