所以我刚开始在课堂上编写代码,但我还没有完全理解它。所以我理解OOP的概念,但我有一个问题。
我有“用户”存储在数据库中,我想要一个用户类,它将获得我可能想要的关于用户的信息并执行与“用户”对象相关的事情。我明白了。
所以说我有一个用户类,具有属性用户名和电子邮件我有以下代码
<?php
class User {
private $username;
private $email;
public function __construct($username,$email) {
$this->username=$username;
$this->email=$email;
}
}
?>
现在我知道我应该有getter和setter来访问用户名和电子邮件。吸烟者,我明白了。但是建立者 - 我需要这些吗?如果我这样做,它们是否应该为该用户更新数据库中的该字段?我的电子邮件安装程序是否会更新数据库以及$ this-&gt;电子邮件?这可能看起来像一个愚蠢的问题,但我想要做到这一点。
那么最后从数据库中获取用户并创建对象的最佳方法是什么?在其他地方说我想从ID 50创建一个用户对象 - 这将从数据库中获取ID为50的用户并构建一个包含数据库电子邮件和用户名字段的用户对象,这样做的最佳方法是什么?
谢谢!
答案 0 :(得分:2)
这取决于。如果您不需要做除设置属性之外的任何操作,则可以不使用它。如果您需要检查提供的值是否匹配,例如,reg exp,或者不是太长/短等,您可以需要一个。如果您有其他属性的setter并且想要保留,那么您可能还需要一个一个统一的界面,不记得哪个属性有或没有setter。
如果要修改多个属性,最好一次只访问数据库。一些数据库抽象库就是这样做的:
$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;
}
但是可能会有更优雅的方法来做到这一点。
答案 1 :(得分:1)
Setter用于设置对象属性值,在大多数情况下就是这样。有很多方法可以实现你想要的东西,而且基本上有关于它的书籍。我个人倾向于有如下情况:
1)使用setter设置对象属性
2)调用一个单独的函数commit()/ save()/ whatever()将所有值写入数据库
从一行创建对象时,最好有单独的工厂类(stackOverflow中的好问题和答案 - What is a Factory Design Pattern in 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;
}
}
背后的想法是将数据库连接传递给静态方法,该方法将返回一个数组,其中包含从数据库初始化的所有User对象。 这里的getAllUsers方法对于demontration来说是静态的,当然可以通过创建一个以数据库连接变量作为参数的contstructor来实现相同的目的
答案 2 :(得分:0)
您的第一个决定是从类中的数据库获取用户的属性,还是从课外进行。让我们说你是在课外做的,然后你就不会在构造中有任何参数,你可以:
$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;
}
答案 3 :(得分:0)
如何持久保存对象主要有两种方法:
使用此方法,property
中的每个class
都会映射到数据库field
上的某个table
。
由于您使用的是PHP,如果您使用 Zend_Db 或 CodeIgniter Active Record ,则可能已使用此模式。
这种模式的问题在于它可能不适用于使用大量继承并且需要深入映射的复杂域。此外,它通常将您的类与数据库紧密结合,这可能会加剧测试。
'ORM'是一个更重的解决方案,它让你纯粹使用'对象',并完全抽象出表/数据库层。
它还需要能够处理对象继承,组合,多态,并且通常为引用对象的“延迟加载”提供一些功能。
值得注意的是'PHP的ORM是(例如): Doctrine 和 Propel 。
另请参阅:Wikipedia