【问题标题】:Use try/catch as if/else?像 if/else 一样使用 try/catch?
【发布时间】:2013-11-22 02:43:55
【问题描述】:

我有一个在实例化时接受用户 ID 的类。当数据库中不存在该 ID 时,它将引发异常。这里是:

class UserModel {
    protected $properties = array();

    public function __construct($id=null) {
        $user = // Database lookup for user with that ID...
        if (!$user) {
            throw new Exception('User not found.');
        }
    }
}

我的客户端代码如下所示:

try {
   $user = new UserModel(123);
} catch (Exception $e) {
   $user = new UserModel();
   // Assign values to $user->properties and then save...
}

它只是试图找出用户是否存在,否则它会创建一个新用户。它有效,但我不确定它是否正确?如果不是,请提供解决方案。

【问题讨论】:

    标签: php exception try-catch


    【解决方案1】:

    不,这是不正确的,应该使用 try catch 块来处理可能发生异常情况的代码。在这里,您只是检查用户是否存在,因此实现此目的的最佳方法是使用简单的 if else。

    from wikipedia definition of programing expception:
    "Exception: an abnormal event occurring during the execution of a 
    routine (that routine is the "recipient" of the exception) during its execution. 
    Such an abnormal event results from the failure of an operation called by 
    the routine."
    

    【讨论】:

      【解决方案2】:

      正如@VictorEloy 和@AIW 回答的那样,不建议将异常用于流控制。

      作为补充,在您的情况下,我可能会坚持使用静态方法来查找现有用户,如果找到,则返回 UserModel 的实例,如果没有,则返回 null。这种方法在一些 ORM 库中使用,例如来自Ruby on RailsActive Record 和来自LaravelEloquent

      class UserModel {
          protected $properties = array();
      
          public static function find($id) {
              $user = // Database lookup for user with that ID...
      
              if ($user) {
                  return new UserModel($user); // ...supposing $user is an array with its properties
              } else {
                  return null;
              }
          }
      
          public function __construct($properties = array()) {
              $this->properties = $properties;
          }
      }
      
      $user = UserModel::find(5);
      
      if (!$user)
          $user = new UserModel();
      

      【讨论】:

        【解决方案3】:

        这是值得商榷的,但我要说这是不正确的。之前已经讨论过了。看 Is it "bad" to use try-catch for flow control in .NET?

        【讨论】:

          【解决方案4】:

          这似乎是一种正确的行为,只要它在 $idnull 时不抛出(这样,您可以假设要创建一个新的)。

          对于使用您的类的代码,如果您稍后要使用相同的 ID 插入它,只需在不检查的情况下使用该 ID 插入它 - 虽然不太可能,但有可能在检查和插入之间发生了一些事情。 (MySQL 有ON DUPLICATE KEY UPDATE。)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-26
            • 1970-01-01
            • 2017-04-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多