PHP 7不一致地抛出错误

PHP 7 inconsistently throwing errors

我目前正在尝试理解PHP 7中新错误处理的行为。

DivisionByZeroError的PHP文档中,它指出:

DivisionByZeroError is thrown when an attempt is made to divide a
number by zero.

很公平,但是当使用/运算符时它不会抛出DivisionByZeroError。

在这个例子中,我希望捕获两个错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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!
"
;
}

echo"
"
;

try {
    echo divide(2,0);
} catch (DivisionByZeroError $e) {
    echo"Caught DivisionByZeroError!
"
;
}

相反,只有第一个被捕获:

Caught DivisionByZeroError!

PHP Warning: Division by zero in TypeError.php on line 9...

为什么? 还有其他这样的情况吗? 我的理解是,如果你捕获Throwable,你将捕获任何可以引发的东西,这将使PHP错误处理更易于管理。 但在这种情况下,如果我使用/运算符,那就是无法捕获的PHP警告。

这是否特定于此错误(可能是因为它是由操作员触发的),还是我误解了错误处理的变化?


我不认为这是向后兼容的方式。 相反,我觉得它是以这种方式实现的,以便与其他语言保持一致:除法运算符符合IEEE-754浮点除法的定义。 在一个且只有一个情况下,它将执行整数除法,相当于intdiv

The division operator ("/") returns a float value unless the two operands are integers (or strings that get converted to integers) and the numbers are evenly divisible, in which case an integer value will be returned. For integer division, see intdiv().

重要的是,在DivisionByZeroError文档中遗憾地没有提到,它是仅在执行整数除法时引发的。 如果开发人员打算进行整数除法,则需要调用intdiv%。 否则,开发人员仍必须检查近乎零条件的股息并进行相应处理(如所有其他浮点操作的情况)。

从问题不清楚Throwable出现了什么问题,但Throwable确实捕获了DivisionByZeroError

1
2
3
4
5
try {                                                                            
    intdiv(2, 0);                                                                
} catch (\Throwable $t) {                                                        
    echo 'caught' . PHP_EOL;                                                    
}

然而,它不会通过零警告来捕捉除法,正是因为它是一个警告而不是例外。