【问题标题】:Try/Catch block in PHP not catching ExceptionPHP 中的 Try/Catch 块未捕获异常
【发布时间】:2011-01-11 11:27:34
【问题描述】:

我正在尝试从此页面运行此示例 #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.5PHP 5.2.3

【问题讨论】:

  • 你能告诉我们你的代码吗?获得此错误的唯一错误是捕获错误的异常(或没有异常)。
  • 代码完全相同(我刚刚添加了一些换行符)......无论如何,我再次将代码复制到测试文件中,这里是相同的错误消息:0.2 致命错误:未捕获的异常'异常”,带有消息“除以零”。在 W:\www\test.php:4 堆栈跟踪:#0 W:\www\test.php(11): inverse(0) #1 {main} 在第 4 行的 W:\www\test.php 中抛出我真的不知道那里发生了什么......也许是错误的 PHP 配置?
  • 一些较旧的扩展版本导致异常处理问题。 5.2.3 是旧的,错误背后可能有一个错误。你能升级PHP吗? UniServer 3.5 也很旧,考虑到当前的生产版本是 5.5。 3.5 是错字吗?
  • 查看 UniServer 发布信息 (wiki.uniformserver.com/index.php/…),3.5 显然不是错字。升级到 UniServer 5.5 并再次尝试示例代码。
  • outis,感谢您的提示 :)。这就是我当时所做的——切换到 XAMPP(不喜欢新版本的 UniServer)。 3.5 不是错字,但服务器对我来说工作得很好,所以我从不费心升级它。

标签: php


【解决方案1】:

我刚刚遇到了这个确切的问题,似乎我什至复制了异常的名称,但它没有捕获它。事实证明这是我的愚蠢错误,但我认为我应该在这里发布我的案例,以防其他人处于同样的情况。

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

【讨论】:

  • 非常感谢您发布此信息,因为我可能已经走了好几天而没有意识到自己的错误。
  • 这解决了我的问题,命名空间代码中的一个简单的惰性捕获块应该是catch (\Exception $e)。没有反斜杠 Exception 是特定于命名空间的,不会被匹配(或捕获)。
  • 感谢您发布此信息,我刚刚花了几个小时为我的 catch 块不起作用的原因而发疯。大掌。
  • 干杯!拯救了我的一天(和神经元......):)
  • @albanx 这不是公认的答案,因为它显然不是 OP 的问题。命名空间在他的代码中匹配。人们只是赞成这个答案,因为它可能会导致类似的问题,但这不是正确的问题。
【解决方案2】:

很老的问题,但是......

我也遇到了这个问题(这就是我找到这篇文章的原因),但只是简单的实验让我找到了解决方案。只需尝试将Exception 更改为\Exception。为我工作!

编辑:

正如 sivann 在 cmets 中指出的那样,使用命名空间应该做同样的事情。所以只需将use \Exception as Exception; 放在你的类声明之前。

【讨论】:

  • 太棒了! :) 可能需要我几个小时才能弄清楚,只是没有考虑命名空间。谢谢!
  • 是的!也:“使用 \Exception 作为异常;”在顶部做同样的事情。
  • @sii-anik 尝试像 sivann 写的那样使用命名空间。
  • 只要use Exception; 就应该这样做
【解决方案3】:

尝试使用 catch(\Exception $e) 而不是 catch(Exception $e) 。如果您使用的代码您不太了解,或者 - 特别是 - 如果您使用的是框架,它可能会用自己的一个覆盖默认的 PHP 异常,因此您可能会走错路并得到不想要的结果。如果您只是输入 \Exception ,那么您确定您正在捕获基本 PHP 异常。

【讨论】:

  • @crassi,你有没有尝试我的建议?
  • 为我做的
【解决方案4】:

您不能像在 C# (Csharp) 等其他语言中那样使用典型的 try{} catch{} 块。

如果你这样做:

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

