【问题标题】:Is throwing exceptions without catching them bad? [closed]抛出异常而不捕获它们是不好的吗? [关闭]
【发布时间】:2014-07-09 08:11:54
【问题描述】:

在我的 MVC 路由器中,我得到了类似的东西:

if (class_exists('Controller')) {
    $controller = new Controller();
} else {
    throw new Exception('Controller not found.');
}

当它发生时,我实际上从来没有捕捉到这个异常。我只是把它放在那里,这样它就会向我显示一个错误,以便我可以查找并修复它。

我觉得这是使用异常的一种不好的方式,不是吗?

如果是这样,使用异常的更好示例是什么?

【问题讨论】:

  • 在脚本的顶层捕捉并显示适当的格式整齐的消息
  • 马克贝克所说的。您是否希望您的访问者以丑陋的 php 异常形式查看(可能是明智的)数据?
  • 看起来很适合开发网站,但不太适合上线。

标签: php exception error-handling


【解决方案1】:

允许不捕获异常可能会导致一些混乱的情况。最坏的情况是异常会导致向客户端输出堆栈跟踪,堆栈跟踪可能包含敏感信息。例如:

class Foo {
    public function __construct($username, $password) {
        throw new Exception('oh noes');
    }
}

$bar = new Foo('Sammitch', 'bologna123');

生成以下输出

PHP Fatal error:  Uncaught exception 'Exception' with message 'oh noes' in /home/sammitch/tmp/test.php:6
Stack trace:
#0 /home/sammitch/tmp/test.php(11): Foo->__construct('Sammitch', 'bologna123')
#1 {main}
  thrown in /home/sammitch/tmp/test.php on line 6

异常可能会在堆栈深处抛出更多层,在与需要这些凭据的代码完全无关的代码中。

这种情况下的最佳实践是使用set_exception_handler() 定义一个函数,该函数将以您明确定义的方式处理未捕获的异常。例如:

set_exception_handler(function($e){ echo $e->getMessage(); });

这使得上面的示例输出变得简单:oh noes

更好的解决方案是将异常记录到文件中和/或通知管理员。

【讨论】:

    【解决方案2】:

    不,这是使用它们的好方法。至少,如果您遇到此错误,您将有一个明确的错误消息可供使用。是否应该被捕获取决于上下文。

    据推测,在生产中您实际上并没有显示错误,但它仍然应该在错误日志中(同样取决于您使用的框架等)。

    【讨论】:

    • 那么,在生产中我会捕获它并显示一条用户友好的消息并记录错误?
    • 是的,例如,您可以使用php.net/manual/en/function.set-exception-handler.php 为未捕获的异常创建一个全局处理程序,并向用户显示一个通用错误页面(同时记录完整的错误)。
    猜你喜欢
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 2016-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多