Ano*_*van 46 php oop constructor class
到目前为止,我有一个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;
}
}
Run Code Online (Sandbox Code Playgroud)
功能loadUser
是查找特定电子邮件地址的数据库.当我将标识符设置为某些电子邮件时,我确定它不在数据库中; 第一个IF被传递,然后进入第一个ELSE.这里构造函数应该返回FALSE; 但相反,它返回具有所有NULL值的类的对象!
我该如何防止这种情况?谢谢
编辑:
谢谢大家的答案.那很快!我看到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 !!
}
}
Run Code Online (Sandbox Code Playgroud)
eri*_*sco 71
构造函数不会获得返回值; 它们完全用于实例化课程.
如果不重组您已经在做的事情,您可以考虑在此处使用例外.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以以这种方式创建新用户.
try {
$user = new User('user@example.com');
} catch (Exception $e) {
// unable to create the user using that id, handle the exception
}
Run Code Online (Sandbox Code Playgroud)
构造函数假设是创建一个对象.因为在php中,booleans不被认为是对象,所以唯一的选择是null.否则使用解决方法,即编写一个创建实际对象的静态方法.
public static function CheckAndCreate($identifier){
$result = self::loadUser();
if($result === true){
return new EmailClassNameHere();
}else{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
你能做的最好的就是史蒂夫的建议.永远不要创建执行任何工作的构造函数,然后将构造函数参数分配给对象属性,也可以创建一些默认值,但不能创建任何其他工作.构造函数旨在创建一个功能齐全的对象.在实例化之后,这样的对象必须始终按预期工作.用户有电子邮件,名称和可能的其他一些属性.如果要实例化用户对象,请将所有这些属性提供给其构造函数.抛出异常也不是一个好方法.在例外条件下抛出异常.通过电子邮件询问用户并不是特例,即使您最终发现没有这样的用户存在.例如,如果您通过email =''询问用户,则可能例外(除非您的系统中是常规状态,但在这种情况下,我建议将电子邮件建议为空).要获得用户对象的所有属性,你应该有一个工厂(或者你喜欢的存储库)对象(是的,一个对象 - 使用静态的不好做法)私有构造函数也是一个不好的做法(你会无论如何都需要一个静态方法,正如我已经说过的,静态非常糟糕)
所以结果应该是这样的:
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
}
Run Code Online (Sandbox Code Playgroud)
看到?没有静态,没有例外,简单的构造函数和非常易读,可测试和可修改
我真的很惊讶,四年来,22k 观众中没有一个建议创建私有构造函数和尝试创建如下对象的方法:
class A {
private function __construct () {
echo "Created!\n";
}
public static function attemptToCreate ($should_it_succeed) {
if ($should_it_succeed) {
return new A();
}
return false;
}
}
var_dump(A::attemptToCreate(0)); // bool(false)
var_dump(A::attemptToCreate(1)); // object(A)#1 (0) {}
//! new A(); - gives error
Run Code Online (Sandbox Code Playgroud)
这样你要么得到一个对象,要么得到 false(你也可以让它返回 null)。现在捕获这两种情况非常容易:
$user = User::attemptToCreate('email@example.com');
if(!$user) { // or if(is_null($user)) in case you return null instead of false
echo "Not logged.";
} else {
echo $user->name; // e.g.
}
Run Code Online (Sandbox Code Playgroud)
您可以在这里测试它: http: //ideone.com/TDqSyi
我发现我的解决方案比抛出和捕获异常更方便使用。