【讨论】:

  • 不一样 ;) 你需要自己抛出异常,这就是我所说的(>)@JaredFarrish
  • 是的,但怎么不一样呢?
  • 该链接已失效,但我发现这很有用:w3schools.com/php/func_error_set_error_handler.asp
  • 在 PHP 版本 7.3.9 中,$number = 5/0; 不会引发异常。 $number 设置为 INF
【解决方案5】:

\Exception 对我不起作用,但我找到了解决方案。

我需要更换:

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

通过

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

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

【讨论】:

  • 你是生命的救星。我已经知道 \Exception 的事情了。但是,这对我不起作用。不知道为什么。这个有效。
  • 这里也一样。我有一段代码正在调用一个函数,并且在该函数内部有一个“致命错误”。多亏了 Throwable 东西,我可以从一段代码(函数外)中捕获它。
【解决方案6】:

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

【讨论】:

  • 这是一篇相当老的帖子。在决定回答之前,先看看主题的日期。除此之外,您的答案并没有真正的帮助,因为它是:-不完整-没有解释原因
  • 解释是PHP7使用Throwable而不是Exception。这个讨论是我遇到问题时发现的第一个讨论,我想贡献一下。像这样的评论是 Stack 对社区不友好的原因。
  • 我无意冒犯你。这篇文章出现在“第一篇文章”审查队列中,在我看来,就一个相当老的问题发表答案是没有用的。在撰写本文时,问题 Throwable 甚至还没有在 PHP 世界中发明。如果您在回答中写下 Throwable 是由异常(和错误)实现的接口,因此也可以被捕获,这将很有帮助。但它不是 Exception 的补充。
【解决方案7】:

虽然我最初的想法是您在捕获/抛出的异常名称中有拼写错误,但如果您的代码完全相同,我不确定到底发生了什么。

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

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

【讨论】:

    【解决方案8】:

    我在以下配置中遇到了同样的问题,

    PHP 5.2.14 (cli)(构建时间:2010 年 8 月 12 日 17:32:30) 版权所有 (c) 1997-2010 PHP 集团 Zend Engine v2.2.0,版权所有 (c) 1998-2010 Zend Technologies 使用 eAccelerator v0.9.5.1,版权所有 (c) 2004-2006 eAccelerator,由 eAccelerator 提供

    解决方案是禁用 eAccelerator 或对其进行更新。我尝试了这两种方法,两种修复方法都有效。这里报告了错误https://eaccelerator.net/ticket/242(注意,firefox 抱怨他们的 SSL 证书)。

    现在我正在使用以下配置正确运行 try catch,

    PHP 5.2.4 (cli)(构建时间:2007 年 10 月 16 日 09:13:35) 版权所有 (c) 1997-2007 PHP 集团 Zend Engine v2.2.0,版权所有 (c) 1998-2007 Zend Technologies 使用 eAccelerator v0.9.6.1,版权所有 (c) 2004-2010 eAccelerator,由 eAccelerator 提供

    【讨论】:

      【解决方案9】:

      在Xdebug中有一个设置:

      xdebug.show_exception_trace = 1
      

      这将强制 php 即使在 try catch 块中也输出异常。 转至0

      【讨论】:

      • 在我的情况下,我必须完全禁用 xdebug 模块(更改 xdebug.show_exception_trace 是不够的)。
      • 感谢您的提醒。一时间我彻底糊涂了。
      【解决方案10】:

      在 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

      【讨论】:

        【解决方案11】:

        TLDR;确保在两个 php 文件的顶部都有 use Exception;

        【讨论】:

          【解决方案12】:

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

          【讨论】:

            【解决方案13】:

            我也遇到过这种情况。我阅读了 Rowinson Gallego 的评论,必须抛出哪个状态异常。所以我修改了我的代码:

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

            进入:

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

            有效。

            【讨论】:

              【解决方案14】:

              就我而言,发生了一个奇怪的情况,即使我有\Exception,也无法捕获Exception。以下是确保您不会遗漏任何内容并始终捕获错误的方法。

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

              当您将这两者结合起来时,您将永远不会错过捕捉Exception。确保将\ 放在ExceptionThrowable 之前。这很重要。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-02-28
                相关资源
                最近更新 更多