Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 最佳实践:表示单个数据库表的类_Php_Oop - Fatal编程技术网

Php 最佳实践:表示单个数据库表的类

Php 最佳实践:表示单个数据库表的类,php,oop,Php,Oop,我有一个用户数据库表,其中包含以下字段:id、用户名、密码、电子邮件、角色、密码还原令牌和过期日期等 现在我需要一个类来读写用户数据 是否最好为每个数据库字段创建类变量,并像这样读/写它们: class User { private $db; private $user_id; private $username; private $email; [...] public function getUsername() { ret

我有一个用户数据库表,其中包含以下字段:id、用户名、密码、电子邮件、角色、密码还原令牌和过期日期等

现在我需要一个类来读写用户数据

是否最好为每个数据库字段创建类变量,并像这样读/写它们:

class User {
    private $db;
    private $user_id;
    private $username;
    private $email;

    [...]

    public function getUsername() {
        return $this->username;
    }

    public function setUsername($name) {
        $this->username = $name;
    }

    public function readDB() {
         $sth = $this->db->query("SELECT * FROM users WHERE id = ?", 
         array((int)$this->user_id));
         $user = $sth->fetch();
         if($user !== false && is_array($user)) {
             $this->username = $user['username'];
             $this->email = $user['email'];
             [...]
    }

    public function writeDB() {
        [...]
        $this->db->insert('users', array(
            'username' => $this->username
            'email' => $this->email), array('user_id' => $this->user_id)); 
    }
}
class User {
    private $db;

    [...]

    public function readDB($userID) {
         $sth = $this->db->query("SELECT * FROM users WHERE id = ?", 
         array((int)$userID));
         $user = $sth->fetch();
         return $user;
    }

    public function writeDB($userID, $username, $email ...) {
        $this->db->insert('users', array(
            'username' => $username
            'email' => $email), array('user_id' => $userID)); 
    }
}
$user = new Entity\User;
$user->setUsername('Drunk Lizard');

$mapper = new Mapper\User($pdo);
$mapper->fetch($user);

if (!$user->hasStatus(Entity\User::UNVERIFIED)) {
    throw new InvalidAction;
}

if (!$user->hasToken($request->get('token'))) {
    throw new WrongToken;
}

$user->setStatus(Entity\User::VERIFIED);
$mapper->store($user);
或者不使用类变量,这样做:

class User {
    private $db;
    private $user_id;
    private $username;
    private $email;

    [...]

    public function getUsername() {
        return $this->username;
    }

    public function setUsername($name) {
        $this->username = $name;
    }

    public function readDB() {
         $sth = $this->db->query("SELECT * FROM users WHERE id = ?", 
         array((int)$this->user_id));
         $user = $sth->fetch();
         if($user !== false && is_array($user)) {
             $this->username = $user['username'];
             $this->email = $user['email'];
             [...]
    }

    public function writeDB() {
        [...]
        $this->db->insert('users', array(
            'username' => $this->username
            'email' => $this->email), array('user_id' => $this->user_id)); 
    }
}
class User {
    private $db;

    [...]

    public function readDB($userID) {
         $sth = $this->db->query("SELECT * FROM users WHERE id = ?", 
         array((int)$userID));
         $user = $sth->fetch();
         return $user;
    }

    public function writeDB($userID, $username, $email ...) {
        $this->db->insert('users', array(
            'username' => $username
            'email' => $email), array('user_id' => $userID)); 
    }
}
$user = new Entity\User;
$user->setUsername('Drunk Lizard');

$mapper = new Mapper\User($pdo);
$mapper->fetch($user);

if (!$user->hasStatus(Entity\User::UNVERIFIED)) {
    throw new InvalidAction;
}

if (!$user->hasToken($request->get('token'))) {
    throw new WrongToken;
}

$user->setStatus(Entity\User::VERIFIED);
$mapper->store($user);
我看不出第一个解决方案的优点,只是以后很容易更改数据库字段名,但在较低的readDB版本中只需简单更改即可

第一个版本的缺点是,我需要编写很多get和set方法,方法调用需要多一点处理时间,我必须首先检查每个类变量,在插入/更新数据之前是否已经设置了它。如果缺少参数,第二个版本将自动生成方法参数错误

例如,有时我只需要用户的电子邮件地址,而第一个版本总是需要首先读取数据库中的所有字段,然后调用getEmail方法。第二种方法允许编写一个特殊的方法,用于返回单个数据库字段selectemail fromsuser,其中user_id=?。这将减少数据库负载


您喜欢哪种方式?为什么?

您应该将域实体逻辑与持久性逻辑分开。不要有一个包含所有内容的类,因为这样你基本上会得到反模式的美化版本

更好的选择是处理业务逻辑,如验证和数据转换,并将存储逻辑保留在单独的实例中

实际上,代码看起来有点像这样:

class User {
    private $db;
    private $user_id;
    private $username;
    private $email;

    [...]

    public function getUsername() {
        return $this->username;
    }

    public function setUsername($name) {
        $this->username = $name;
    }

    public function readDB() {
         $sth = $this->db->query("SELECT * FROM users WHERE id = ?", 
         array((int)$this->user_id));
         $user = $sth->fetch();
         if($user !== false && is_array($user)) {
             $this->username = $user['username'];
             $this->email = $user['email'];
             [...]
    }

    public function writeDB() {
        [...]
        $this->db->insert('users', array(
            'username' => $this->username
            'email' => $this->email), array('user_id' => $this->user_id)); 
    }
}
class User {
    private $db;

    [...]

    public function readDB($userID) {
         $sth = $this->db->query("SELECT * FROM users WHERE id = ?", 
         array((int)$userID));
         $user = $sth->fetch();
         return $user;
    }

    public function writeDB($userID, $username, $email ...) {
        $this->db->insert('users', array(
            'username' => $username
            'email' => $email), array('user_id' => $userID)); 
    }
}
$user = new Entity\User;
$user->setUsername('Drunk Lizard');

$mapper = new Mapper\User($pdo);
$mapper->fetch($user);

if (!$user->hasStatus(Entity\User::UNVERIFIED)) {
    throw new InvalidAction;
}

if (!$user->hasToken($request->get('token'))) {
    throw new WrongToken;
}

$user->setStatus(Entity\User::VERIFIED);
$mapper->store($user);

第一种方法违反了来自SOLID用户类的S,同时是DTO和DAO,第二种方法违反了来自SOLID的O,它返回一个数组,该数组打开以进行修改,关闭以进行扩展。第一种方法进展顺利,但您需要删除从实体获取数据的工作。创建一个执行持久性和数据访问的数据库类是一个不错的选择。或者给自己找一个好的老式数据库框架。有很多可供选择,并且都有其特殊的优点和难点。我使用Doctrine DBAL是因为它的开销非常轻。此类应仅用于结合用户管理工具读取和保存用户数据库表的数据。所有其他逻辑都由安全提供程序处理。这已经是某种数据映射器类,仅用于数据库操作。用户实体由Silex/Symfony的安全提供商处理。