【问题标题】:Writing functions that deal with exceptions编写处理异常的函数
【发布时间】:2013-02-18 22:19:12
【问题描述】:

Building upon a question I already asked regarding exceptions,我怕我写错了php函数,或者滥用了异常。我之所以这么说,是因为如果要使用 try/catch 块捕获自定义异常,则使用以下函数:

public function get_specific_page($page) {
    if (!is_array( $this->_page )){
        throw new AisisCore_Template_TemplateException( "<div class='error'>Trying to get a property from a non array.</div>" );
    }

    return $this->_page[$page];
}

然后会被称为:

try{
    get_specific_page($page);
}
catch(Exception $e){
    echo $e->getMessage();
}

这种方法的问题是我有很多这样写的函数,要么检查文件是否存在,要么抛出错误。检查是否在数组中设置了一个值,抛出一个错误,我的问题是处理这些函数调用的文件可能会因 try catch 而过载.....

所以我的问题是,我将如何更好地编写这样的函数,这样我的 php 文件就不会被 try catch 语句过度加载,但仍然能够拥有自己的自定义函数。

是否像在它自己的函数中编写try catch一样明显?

我问的原因是因为我习惯于与成名的工作以及在我们编写函数的公司中工作,如您在上面看到的那样。我如何使用具有大量这些功能的代码库,并且我没有看到使用它们的一半文件执行了一堆尝试捕获......

更新:

我正在查看 zend 源以更好地理解异常并遇到了这个问题:

public function setMessage($messageString, $messageKey = null)
    {
        if ($messageKey === null) {
            $keys = array_keys($this->_messageTemplates);
            foreach($keys as $key) {
                $this->setMessage($messageString, $key);
            }
            return $this;
        }

        if (!isset($this->_messageTemplates[$messageKey])) {
            require_once 'Zend/Validate/Exception.php';
            throw new Zend_Validate_Exception("No message template exists for key '$messageKey'");
        }

        $this->_messageTemplates[$messageKey] = $messageString;
        return $this;
    }

你可以看到他们如何在底部附近抛出一个新的异常消息,这个函数不是通过doing调用的:

try{}catch(){}

然而,当它抛出异常时,“未捕获的带有消息的异常”没有问题

【问题讨论】:

  • Zend 有自己的异常处理程序,其中一些是处理程序自己捕获的。

标签: php exception


【解决方案1】:

在我看来,您的方法总体上是正确的。但是,请注意:

  1. 您应该避免在异常消息中使用 HTML 格式。通常,您不知道如何处理您抛出的异常。例如,异常处理程序可以将消息写入日志文件(此时您不需要 HTML 格式),在特殊的错误视图中将其呈现给用户(在这种情况下,视图本身应该包含 HTML 格式),或者干脆忽略它(无论如何都不需要格式化)。
  2. 仅捕获您可以处理的异常。如果您知道您的函数抛出了AisisCore_Template_TemplateException,您应该只捕获该异常并将所有其他异常冒泡到一个可以处理它们的异常处理程序。您可以使用set_exception_handler 定义这样一个异常处理程序,该处理程序默认捕获所有未捕获的异常(这可能是Zend Framework 的示例中的情况)。简单地说:只在您知道如何处理它们的地方捕获异常
  3. 只使用名称所暗示的异常:处理控制流中的(意外)异常。使用异常来控制程序的常规流程是可能的,但通常被认为是糟糕的设计(顺便说一句,您的代码示例看起来还不错)。

为了完整起见,使用异常的一些替代方法:

  1. 使用返回码而不是异常。这是老式的 C 风格。优点是您不需要使用 try/catch 语句包装语句。但是,您必须检查每个过程的返回值,这很容易忘记。另一方面,使用异常时,您可以降低意外错误的风险,因为默认情况下未捕获的异常会产生致命错误。
  2. 使用 PHP 错误。请参阅trigger_error 函数。然而,在 PHP 中几乎不可能捕获自定义错误(使用 set_error_handler 除外,它仅适用于全局级别)。

【讨论】:

  • 我同意 helmbert。特别是在说您需要添加返回码的部分。我强烈认为你应该尽可能地使用返回码,并且只在出现问题时抛出异常,你必须打破原始代码块并转移到异常处理程序。在很多情况下,返回码将允许调用函数/程序采取不同的行动。
  • 嗯,我实际上试图说明的一点是,在我看来,异常比返回码更优雅,更安全,但这个问题显然取决于个人口味......; )
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多