如何使用 pdo 作为 getter 来最好地获取数据
Posted
技术标签:
【中文标题】如何使用 pdo 作为 getter 来最好地获取数据【英文标题】:How to best fetch data with pdo as a getter 【发布时间】:2013-10-17 07:53:42 【问题描述】:我希望你们能对我的问题有所了解。我需要的基本上是从数据库行(实例获取器)获取和分配属性的最佳实践。这是一个非常标准的问题,我知道它在 C# 中是如何工作的,但我不清楚如何在 php 中完成类似的结果,也没有找到任何满足我需求的在线解决方案。
假设我有这个简化的代码:
Class User
private $Pdo;
private $UserID;
private $UserName;
function GetUserName()
return $this->UserName;
function GetUserInfo()
// return user object with given user id, in this example just use "1"
$Pdo = $this->Pdo;
$Query = $Pdo->query('select * from User where UserID = 1');
$Query->setFetchMode(PDO::FETCH_CLASS, "User", array($Pdo) ); // this is returning object
$UserInfo = $Query->fetch();
return $UserInfo;
然后,当我想获取用户对象时,我会这样称呼它:
$User = new User($Pdo);
$UserInfo = $User->GetUserInfo();
echo $UserInfo->GetUserName();
这行得通,但是我不喜欢这样做。一种选择是使用静态方法,所以最后我会得到类似的结果:
$UserInfo = User::GetUserInfo()
我认为这被称为“单身人士”(编辑:不是单身人士:)),通常被认为是不好的做法。
我的问题是它应该是什么样子?我想要的是这样的:
$UserInfo = new User($Pdo);
$UserInfo->GetUserInfo();
echo $UserInfo->GetUserName();
我知道在 GetUserInfo 方法中我可以手动将值分配给当前对象 ($this),例如:
function GetUserInfo()
// get data from db
$this->UserName = "John"; // this value I will get from db
但是我想使用 FetchClass,这样我就可以在一行中根据它们的名称获取所有属性,而不是手动分配它们。我希望你明白我的问题是什么:) 我很想听听你对什么是最好的方法的意见。
非常感谢您的任何意见。
【问题讨论】:
User::GetUserInfo()
不是单例,而是静态方法。单例只是只允许实例化一次的对象。
好的,不知道 :) 我看到类似的例子并认为是它。
【参考方案1】:
朝着最佳实践和良好设计方向迈出的一步是将域模型和持久层分开。
因此,您可以独立于所使用的数据库,甚至可以使用 Web 服务替换数据库。看Data Mapper pattern。
因此,您的 User
模型将仅包含属性 + getter/setter 以及以某种方式使用这些属性的方法(业务逻辑)。
class User
protected $UserID;
protected $UserName;
public function getUserId()
return $this->UserID;
public function setUserId($userId)
$this->UserID = userId;
return $this;
...
您的映射器持有数据库连接并负责保存/获取User
对象。
class UserMapper
protected $_pdo;
public function __construct($pdo)
$this->_pdo = $pdo;
public function getUserById($id)
// TODO: better use prepared statements!
$query = $this->_pdo->query("select * from User where UserID = ".id);
$query->setFetchMode(PDO::FETCH_CLASS, "User");
return $query->fetch();
public function save(User $user)
// insert/update query
...
你可以像这样使用它:
$userMapper = new UserMapper($pdo);
$user = $userMapper->getUserById(1);
echo $user->getUserName();
$user->setUserName('Steve');
$userMapper->save($user);
还有其他类似的模式,例如表网关模式。但我更喜欢数据映射器,因为数据源的独立性。
查看 Martin Fowler 的整个目录:Catalog of Patterns of Enterprise Application Architecture
另一个有用的帖子:What is the difference between the Data Mapper, Table Data Gateway (Gateway), Data Access Object (DAO) and Repository patterns?
【讨论】:
您好,谢谢您的回答。我想我可以试试这个。我正在考虑创建 UserInfoProvider 来获取对象,并且您向我确认这应该是一种合理的方法。 我有一个问题 - 我阅读了这篇文章,它指出基本上我的 User 类中甚至没有任何 PDO (Sql) 语句。那么,如果我有一个在给定用户存在的情况下返回真/假的方法,我该怎么办。我必须使用 PDO 和 SQL 来检查用户是否存在于数据库中。但是我必须在 UserClass 中使用这种方法,这对我来说似乎“过于复杂”.. 是的,User 类对持久层一无所知。如果用户不存在,getUserById
方法应该已经返回 null
。否则,您可以在映射器中创建类似 userExists($userName)
的方法,该方法返回 true 或 false。但是您是对的,通常使用数据映射器或 ORM 方法存在一些缺陷。另一种选择是使用现成的 ORM 系统,例如 doctrine,它已经解决了许多问题。
一定会去看看的。非常感谢您的宝贵时间。很好的答案。
您好,感谢您的出色回答。我想如果我创建 getUserById(), getUserByName(), getUserNameByID(), ... 那么方法太多了。你有什么想法吗?以上是关于如何使用 pdo 作为 getter 来最好地获取数据的主要内容,如果未能解决你的问题,请参考以下文章
Firestore、vue、vuex、vuexfire:如何让 getter 真正从存储中获取数据?