我的所有用户方法都有以下类:
class User {
protected $_db,
$_data;
public function __construct($user = null, $findby = 'id') {
$this->_db = DB::getInstance();
if (!$user) {
........
} else {
........
}
}
.......
public function login($username = null, $password = null) {
$user = $this->find($username, 'username');
if ($user) {
$lockdown = new Lockdown;
}
}
public function find($param = null, $method = null) {
if ($param && $method) {
$data = $this->_db->query("SELECT * FROM users ...");
if ($data->count()) {
$this->_data = $data->result();
return true;
}
}
return false;
}
public function data() {
return $this->_data;
}
}
以上是我的用户类的完全剥离版本。我还有另一个类(锁定)扩展用户:
class Lockdown extends User {
public $getAttempts;
public function __construct() {
var_dump($this->data());
die();
}
}
但是当我在登录类中调用lockdown类时,即使数据对象应该包含所有用户信息,var_dump()也只是返回NULL。
根据我的计算,当调用登录类时,查找方法应设置$ _data = USER INFO,因此应允许在($ this-> find)之后调用新的Lockdown方法())能够访问相同的数据方法。
我还在学习OOP编程,所以不知道是否有我遗漏的东西,但我似乎无法理解为什么Lockdown类在数据方法上返回NULL的原因应该继承它。
答案 0 :(得分:2)
您不应该在构造函数中放置任何计算逻辑。这使得测试变得困难。您也无法从构造函数返回。
你的结构是一场彻底的灾难。两者都是因为你滥用继承和全球国家。
为类创建自己的子类的新实例以检索数据是没有意义的。这可能是因为您试图让User
类结合两个不同的职责:持久性和业务逻辑。这违反了Single Responsibility Principle,然后以复杂的调用图形式显示。
整个class Lockdown extends User
构造也毫无意义。 OOP中的extends
关键字可以翻译为"是"的特殊情况。 (根据LSP)。跟踪用户登录尝试的类不是" user"的专门案例。
你应该至少有3个单独的类:一个用于处理"用户的行为"和其他用于保存/恢复"用户的状态" (该方法称为" data mapper")。第三个是管理失败的尝试。
我还强烈建议您观看this lecture。
对于全局状态,您应该将数据库连接作为构造函数的依赖项传递给类,而不是使用单例反模式,这需要与持久性进行交互。
至于代码,在高级别,它应该看起来像这样:
$user = new User;
$mapper = new UserMapper($db);
$user->setName($username)
if ($mapper->fetch($user)) {
if ($user->matchPassword($password)) {
// you have logged in
// add some flag in session about it
header('Location: /greetings');
exit;
}
// check the failed attempts
} else {
// no matching username
}