在类的构造函数中返回值

2022-08-30 10:29:31

到目前为止,我有一个带有构造函数的类PHP

public function __construct ($identifier = NULL)
{
 // Return me.
if ( $identifier != NULL )
{
  $this->emailAddress = $identifier;
  if ($this->loadUser() )
    return $this;      
  else
  {
// registered user requested , but not found ! 
return false;
  }
}

的功能是在数据库中查找特定的电子邮件地址。当我将标识符设置为某些电子邮件时,我确定它不在数据库中;第一个 IF 通过,并转到第一个 ELSE。在这里,构造函数应返回 FALSE;但是,相反,它返回具有所有 NULL 值的类的对象!loadUser

我该如何防止这种情况?谢谢

编辑:

谢谢大家的回答。这太快了!我看到OOP的方法是抛出一个异常。所以抛出一个,我的问题改变了,我该怎么办与例外??php.net的手册非常令人困惑!

    // Setup the user ( we assume he is a user first. referees, admins are   considered users too )
    try { $him = new user ($_emailAddress);
    } catch (Exception $e_u) { 
      // try the groups database
      try { $him = new group ($_emailAddress); 
      } catch (Exception $e_g) {
          // email address was not in any of them !!  
        }
    }

答案 1

构造函数不获取返回值;它们完全用于实例化类。

在不重组你已经在做的事情的情况下,你可以考虑在这里使用一个例外。

public function __construct ($identifier = NULL)
{
  $this->emailAddress = $identifier;
  $this->loadUser();
}

private function loadUser ()
{
    // try to load the user
    if (/* not able to load user */) {
        throw new Exception('Unable to load user using identifier: ' . $this->identifier);
    }
}

现在,您可以通过这种方式创建新用户。

try {
    $user = new User('user@example.com');
} catch (Exception $e) {
    // unable to create the user using that id, handle the exception
}

答案 2

你能做的最好的事情就是史蒂夫的建议。切勿创建执行任何工作的构造函数,然后将构造函数参数分配给对象属性,也许可以创建一些默认参数,但不创建其他任何操作。构造函数旨在创建一个功能齐全的对象。此类对象在实例化后必须始终按预期工作。用户具有电子邮件,姓名以及可能的其他一些属性。如果要实例化用户对象,请将所有这些属性提供给其构造函数。抛出异常也不是一个好方法。异常意味着在特殊情况下引发。通过电子邮件询问用户并不是什么特别的事情,即使您最终发现不存在这样的用户。例外情况可能是例如,如果您通过电子邮件= ''询问用户(除非这是系统中的常规状态,但id在这些情况下建议电子邮件为空)。要获取用户对象的所有这些属性,您应该有一个工厂(或者如果您愿意,可以拥有一个存储库)对象(是的,一个对象 - 使用静态任何东西都是一种不好的做法)私有构造函数也是一种不好的做法(无论如何,您都需要一个静态方法,正如我已经说过的,静态非常糟糕)

所以结果应该是这样的:

class User {
  private $name;
  private $email;
  private $otherprop;

  public function __construct($name, $email, $otherprop = null) {
    $this->name = $name;
    $this->email = $email;
    $this->otherprop = $otherprop;
  }
}

class UserRepository {
  private $db;

  public function __construct($db) {
    $this->db = $db; //this is what constructors should only do
  }

  public function getUserByEmail($email) {
    $sql = "SELECT * FROM users WHERE email = $email"; //do some quoting here
    $data = $this->db->fetchOneRow($sql); //supose email is unique in the db
    if($data) {
      return new User($data['name'], $data['email'], $data['otherprop']);
    } else {
      return null;
    }
  }
}

$repository = new UserRepository($database); //suppose we have users stored in db
$user = $repository->getUserByEmail('whatever@wherever.com');
if($user === null) {
  //show error or whatever you want to do in that case
} else {
  //do the job with user object
}

看?没有静态,没有例外,构造函数简单,可读性强,可测试和可修改


推荐