繁体   English   中英

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

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

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

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

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

很老的问题,但...

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

编辑:

正如 sivann 在评论中指出的那样,使用命名空间应该做同样的事情。 所以简单地把use \\Exception as Exception; 在你的类声明之前。

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

您不能在 PHP 中使用典型的 try{} catch{} 块,就像在 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

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

我需要更换:

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

经过

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

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

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

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

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

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

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

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

解决方案是禁用 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 Group Zend Engine v2.2.0,版权所有 (c) 1998-2007 Zend Technologies with eAccelerator v0.9.6。 1 , 版权所有 (c) 2004-2010 eAccelerator,由 eAccelerator

在 Xdebug 中有一个设置:

xdebug.show_exception_trace = 1

即使在 try catch 块中,这也将强制 php 输出异常。 将其设为0

捕获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

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

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

我也在经历这个。 我阅读了 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());
}

有用。

就我而言,一个奇怪的情况发生,并且捕捉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之前。 这很重要。

暂无
暂无

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

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