0

所以我刚刚开始在课堂上编码,我还没有完全理解它。所以我理解 OOP 的概念,但我有一个问题。

我将“用户”存储在数据库中,并且我想要一个用户类来获取我可能想要的有关用户的信息并执行与“用户”对象相关的事情。我明白那个。

所以说我有一个用户类,具有属性用户名和电子邮件我有以下代码

<?php
    class User {
        private $username;
        private $email;

        public function __construct($username,$email) {
            $this->username=$username;
            $this->email=$email;
        }
    }
?>

现在我知道我应该有获取器和设置器来访问用户名和电子邮件。吸气剂,我明白。但是二传手——我需要这些吗?如果我这样做了,这些是否应该为该用户更新数据库中的该字段?我的电子邮件设置器会更新数据库以及 $this->email 吗?这似乎是一个愚蠢的问题,但我想把这个做对。

那么最后从数据库中获取用户并创建对象的最佳方法是什么?在别处说我想从 ID 50 创建一个用户对象 - 这将从数据库中获取 ID 为 50 的用户并使用数据库电子邮件和用户名字段构造一个用户对象,最好的方法是什么?

谢谢!

4

4 回答 4

2
  • 但是二传手——我需要这些吗?

这取决于。如果除了设置属性之外你不需要做任何事情,你可能不会使用一个。如果您需要检查提供的值是否匹配,例如,reg exp,或者不是太长/太短等,您可能需要一个。如果您有其他属性的设置器并且想要保留,您可能还需要一个一个统一的接口,不要记住哪个属性有或没有设置器。

  • 如果我这样做了,这些是否应该为该用户更新数据库中的该字段?

如果要修改多个属性,最好只访问一次数据库。一些数据库抽象库就是这样做的:

$user->name = 'whatever';
$suer->email = 'whatever';
$user->save(); // Execute the modify query.

访问/修改数据库中的数据是昂贵的。

  • 那么最后从数据库中获取用户并创建对象的最佳方法是什么?

例如,如果您使用的是 mysql,则可以使用:

$users = [ ];

while($row = $result->fetch_assoc()) {
    $user = new User;
    foreach($row as $field => $value) {
       $user->$field = $value;
    }
    $users[] = $user;
}

但是可能有更优雅的方法可以做到这一点。

于 2013-07-30T12:51:35.910 回答
2

Setter 用于设置对象属性值,在大多数情况下就是这样。有很多方法可以实现你想要的,基本上有关于这方面的书籍。我个人倾向于有如下场景:

1)使用setter设置对象属性

2) 调用单独的函数 commit()/save()/whatever() 将所有值写入数据库

从连续创建对象时,您最好有单独的工厂类(stackOverflow 中的好问题和答案 - PHP 中的工厂设计模式是什么?)。工厂类的思想是对象是不可变的,仅仅服务于数据容器的目的。我包含 PDO 只是为了演示目的,但当然还有其他方法(对于简单的用户表来说似乎很好)

class UserFactory
{
    private $db;

    public function __construct($db)
    {
        $this->db = $db;
    }

    public function fromID($id)
    {
        $userObject = new User();
        $q = $this->db->prepare("SELECT * FROM user WHERE u_id = :id");
        $q->bindValue(":id", $id);
        $q->setFetchMode( PDO::FETCH_INTO, $userObject);
        $q->execute();
        $q->fetch(PDO::FETCH_INTO);
        return $userObject;
    }

    public static function fromRow($row)
    {
        $userObject = new User();
        $userObject->setName($row['name']);
        $userObject->setEmail($row['name']);
        return $userObject;
    }
}

并且作为对象的集合

class UserCollection
{
    public static function getAllUsers($db)
    {
        $users = array();
        $q = $db->query("SELECT * FROM user");
        while($row = $q->fetch()){
            $users[] = UserFactory::fromRow($row);
        }
        return $users;          
    }
}

背后的想法是将数据库连接传递给静态方法,该方法将返回一个数组,其中包含从数据库初始化的所有用户对象。此处的 getAllUsers 方法是静态的,用于演示目的,当然也可以通过创建一个将数据库连接变量作为参数的构造函数来实现

于 2013-07-30T13:06:01.657 回答
1

您的第一个决定是是从类内的数据库中获取用户的属性还是从类外获取用户的属性。假设您在课堂外进行,那么您在构造中将没有任何参数,并且您可以:

$users = array();
while($row = $result->fetch_assoc()) {
    $user = new User();
    for($row as $field => $value) {
       $camelField = strtoupper(substr($field,0,1) . strtolower(substr($field, 1);
       $fieldClass = 'set' . $camelField;
       $user->{$fieldClass}($value);
    }
    $users[] = $user;
}

在你的课堂上,你会有像这样的二传手

public function setName(value) {
    $this-<name = $value;
}
于 2013-07-30T13:10:22.173 回答
0

关于如何持久化对象,主要有两种方法:

活动记录/表网关

使用这种方法,propertya 中的每个class都映射到field数据库中的某个table

由于您使用的是 PHP,如果您使用Zend_DbCodeIgniter Active Record ,您可能已经使用过此模式。

这种模式的问题是它可能不适合使用大量继承并且需要深度映射的复杂领域。此外,它通常将您的类与可能加剧测试的数据库紧密耦合。

参见:维基百科福勒

对象关系映射器 (ORM)

“ORM”是一个更繁重的解决方案,它让您可以纯粹使用“对象”并完全抽象出表/数据库层。

它还需要能够处理对象继承、组合、多态性,并且通常为引用对象的“延迟加载”提供一些功能。

PHP 的值得注意的“ORM”是(例如):DoctrinePropel

另见:维基百科

于 2013-07-30T13:24:52.767 回答