在PHP中Try/Catch块不捕获异常。

时间:2022-10-28 13:27:40

I am trying to run this Example #1 from this page: http://php.net/manual/en/language.exceptions.php

我正在尝试从这个页面运行这个示例#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";
?>

However instead of the desired output I get:

但是我得到的输出不是我想要的输出:

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

The developer environment I am using is UniServer 3.5 with PHP 5.2.3

我使用的开发环境是UniServer 3.5和PHP 5.2.3

8 个解决方案

#1


173  

I just had this exact problem where it seemed like I had even copied the name of the exception and yet it didn't catch it. It turned out it was my stupid mistake but I thought I should post my case here in case there is someone else in the same situation.

我刚刚遇到了这个问题,看起来我甚至复制了异常的名称,但是它并没有捕捉到它。原来这是我的愚蠢错误,但我想我应该把我的案子放在这里,以防有其他人也有同样的情况。

I had my exception in my namespace called A and the script was in a namespace called B. The problem was that I had A\MyException which equals (in PHP) \B\A\MyException (because my script is in the namespace called B!). All I had to do to fix it was to add backslash (or whatever it's called) to the exception name so it would look like this: \A\MyException

我的命名空间中有一个异常名为A,脚本位于一个名为B的命名空间中,问题是我有一个\MyException,它等于(在PHP中)\B\A MyException(因为我的脚本位于命名空间B!)我所要做的就是将反斜杠(或其他名称)添加到异常名中,使其看起来像这样:\一个MyException

#2


34  

Quite old question, yet...

很古老的问题,然而……

I had this problem as well (and that's how I found this post) but just simple experiment allowed me to find the solution. Just try changing Exception to \Exception. Worked for me!

我也有这个问题(这就是我发现这篇文章的原因),但是仅仅是一个简单的实验就能让我找到答案。尝试将异常更改为\Exception。为我工作!

EDIT:

编辑:

As sivann pointed in the comments, using namespace should do the same thing. So simply put use \Exception as Exception; before your class declaration.

正如sivann在注释中指出的那样,使用名称空间应该做同样的事情。因此简单地将使用\Exception作为异常;在你的类声明。

#3


19  

Try to put catch(\Exception $e) instead of catch(Exception $e) . If you are using a code you don't know about very well, or - especially - if you are using a framework, it might override the default PHP Exception with one of its own, and therefore you might go to the wrong path and get the undesired result. If you just put \Exception , then you are sure you are catching the base PHP exception.

尝试放入catch(\Exception $e)而不是catch(Exception $e)。如果您正在使用一个您不太了解的代码,或者—尤其是—如果您正在使用一个框架,它可能会覆盖一个自己的默认PHP异常,因此您可能会走错路径,得到不希望的结果。如果您只是放入\Exception,那么您肯定正在捕获基本的PHP异常。

#4


18  

You can not use the typical try{} catch{} blocks in PHP as you could do in another language like C# (Csharp).

在PHP中,不能像在c# (Csharp)这样的语言中那样使用典型的try{}捕获{}块。

If you do this:

如果你这样做:

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

You will not see the 'Got it!' message never. Why? It's just because PHP always needs an Exception to be "Thrown". You need to set your own error handler and throw an Exception with it.

你不会看到“得到它!”从来没有的消息。为什么?只是因为PHP总是需要一个异常来“抛出”。您需要设置自己的错误处理程序并抛出异常。

See set_error_handler function: http://php.net/manual/es/function.set-error-handler.php

看到set_error_handler函数:http://php.net/manual/es/function.set-error-handler.php

#5


5  

My initial though is you have a typo in the name of the exception you are catching/throwing, but if your code is exactly the same I'm not sure exactly what is going on.

我最初的想法是,您正在捕获/抛出的异常的名称中有一个错误,但是如果您的代码完全相同,我不确定究竟发生了什么。

Try the following modification of the original script, and paste your results. It will help diagnose your issue a bit better.

尝试对原始脚本进行以下修改,并粘贴结果。这将有助于更好地诊断您的问题。

<?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';
?>

#6


4  

I had the same problem with following configurations,

我也有同样的问题,

PHP 5.2.14 (cli) (built: Aug 12 2010 17:32:30) Copyright (c) 1997-2010 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies with eAccelerator v0.9.5.1, Copyright (c) 2004-2006 eAccelerator, by eAccelerator

PHP 5.2.14 (cli)(内置:2010年8月12日17:32:30)版权(c) 1997-2010 PHP Group Zend Engine v2.2.0,版权(c) 1998-2010 Zend Technologies with eAccelerator v0.9.5.1,版权(c) 2004-2006 eAccelerator,由eAccelerator

The solution is to either disable eAccelerator or update it. I tried both and both of the fixes worked. The bug is reported here https://eaccelerator.net/ticket/242 (NB. firefox complains about their SSL cert) .

解决方案是要么禁用eAccelerator,要么更新它。我尝试了两种方法,两种方法都奏效了。这里报告了这个错误:https://eaccelerator.net/ticket/242 (NB)。firefox抱怨他们的SSL证书)。

Now I am running try catch properly with following configurations,

现在我正在运行尝试捕获与以下配置,

PHP 5.2.4 (cli) (built: Oct 16 2007 09:13:35) Copyright (c) 1997-2007 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator

版权(c) 1997-2007年的PHP组Zend Engine v2.2.0,版权(c) 1998-2007 Zend技术,eAccelerator v0.9.6.1,版权(c) 2004-2010 eAccelerator, eAccelerator。

#7


3  

in Xdebug there is a setting:

在Xdebug中有一个设置:

xdebug.show_exception_trace = 1

This will force php to output exceptions even in a try catch block. Turn this to 0

这将迫使php输出异常,即使在try catch块中也是如此。把这个为0

#8


1  

Maybe try disabling certain 3rd party extensions you might have installed? http://bugs.php.net/bug.php?id=41744

可能尝试禁用您可能安装的某些第三方扩展?http://bugs.php.net/bug.php?id=41744

#1


173  

I just had this exact problem where it seemed like I had even copied the name of the exception and yet it didn't catch it. It turned out it was my stupid mistake but I thought I should post my case here in case there is someone else in the same situation.

我刚刚遇到了这个问题,看起来我甚至复制了异常的名称,但是它并没有捕捉到它。原来这是我的愚蠢错误,但我想我应该把我的案子放在这里,以防有其他人也有同样的情况。

I had my exception in my namespace called A and the script was in a namespace called B. The problem was that I had A\MyException which equals (in PHP) \B\A\MyException (because my script is in the namespace called B!). All I had to do to fix it was to add backslash (or whatever it's called) to the exception name so it would look like this: \A\MyException

我的命名空间中有一个异常名为A,脚本位于一个名为B的命名空间中,问题是我有一个\MyException,它等于(在PHP中)\B\A MyException(因为我的脚本位于命名空间B!)我所要做的就是将反斜杠(或其他名称)添加到异常名中,使其看起来像这样:\一个MyException

#2


34  

Quite old question, yet...

很古老的问题,然而……

I had this problem as well (and that's how I found this post) but just simple experiment allowed me to find the solution. Just try changing Exception to \Exception. Worked for me!

我也有这个问题(这就是我发现这篇文章的原因),但是仅仅是一个简单的实验就能让我找到答案。尝试将异常更改为\Exception。为我工作!

EDIT:

编辑:

As sivann pointed in the comments, using namespace should do the same thing. So simply put use \Exception as Exception; before your class declaration.

正如sivann在注释中指出的那样,使用名称空间应该做同样的事情。因此简单地将使用\Exception作为异常;在你的类声明。

#3


19  

Try to put catch(\Exception $e) instead of catch(Exception $e) . If you are using a code you don't know about very well, or - especially - if you are using a framework, it might override the default PHP Exception with one of its own, and therefore you might go to the wrong path and get the undesired result. If you just put \Exception , then you are sure you are catching the base PHP exception.

尝试放入catch(\Exception $e)而不是catch(Exception $e)。如果您正在使用一个您不太了解的代码,或者—尤其是—如果您正在使用一个框架,它可能会覆盖一个自己的默认PHP异常,因此您可能会走错路径,得到不希望的结果。如果您只是放入\Exception,那么您肯定正在捕获基本的PHP异常。

#4


18  

You can not use the typical try{} catch{} blocks in PHP as you could do in another language like C# (Csharp).

在PHP中,不能像在c# (Csharp)这样的语言中那样使用典型的try{}捕获{}块。

If you do this:

如果你这样做:

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

You will not see the 'Got it!' message never. Why? It's just because PHP always needs an Exception to be "Thrown". You need to set your own error handler and throw an Exception with it.

你不会看到“得到它!”从来没有的消息。为什么?只是因为PHP总是需要一个异常来“抛出”。您需要设置自己的错误处理程序并抛出异常。

See set_error_handler function: http://php.net/manual/es/function.set-error-handler.php

看到set_error_handler函数:http://php.net/manual/es/function.set-error-handler.php

#5


5  

My initial though is you have a typo in the name of the exception you are catching/throwing, but if your code is exactly the same I'm not sure exactly what is going on.

我最初的想法是,您正在捕获/抛出的异常的名称中有一个错误,但是如果您的代码完全相同,我不确定究竟发生了什么。

Try the following modification of the original script, and paste your results. It will help diagnose your issue a bit better.

尝试对原始脚本进行以下修改,并粘贴结果。这将有助于更好地诊断您的问题。

<?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';
?>

#6


4  

I had the same problem with following configurations,

我也有同样的问题,

PHP 5.2.14 (cli) (built: Aug 12 2010 17:32:30) Copyright (c) 1997-2010 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies with eAccelerator v0.9.5.1, Copyright (c) 2004-2006 eAccelerator, by eAccelerator

PHP 5.2.14 (cli)(内置:2010年8月12日17:32:30)版权(c) 1997-2010 PHP Group Zend Engine v2.2.0,版权(c) 1998-2010 Zend Technologies with eAccelerator v0.9.5.1,版权(c) 2004-2006 eAccelerator,由eAccelerator

The solution is to either disable eAccelerator or update it. I tried both and both of the fixes worked. The bug is reported here https://eaccelerator.net/ticket/242 (NB. firefox complains about their SSL cert) .

解决方案是要么禁用eAccelerator,要么更新它。我尝试了两种方法,两种方法都奏效了。这里报告了这个错误:https://eaccelerator.net/ticket/242 (NB)。firefox抱怨他们的SSL证书)。

Now I am running try catch properly with following configurations,

现在我正在运行尝试捕获与以下配置,

PHP 5.2.4 (cli) (built: Oct 16 2007 09:13:35) Copyright (c) 1997-2007 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator

版权(c) 1997-2007年的PHP组Zend Engine v2.2.0,版权(c) 1998-2007 Zend技术,eAccelerator v0.9.6.1,版权(c) 2004-2010 eAccelerator, eAccelerator。

#7


3  

in Xdebug there is a setting:

在Xdebug中有一个设置:

xdebug.show_exception_trace = 1

This will force php to output exceptions even in a try catch block. Turn this to 0

这将迫使php输出异常,即使在try catch块中也是如此。把这个为0

#8


1  

Maybe try disabling certain 3rd party extensions you might have installed? http://bugs.php.net/bug.php?id=41744

可能尝试禁用您可能安装的某些第三方扩展?http://bugs.php.net/bug.php?id=41744