PHP Попробуйте проблему catch [duplicate]

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

12 ответов

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

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

16
ответ дан nyuszika7h 19 August 2018 в 05:51
поделиться
  • 1
    Нет ... как я сказал, выражение построено динамически. Если бы это было статическое выражение, это было бы очень просто, но это не так. – Cristian 18 June 2010 в 16:46
  • 2
    Как он построен динамически? Он должен быть "построен" каким-то образом вашим «парсером» ... и в этот момент вы сможете определить, равен ли делитель 0 или нет! – Mark Baker 18 June 2010 в 16:49
  • 3
    Это должно работать, если вы замените $ baz на eval (& quot; \ $ result = $ baz; & quot;), а затем проверьте, что результат $ равен 0 или нет. – vad 18 June 2010 в 16:55
  • 4
    @Mark Я обновил сообщение с дополнительной информацией, которая отвечает на ваш вопрос. Спасибо за вашу помощь. – Cristian 18 June 2010 в 16:55
  • 5
    Добавлена ​​ссылка на класс оценки, который может сэкономить вам много горя в будущем. – Mark Baker 18 June 2010 в 17:03

Как уже упоминалось, рассмотрите попытку решения, которое позволит вам проверить, равен ли знаменатель 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
ответ дан Alan Storm 19 August 2018 в 05:51
поделиться
  • 1
    Я получаю Fatal Error с PHP 5.6. Не предупреждение. – MightyPork 20 October 2015 в 16:49
  • 2
    неважно, что это была моя Framework, делающая что-то действительно заторможенное с помощью set_error_handler () – MightyPork 20 October 2015 в 16:57

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

<?php

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

set_error_handler('e');

eval('echo 1/0;');

См. set_error_handler()

6
ответ дан Bill Karwin 19 August 2018 в 05:51
поделиться
  • 1
    & quot; Невозможно уловить ошибку синтаксического анализа в eval () с помощью set_error_handler () & quot; php.net/manual/en/function.eval.php – Pete 18 June 2010 в 16:56
  • 2
    @Pete: Правильно, но ОП спрашивал о делении на нулевые ошибки, а не на синтаксические ошибки. Я протестировал вышеуказанный скрипт и поймал ошибку. – Bill Karwin 18 June 2010 в 17:04

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

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
ответ дан Christopher Fox 19 August 2018 в 05:51
поделиться

На PHP7 вы можете использовать DivisionByZeroError

try {
    echo 1/0;
}
catch(DivisionByZeroError $e){
    echo "got $e";
}
2
ответ дан David L 19 August 2018 в 05:51
поделиться
  • 1
    Я согласен, если вы используете PHP & gt; = 7, это более чистый способ его поймать. – Nicolas Talichet 29 June 2018 в 02:03
  • 2
    Это по существу повторяет ответ @ simpod . – faintsignal 13 July 2018 в 19:32

В качестве входных данных передается строка, содержащая числа и математические операторы + - * /. Программа должна оценивать значение выражения (в соответствии с BODMAS) и печатать выходные данные.

Пример Ввод / вывод: если аргумент равен «7 + 4 * 5», выход должен быть 27. Если аргумент «55 + 21 * 11 - 6/0», выход должен быть «ошибкой» (поскольку деление на ноль не определено).

0
ответ дан dinesh 19 August 2018 в 05:51
поделиться

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

eval("\$result = @($expresion);");
if ($result == 0) {
    // do division by zero handling 
} else {
    // it's all good
}
0
ответ дан ghoppe 19 August 2018 в 05:51
поделиться
  • 1
    Не хорошо. Что делать, если $expression = "0 / 5"? Тогда у вас есть ложный позитив. – Christian Mann 5 November 2010 в 23:18
  • 2
    Деление на ноль фактически возвращает false, а не 0. Попробуйте $result === false. – Hubro 11 August 2013 в 08:15

Я тоже борется с этим, решения set_error_handler не работали для меня, возможно, на основе различий в версии PHP.

Решение для меня заключалось в попытке обнаружить ошибку при выключении :

// Since set_error_handler doesn't catch Fatal errors, we do this
function shutdown()
{
    $lastError = error_get_last();
    if (!empty($lastError)) {
        $GLOBALS['logger']->debug(null, $lastError);
    }
}
register_shutdown_function('shutdown');

Я не уверен, почему деление на 0 выключается, а не обрабатывается set_error_handler, но это помогло мне выйти за пределы этого, просто молча умер.

0
ответ дан justin.m.chase 19 August 2018 в 05:51
поделиться
if(@eval("\$result = $expresion;")===FALSE){
  $result=0;
}

Не поймает деление на 0 ошибок.

2
ответ дан Pete 19 August 2018 в 05:51
поделиться
  • 1
    +1, но вместо $ result = 0; используйте $ result = "# error", или генерируйте исключение. – ern0 2 May 2011 в 07:40
  • 2
    eval - зло! Пожалуйста, НЕ используйте – Eddie Jaoude 26 April 2015 в 09:16

Вы можете просто поймать DivisionByZeroError в PHP> = 7

См. http://php.net/manual/en/class.divisionbyzeroerror.php

1
ответ дан simPod 19 August 2018 в 05:51
поделиться

Вам просто нужно установить обработчик ошибок для исключения исключения в случае ошибок:

set_error_handler(function () {
    throw new Exception('Ach!');
});

try {
    $result = 4 / 0;
} catch( Exception $e ){
    echo "Divide by zero, I don't fear you!".PHP_EOL;
    $result = 0;
}

restore_error_handler();
4
ответ дан tacone 19 August 2018 в 05:51
поделиться

Проблема:

b=1; c=0; a=b/c; // Error Divide by zero

Решение простое:

if(c!=0) a=b/c;
else // error handling
0
ответ дан user3557421 19 August 2018 в 05:51
поделиться
Другие вопросы по тегам:

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