简体   繁体   English

PHP 中的 Try/Catch 块未捕获异常

[英]Try/Catch block in PHP not catching Exception

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 with PHP 5.2.3

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 .我在名为A 的命名空间中有异常,脚本位于名为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 !).问题是我有A\\MyException等于(在 PHP 中) \\B\\A\\MyException (因为我的脚本在名为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\\MyException

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 .只需尝试将Exception更改为\\Exception Worked for me!为我工作!

EDIT:编辑:

As sivann pointed in the comments, using namespace should do the same thing.正如 sivann 在评论中指出的那样,使用命名空间应该做同样的事情。 So simply put use \\Exception as Exception;所以简单地把use \\Exception as Exception; before your class declaration.在你的类声明之前。

Try to put catch(\\Exception $e) instead of catch(Exception $e) .尝试放置catch(\\Exception $e)而不是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.如果您正在使用您不太了解的代码,或者 - 特别是 - 如果您使用的是框架,它可能会用自己的一个覆盖默认的 PHP 异常,因此您可能会走错路并得到不希望的结果。 If you just put \\Exception , then you are sure you are catching the base PHP exception.如果您只是放置\\Exception ,那么您肯定会捕获基本的 PHP 异常。

You can not use the typical try{} catch{} blocks in PHP as you could do in another language like C# (Csharp).您不能在 PHP 中使用典型的 try{} catch{} 块,就像在 C# (Csharp) 等另一种语言中一样。

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".这只是因为 PHP 总是需要一个异常来“抛出”。 You need to set your own error handler and throw an Exception with it.您需要设置自己的错误处理程序并用它抛出异常。

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

\\Exception doesn't work for me but I found a solution. \\Exception对我不起作用,但我找到了解决方案。

I needed to replace:我需要更换:

  try {
   ...
  } catch(Exception $e){
   ...
  } 

by经过

  try {
   ...
  } catch(Throwable $e){
   ...
  }.

For more information : https://trowski.com/2015/06/24/throwable-exceptions-and-errors-in-php7/欲了解更多信息: https : //trowski.com/2015/06/24/throwable-exceptions-and-errors-in-php7/

如果您使用的是 PHP 7,您可能需要 Throwable 而不是 Exception

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

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.解决方案是禁用 eAccelerator 或更新它。 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) .该错误在此处报告https://eaccelerator.net/ticket/242 (注意。firefox 抱怨他们的 SSL 证书)。

Now I am running try catch properly with following configurations,现在我正在使用以下配置正确运行 try catch,

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 PHP 5.2.4 (cli)(构建时间:2007 年 10 月 16 日 09:13:35) 版权所有 (c) 1997-2007 PHP Group Zend Engine v2.2.0,版权所有 (c) 1998-2007 Zend Technologies with eAccelerator v0.9.6。 1 , 版权所有 (c) 2004-2010 eAccelerator,由 eAccelerator

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.即使在 try catch 块中,这也将强制 php 输出异常。 Turn this to 0将其设为0

catch all exception in php捕获php中的所有异常

 try
 {
   //place code
   throw new Exception('foo');//eg
 }
  catch (\Throwable $e) 
 { 
   dd('for php 7');
 } catch (\Exception $e) 
 { 
    dd('for php 5');
 }

https://www.php.net/manual/en/language.exceptions.php https://www.php.net/manual/en/language.exceptions.php

TLDR; TLDR; make sure you have use Exception;确保你有use Exception; on the top of both php files在两个 php 文件的顶部

Maybe try disabling certain 3rd party extensions you might have installed?也许尝试禁用您可能已安装的某些 3rd 方扩展? http://bugs.php.net/bug.php?id=41744 http://bugs.php.net/bug.php?id=41744

I am experiencing this as well.我也在经历这个。 I read comment from Rowinson Gallego which state Exception must be thrown.我阅读了 Rowinson Gallego 的评论,其中必须抛出状态异常。 So I modified my code from :所以我修改了我的代码:

try
{
  $number = 5/0; //or other exception
}
catch(Exception $e)
{
  throw $e;
}

into :进入 :

try
{
  $number = 5/0; //or other exception
}
catch(Exception $e)
{
  throw new Exception($e->getMessage(),$e->getCode());
}

It works.有用。

In my case, a weird situation occurred and catching Exception didn't work even when I had \\Exception .就我而言,一个奇怪的情况发生,并且捕捉Exception ,当我有没有连工作\\Exception Here is what to do to make sure that you never miss anything and always catch the error.以下是确保您不会错过任何内容并始终捕获错误的方法。

 catch (\Exception $e) {
        // do what you want to do on exception catching
 } catch (\Throwable $e) {
        // do what you want to do on exception catching 
 }

When you combine these two, you will never miss catching an Exception .当您将这两者结合起来时,您将永远不会错过捕获Exception Make sure to put the \\ before Exception and Throwable .确保将\\放在ExceptionThrowable之前。 That's important.这很重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM