anjanesh
anjanesh

Reputation: 4261

@ division by 0 returns fatal in PHP 8

In PHP 7 it returns INF which is okay but in PHP 8 onwards its returning a fatal error.

<?php
$a = 2;
$b = 0;
$c = @($a / $b);
echo $c;
echo "\n";
?>

Is there anyway to get PHP 8 return INF too ? I have a script where there are like 100 possible division by zero - I can't add 100 if conditions, I need the @ suppress to care of it.

Upvotes: 3

Views: 4277

Answers (2)

DevWL
DevWL

Reputation: 18860

This is one of the hidden braking changes if you rely on the value returned from dividing by 0.

Generally, User @Alister Bulman already gave you the answer you're looking for. But if you need a backward compatible solution, read on. It is quite important to know how division by 0 works with different PHP versions.

Consider the fallowing example:

<?php

echo "--- 2 / 0 ---". PHP_EOL;
try{
    $res = 2 / 0;
}catch(DivisionByZeroError $e){
    echo " ### Caught 2 / 0! ". $e->getMessage() . PHP_EOL;
    $res = "nothing returned - error thrown!";
}
echo "RETURNS: ";
var_dump($res);
echo " ### Continue script" . PHP_EOL;
echo PHP_EOL;

echo "--- intdiv(2, 0) ---". PHP_EOL;
try{
    $res = intdiv(2, 0);
}catch(DivisionByZeroError $e){
    echo " ### Caught intdiv(2, 0)!". $e->getMessage() . PHP_EOL;
    $res = "nothing returned - error thrown!";
}
echo "RETURNS: ";
var_dump($res);
echo " ### Continue script" . PHP_EOL;

Depending on the PHP version, it will behave and return different values. See the example below for php8, php7 and php5.

PHP8 / 0 would return (nothing - DivisionByZeroError thrown):

--- 2 / 0 ---
### Caught 2 / 0! Division by zero
RETURNS: string(32) "nothing returned - error thrown!"
### Continue script

--- intdiv(2, 0) ---
### Caught intdiv(2, 0)! Division by zero
RETURNS: string(32) "nothing returned - error thrown!"
### Continue script

PHP7 / 0 would return INF
and intdiv() return (nothing - DivisionByZeroError thrown):

--- 2 / 0 ---
Warning: Division by zero in /home/user/scripts/code.php on line 5
RETURNS: float(INF)
### Continue script

--- intdiv(2, 0) ---
### Caught intdiv(2, 0) !Division by zero
RETURNS: string(32) "nothing returned - error thrown!"
### Continue script

PHP5 / 0 would return FALSE:

--- 2 / 0 ---
Warning: Division by zero in /home/user/scripts/code.php on line 5
RETURNS: bool(false)
### Continue script

--- intdiv(2, 0) ---
Fatal error: Call to undefined function intdiv() in /home/user/scripts/code.php on line 17

So if you need to resolve the value of your division by 0 in PHP8 to INF and make it backward compatible, you would need to write custom function and assign INF value inside the catch block.

<?php

/**
 * Division returns INF when dividing by 0 
 * in PHP8, PHP7, PHP5
 * 
 * @param int | float $a number to divide
 * @param int | float $b number dividing by
 * 
 * @return int | float | INF
 */
function divide($a, $b){
    try {
        if(@($a / $b) === false) return INF; // covers PHP5
        return @($a / $b); // covers PHP7
    } catch (DivisionByZeroError $e) {
        return INF; // covers PHP8
    }
}

/* Compatible with PHP8, PHP7, PHP5 */
divide(8,2); // returns int(4)
divide(8,1.1); // returns float(7.2727272727273)
divide(8,0); // returns INF

Upvotes: 1

Alister Bulman
Alister Bulman

Reputation: 35169

<?php
try {
    echo (2 / 0);
} catch (DivisionByZeroError $e) {
    return INF;
}

Upvotes: 1

Related Questions