Блок Try / Catch в PHP не перехватывает исключение - PullRequest
82 голосов
/ 31 января 2010

Я пытаюсь запустить этот пример № 1 с этой страницы: http://php.net/manual/en/language.exceptions.php

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    return 1/$x;
}
try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}
// Continue execution
echo "Hello World\n";
?>

Однако вместо желаемого результата я получаю:

0.2
Fatal error: Uncaught exception 'Exception' with message 'Division by zero.' 
in xxx:
7 Stack trace: #0 xxx(14): inverse(0) #1 {main} thrown in xxx on line 7

Я использую среду разработчика UniServer 3.5 с PHP 5.2.3

Ответы [ 9 ]

196 голосов
/ 25 октября 2011

У меня была именно эта проблема, когда казалось, что я даже скопировал название исключения, и все же он не уловил его. Оказалось, что это была моя глупая ошибка, но я решил опубликовать здесь свое дело на случай, если кто-то еще окажется в такой же ситуации.

В моем пространстве имен было мое исключение A , а сценарий находился в пространстве имен B . Проблема заключалась в том, что у меня было A \ MyException , что равно (в PHP) \ B \ A \ MyException (потому что мой скрипт находится в пространстве имен с именем B ! ). Все, что мне нужно было сделать, чтобы это исправить, это добавить обратную косую черту (или как она там называется) к имени исключения, чтобы оно выглядело так: \ A \ MyException

48 голосов
/ 10 декабря 2015

Довольно старый вопрос, но ...

У меня тоже была эта проблема (и вот как я нашел этот пост), но простой эксперимент позволил мне найти решение. Просто попробуйте изменить Exception на \Exception. Работал на меня!

EDIT:

Как указал Сиванн в комментариях, использование пространства имен должно делать то же самое. Поэтому просто поставьте use \Exception as Exception; перед объявлением класса.

26 голосов
/ 20 апреля 2017

Попробуйте поставить catch(\Exception $e) вместо catch(Exception $e). Если вы используете код, о котором вы не очень хорошо знаете, или - особенно - если вы используете фреймворк, он может переопределить исключение PHP по умолчанию одним из его собственных, и поэтому вы можете пойти по неверному пути и получить нежелательный результат. Если вы просто поместите \Exception, то вы наверняка поймаете базовое исключение PHP.

20 голосов
/ 29 октября 2011

Вы не можете использовать типичные блоки try {} catch {} в PHP, как вы могли бы использовать на другом языке, например C # (Csharp).

Если вы сделаете это:

try{
    //division by zero
    $number = 5/0;
}
catch(Exception $ex){
    echo 'Got it!';
}

Вы не увидите «Понял!» сообщение никогда. Зачем? Это просто потому, что PHP всегда нужно исключение, чтобы быть "брошенным". Вам нужно установить свой собственный обработчик ошибок и выдать ему исключение.

См. set_error_handler Функция: http://php.net/manual/es/function.set-error-handler.php

5 голосов
/ 01 февраля 2010

Хотя, вначале у вас есть опечатка в названии исключения, которое вы перехватываете / выкидываете, но если ваш код точно такой же, я точно не знаю, что происходит.

Попробуйте следующую модификацию оригинального скрипта и вставьте свои результаты. Это поможет диагностировать вашу проблему немного лучше.

<?php

//set up exception handler to report what we didn't catch
function exception_handler($exception) {

    if($exception instanceof MyException) {
        echo "you didn't catch a myexception instance\n";

    } else if($exception instanceof Exception) {
        echo "you didn't catch a exception instance\n";

    } else {
        echo "uncaught exception of type: ".gettype($exception)."\n";
    }

    echo "Uncaught exception: " , $exception->getMessage(), "\n";
}

//install the handler
set_exception_handler('exception_handler');

class MyException extends Exception {
}

function inverse($x) {
    if (!$x) {
        throw new MyException('Division by zero.');
    }
    else return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (MyException $e) {
    echo 'Caught myexception: ',  $e->getMessage(), "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

// Continue execution
echo 'Hello World';
?>
4 голосов
/ 20 декабря 2010

У меня была такая же проблема со следующими конфигурациями,

PHP 5.2.14 (cli) (сборка: 12 августа 2010 г., 17:32:30) Copyright (c) 1997-2010 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies с eAccelerator v0.9.5.1 , Copyright (c) 2004-2006 eAccelerator, eAccelerator

Решение состоит в том, чтобы либо отключить eAccelerator, либо обновить его. Я попробовал оба варианта, и оба исправления сработали. Об ошибке сообщается здесь https://eaccelerator.net/ticket/242 (примечание. Firefox жалуется на их сертификат SSL).

Теперь я работаю, попробуйте правильно отловить следующие конфигурации,

PHP 5.2.4 (cli) (сборка: 16 октября 2007 г., 09:13:35) Copyright (c) 1997-2007 PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies с eAccelerator v0.9.6.1 , Copyright (c) 2004-2010 eAccelerator, eAccelerator

3 голосов
/ 03 ноября 2013

в Xdebug есть настройка:

xdebug.show_exception_trace = 1

Это заставит php выводить исключения даже в блоке try catch. Преврати это в 0

1 голос
/ 01 февраля 2010

Может быть, попытаться отключить некоторые сторонние расширения, которые вы, возможно, установили? http://bugs.php.net/bug.php?id=41744

0 голосов
/ 20 июня 2019

\ Исключение не работает для меня, но я нашел решение.

Мне нужно было заменить try {} catch (Exception $ e) {} на try {} catch (Throwable $ e) {}.

Для получения дополнительной информации: https://trowski.com/2015/06/24/throwable-exceptions-and-errors-in-php7/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...