PHP中的try / catch块未捕获异常


97

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


1
您能告诉我们您的代码吗?要获得此错误,您唯一可以做的错误就是捕获错误的异常(或没有错误)。
Tammo '01

2
代码完全相同(我刚刚添加了一些换行符)...总之,我再次将代码复制到了测试文件中,这是相同的错误消息:0.2致命错误:未捕获的异常“ Exception”,消息为“除零” 。” 在W:\ www \ test.php:4中堆栈跟踪:#0 W:\ www \ test.php(11):inverse(0)#1 {main}在第4行的W:\ www \ test.php中抛出我真的不知道那里发生了什么……也许是错误的PHP配置?
克拉西(Krassi)

1
一些较旧的扩展版本导致异常处理问题。5.2.3是较旧的,可能是错误背后的错误。可以升级PHP吗?考虑到当前的生产版本为5.5,UniServer 3.5也相当旧。3.5是错字吗?
outis 2010年

1
查看UniServer发行信息(wiki.uniformserver.com/index.php/…),3.5显然不是错字。升级到UniServer 5.5,然后再次尝试示例代码。
2010年

1
outis,谢谢你的提示:)。这就是我当时所做的-切换到XAMPP(不要像新版本的UniServer)。3.5并不是一个错字,但是服务器对我来说工作得很好,所以我从不费心升级它。
克拉西2010年

Answers:


217

我只是遇到了一个确切的问题,似乎我什至已经复制了异常的名称,但是没有捕获到它。原来这是我的愚蠢错误,但我认为我应该在这里发布案件,以防万一有人遇到同样的情况。

我在名为A的命名空间中遇到了异常,而脚本在名为B的命名空间中发生了异常。问题是我的A \ MyException等于(在PHP中)\ B \ A \ MyException(因为我的脚本在名为B的命名空间中)。我要解决的所有事情就是在异常名称中添加反斜杠(或其他名称),使其看起来像这样:\ A \ MyException


7
非常感谢您发布此信息,因为我会走了好几天却没有意识到自己的错误。
tipu 2012年

79
这解决了我的问题,命名空间代码中的一个简单的惰性捕获块应该是catch (\Exception $e)。没有反斜杠Exception是特定于名称空间的,不会被匹配(或捕获)。
joemaller

3
感谢您发布!
keepkimi

2
感谢您发布此信息,最近几个小时我一直在为为什么我的catch块不起作用而疯狂。主要面霜。
米奇

4
干杯! 拯救了我的一天(和神经元...):)
2015年

67

相当老的问题了……

我也遇到了这个问题(这就是我找到这篇文章的方式),但是仅通过简单的实验就可以找到解决方案。只需尝试更改Exception为即可\Exception。为我工作!

编辑:

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


辉煌!:)可能要花我几个小时才能弄清楚,只是没有考虑命名空间。谢谢!
亚历山大·吉尔曼诺夫'16

是! 还:“使用\ Exception作为异常;” 在顶部执行相同的操作。
sivann

@ sii-anik尝试使用sivann所写的名称空间。
伦理

只是use Exception;应该做
迭戈·庞恰诺

谢谢!@Enethion
Noamway

32

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


@crassi,您尝试了我的建议吗?
弗拉基米尔·德斯波托维奇(Fladimir Despotovic)

2
为我做到了
cljk

20

您不能像在C#(Csharp)这样的其他语言中那样在PHP中使用典型的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


6
那是不一样的;)您需要自己抛出一个异常,这就是我所说的(<<这仅仅是因为PHP总是需要一个异常才能“抛出” >>)@JaredFarrish
Rowinson Gallego

是的,但是怎么不一样呢?
Jared Farrish

该链接已死,但我发现它很有用:w3schools.com/php/func_error_set_error_handler.asp
讨厌2014年

在PHP版本7.3.9中,$number = 5/0;不会引发异常。$number设置为INF
virtualmic

6

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

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

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

使用以下配置时,我遇到了同样的问题,

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,eAccelerator版权所有(c)2004-2006 eAccelerator

解决方案是禁用eAccelerator或对其进行更新。我尝试了两个,并且两个修复程序都起作用。该错误在此处报告https://eaccelerator.net/ticket/242(注意:firefox抱怨其SSL证书)。

现在,我正在运行,尝试使用以下配置正确捕获,

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,eAccelerator版权所有(c)2004-2010 eAccelerator



3

在Xdebug中有一个设置:

xdebug.show_exception_trace = 1

这将迫使php即使在try catch块中也输出异常。转到0


2
就我而言,我必须完全禁用xdebug模块(更改xdebug.show_exception_trace不够)。
托马斯·萨林

感谢您的提醒。我彻底感到困惑了一段时间。
Brian Litzinger'Mar

3

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


这是一个相当老的帖子。在决定回答之前,请先查看主题的日期。在那旁边是你的答案不是真的有益,因为它是: -不完全-没有解释为什么
monofone

1
原因是PHP7使用Throwable而不是Exception。这次讨论是我遇到问题并希望做出贡献时发现的第一个。像这样的评论是Stack不适合社区的原因。
user5528384

1
我不是要冒犯你。这篇文章出现在“第一篇文章”评论队列中,我认为发布一个相当老的问题的答案是没有用的。在撰写本文时,Throwable Throwable甚至不是在PHP世界中发明的。如果您在回答中写到Throwable是由Exception(和Error)实现的接口,因此也可以被捕获,则将很有帮助。但这不是对Exception的补充。
monofone



0

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

有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.