开放的编程资料库

当前位置:我爱分享网 > PHP教程 > 正文

关于 PEAR_Exception 的注释

我一直在思考异常,尤其是PEAR_Exception。您可能想直接跳到阅读有关如何使用PEAR_Exception的内容,以及我对首次使用该类的一些想法。如果您想了解背景,请继续阅读。

我已经在PEAR上为一个名为File_Fortune的包创建了一个包提案,这是一个用于读取和写入财富文件的OOP接口。多年来,我一直在家庭网站上为此使用perl模块,现在我开始进行PHP转换,我想我应该从构建块开始。

在创建提案时,我从一个仅限PHP5的版本开始,尽管我发现除了public/private/protected/static关键字。对于错误处理,我决定试用PEAR_ErrorStack,因为我一直听说它是PEAR中错误处理的新“首选”方法。(老实说,在使用它之后,我对它不太满意;抛出PEAR_Error更容易,也更容易操作——但那是另一篇文章的主题——而且异常更容易,虽然打字更多。)

我收到的关于提案的第一条评论是问题:“为什么是PHP5?”(Paul对这种反应并不太惊讶。)我考虑了一下,决定不是除了我需要采取一些额外的步骤才能实际测试PHP4版本之外,真的所有这些都是必要的。所以,我做了一个PHP4版本。

好吧,然后发生了一些争论,许多开发人员说,“为什么PHP5?”所以,我又回到了PHP5。然后其他人说,“使用PEAR_Exception。”所以,我开始研究它,我们终于进入了这篇文章的主题。

异常处理是PHP5给PHP带来的进步之一。我很高兴它可用,因为我习惯了perl中的异常处理(这实际上与PHP的模型完全不同,但基础是相同的)。当我看到使用它的建议时,我意识到异常处理将使该包成为一个可靠的PHP5包。同时,我想知道为什么我没有想到。我猜我编写的PHP代码比perl代码多了一段时间了……

问题是关于PEAR_Exception的文档非常少,我在列表中得到的提示虽然有助于我提出建议,但给我留下了很多问题。

对于那些还没有使用过PEAR_Exception的人,这里是基础知识:

  • 创建一个文件来保存您的异常类。(是的,复数;我会说的)。如果你正在开发一个PEAR风格的包,你想把它放在与你的包名相关的目录中。所以,由于我正在开发File_Fortune,我的异常类变成了File/Fortune/Exception.php

  • 创建一个扩展PEAR_Exception的类的基本异常类:

    class File_Fortune_Exception extends PEAR_Exception
    {
    }
    

    注意:它不会覆盖任何内容。它只是创建一个伪命名空间。

  • 对于每个独特的异常类型,扩展您的基类:

    class File_Fortune_FileException extends File_Fortune_Exception
    {
    }
    
    class File_Fortune_HeaderException extends File_Fortune_Exception
    {
    }
    

    (是的,您应该为每个文档块创建文档块,描述它们的用途。)

  • 在您的代码中,抛出异常而不是引发错误:

    if (false === ($fh = fopen($filename))) {
        throw new File_Fortune_FileException('Unable to open file');
    }
    
  • 在您的phpDoc块中,使用@throwsException_Class_Name和一些描述性文本

简而言之就是这些。

它的美妙之处在于您可以真正将错误与返回值分开——错误不再是可能的返回值:

try {
    $fortune = $ff->getRandom();
} catch (File_Fortune_Exception $e) {
    echo "Couldn't get fortune: " . $e->getMessage();
}

我在系统中看到的问题是你最终会得到一堆异常类,每个异常类都有一个veeeerrryyylooooonnnnngggg名称,这会导致大量输入,可能会出现拼写错误(我在用于调用投票),以及比代码更多的错误处理的可能性,这取决于可能的异常数量以及您想要检查它们的仔细程度:

try {
    $fortune = $ff->getRandom();
} catch (File_Fortune_BadHeaderFileException $e) {
    echo "Could not parse header file";
} catch (File_Fortune_HeaderFileException $e) {
    echo "Could not open header file";
} catch (File_Fortune_BadFileException $e) {
    echo "Badly formed fortune file";
} catch (File_Fortune_Exception $e) {
    // Catch-all for File_Fortune errors...
    echo "Couldn't get fortune: " . $e->getMessage();
}

我开始思考一定有更好的方法。不过,我还没有真正想出一个。然而,到目前为止,我的想法是拥有一个异常类,并在其中定义一些类常量或静态变量——很像PEAR_Error/PEAR_ErrorStack,它们映射到整数值——并将这些值映射到实际的错误消息(也可能在类中进行本地化)。然后,当抛出错误时,它可能是这样的:

if (false === ($fh = fopen($filename))) {
    throw new File_Fortune_Exception(1);
} 
// or
if (false === ($fh = fopen($filename))) {
    throw new File_Fortune_Exception(File_Fortune_Exception::FILE);
} 

构造函数将被覆盖以根据传递的代码设置代码和消息(如果传递的是字符串,那将是消息)。然后您可以测试单个异常类,如果您需要更细粒度的控制,则可以使用$e->getCode()检查类型。

我非常乐意讨论各种可能性。异常是检查代码中真正异常行为的绝佳方式;在PHP5中,它们似乎也非常快速和轻量级(尽管我没有实质性数据来支持该声明,除了API响应能力)。我希望看到更多人与他们一起开发。

关于这一点,其他PHP开发人员如何看待异常处理?我听说有人说它太“goto-ish”(我不确定我是否遵循了这种思路),其他人更喜欢PEAR_Error的简单性。发表评论!

未经允许不得转载:我爱分享网 » 关于 PEAR_Exception 的注释

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