【问题标题】:PHP rethrow exception from constructor [closed]PHP从构造函数重新抛出异常[关闭]
【发布时间】:2013-08-20 20:21:49
【问题描述】:

只是想知道这是否是一种常见做法。基本上,构造函数正在调用一些引发失败的初始化函数。我的想法是,将异常重新抛出到创建对象的位置是有意义的,因为那是发送实际输出的位置。

对于这种情况,这是“最佳做法”吗?还是有更标准的方法来做到这一点?

<?php
  class a {   
        private $x;
        private $y;
        function __construct($filename) {
             try {
                 $this->x = $this->functionThatMightThrowException($filename);
                 $this->y = $this->doSomethingElseThatMightThrow();
             }
             catch(InvalidArgumentException $e) {
                  throw $e;    //is this a good practice or not???
             }
             catch(Exception $e) {
                  throw $e;    //again
             }
         }

         //rest of class definition
    }

  // then somewhere else where the object is created and output is being sent
  $fn = "blah.txt";
  try {
    $a = new a($fn);
  }
  catch (InvalidArgumentException $e) {
     //actually handle here -- send error message back etc
  } 
  catch (Exception $e) {
     //etc
  }
?> 

【问题讨论】:

  • 如果你只是要重新扔它,你为什么要先抓住它???
  • 我会说这是多余的。不用担心。让它们不受约束地弹出,无需重新扔掉。
  • 如果你没有捕捉到一个特定的异常,它只会涓涓流回执行链。捕获并重新抛出相同的异常通常是没有意义的。通常你只抓住你真正想要处理的那些,然后让其余的在楼上涓涓细流以便在其他地方处理。这就像自助餐:如果你不想吃东西,那么一开始就不要把它放在你的盘子里。
  • 如果你除了重新扔它之外什么都不做,那就别费心去抓它了。
  • 我严重质疑投票结束这个问题的人的判断。我知道问题中的想法是错误的,但问题的整个 point 是异常是否需要重新抛出,或者它是否自动发生。说这个问题没有表现出对正在解决的问题的最低限度的理解是荒谬的。当然,提供的示例代码和解释已经绰绰有余——也许是错误的,但这不就是提问的全部原因吗?你们是版主建议我们只发布我们已经知道答案的问题吗?

标签: php oop exception-handling


【解决方案1】:

我们只看这部分代码:

         try {
             $this->x = $this->functionThatMightThrowException($filename);
             $this->y = $this->doSomethingElseThatMightThrow();
         }
         catch(InvalidArgumentException $e) {
              throw $e;    //is this a good practice or not???
         }
         catch(Exception $e) {
              throw $e;    //again
         }

因为InvalidArgumentException 也是Exception,这是一个典型的代码重复案例,并且本身可以简化为:

         try {
             $this->x = $this->functionThatMightThrowException($filename);
             $this->y = $this->doSomethingElseThatMightThrow();
         }
         catch(Exception $e) {
              throw $e;    //again
         }

现在,您询问这是否是好的做法的那一行已经消失了。所以我想即使使用这种纯粹系统的方法来删除重复代码,也可以回答这个问题:不,这不是一个好习惯。那是代码重复。

除此之外 - 正如已经评论过的 - 重新抛出异常没有任何价值。所以代码甚至可以简化为:

         $this->x = $this->functionThatMightThrowException($filename);
         $this->y = $this->doSomethingElseThatMightThrow();

所以我希望这会有所帮助。代码和以前完全一样,没有区别,只是代码更少,总是受欢迎的。

【讨论】:

  • 所以你说的是 "$A = new a($fn);" 周围的 try/catch 块足以捕获异常吗?构造函数中不需要额外的 try 块,因为异常会回到那里?
  • 好吧,定义 suffice,但是阅读 PHP php.net/language.exceptions 中的异常通常如何工作基本上会得出这样的结论,是的。
  • 我应该提到多个 catch 块,因为函数会针对特定情况抛出 InvalidArgumentException ,并且需要与其他随机可能性不同的处理方式。
猜你喜欢
  • 2011-11-04
  • 2019-07-11
  • 2019-03-11
  • 2023-03-11
  • 2014-11-03
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
  • 2012-10-28
相关资源
最近更新 更多