PHP, Как поймать деление на нуль?

У меня есть большое математическое выражение, которое должно быть создано динамично. Например, после того как я проанализировал "что-то", как что результатом будет строка: "$foo+$bar/$baz";.

Так, для вычисления результата того выражения я использую eval функционируйте... что-то вроде этого:

eval("\$result = $expresion;");
echo "The result is: $result";

Проблема здесь состоит в том, что иногда я получаю ошибки, который говорит, что было деление на нуль, и я не знаю, как поймать то Исключение. Я попробовал вещи как:

eval("try{\$result = $expresion;}catch(Exception \$e){\$result = 0;}");
echo "The result is: $result";

Или:

try{
    eval("\$result = $expresion;");
}
catch(Exception $e){
    $result = 0;
}
echo "The result is: $result";

Но это не работает. Так, как я могу избежать, что мои сбои приложения, когда существует деление на нуль?

Править:

Во-первых, я хочу разъяснить что-то: выражение создается динамично, таким образом, я не могу просто оценка, если знаменатель является нулем. Так... относительно комментария Mark Baker, позвольте мне дать Вам пример. Мой синтаксический анализатор мог создать что-то вроде этого:

"$foo + $bar * ( $baz / ( $foz - $bak ) )"

Сборка синтаксического анализатора строка шаг за шагом, не вызывая беспокойство о значении Вара... так в этом случае, если $foz == $bak существует на самом деле деление на нуль: $baz / ( 0 ).

С другой стороны, как предложенный Pete, я попробовал:

<?php
$a = 5;
$b = 0;

if(@eval(" try{ \$res = $a/$b; } catch(Exception \$e){}") === FALSE)
        $res = 0;
echo "$res\n";
?> 

Но это ничего не печатает.

28
задан Eric Leschinski 13 March 2014 в 19:01
поделиться

6 ответов

if ($baz == 0.0) {
    echo 'Divisor is 0';
} else {
    ...
}

Вместо того, чтобы использовать eval, что очень опасно, если вы используете вводимые пользователем данные в названном выражении, почему бы не использовать правильный синтаксический анализатор, такой как evalmath на PHPClasses , который вызывает чистое исключение на разделить на ноль

17
ответ дан 28 November 2019 в 03:32
поделиться

Вот еще одно решение:

<?php

function e($errno, $errstr, $errfile, $errline) {
    print "caught!\n";
}

set_error_handler('e');

eval('echo 1/0;');

См. set_error_handler ()

6
ответ дан 28 November 2019 в 03:32
поделиться
if(@eval("\$result = $expresion;")===FALSE){
  $result=0;
}

Но не будет просто уловить ошибки деления на 0.

2
ответ дан 28 November 2019 в 03:32
поделиться

Используйте @ (оператор контроля ошибок.) Это говорит php не выводить предупреждения в случае ошибок.

eval("\$result = @($expresion);");
if ($result == 0) {
    // do division by zero handling 
} else {
    // it's all good
}
0
ответ дан 28 November 2019 в 03:32
поделиться

Как уже упоминали другие, попробуйте решение, которое позволит вам проверить, равен ли знаменатель 0.

Поскольку этот совет кажется бесполезным для вашей цели, вот небольшая справочная информация по обработке ошибок PHP.

В ранних версиях PHP не было исключений. Вместо этого появлялись сообщения об ошибках различного уровня (Уведомления, предупреждения и т. Д.). Неустранимая ошибка останавливает выполнение.

PHP5 внес исключения в таблицу, а новые библиотеки, предоставляемые PHP (PDO), будут генерировать исключения, когда происходят плохие / неожиданные вещи. Однако основная кодовая база НЕ была переписана для использования исключения. Основные функции и операции по-прежнему полагаются на старую систему ошибок.

Когда вы делите на 0, вы получаете предупреждение, а не исключение

PHP Warning:  Division by zero in /foo/baz/bar/test.php(2) : eval()'d code on line 1
PHP Stack trace:
PHP   1. {main}() /foo/baz/bar/test.php:0
PHP   2. eval() /foo/baz/bar/test.php:2

Если вы хотите «поймать» их, вам нужно установить собственный обработчик ошибок , который будет определять деление на ноль ошибок и что-нибудь с ними делать. К сожалению, пользовательские обработчики ошибок - это уловка, а это значит, что вам также нужно написать код, чтобы делать что-то подходящее со всеми другими ошибками.

3
ответ дан 28 November 2019 в 03:32
поделиться

Я тоже столкнулся с этой проблемой (динамические выражения). Я так и сделал, что может быть не самым лучшим способом, но он работает. Вместо того, чтобы бросать Exception, вы, конечно, можете вернуть null или false или что угодно. Надеюсь это поможет.

function eval_expression($expression)
{
    ob_start();
    eval('echo (' .  $expression . ');');
    $result = ob_get_contents();
    ob_end_clean();
    if (strpos($result, 'Warning: Division by zero')!==false)
    {
        throw new Exception('Division by zero');
    }
    else return (float)$result;
}
2
ответ дан 28 November 2019 в 03:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: