首页 > 解决方案 > oop php 什么是数据库访问的最佳实践?

问题描述

我编码是一种爱好,所以我没有接受过关于这个主题的正规教育,所以请原谅我这个问题。我确实对这个主题做了很多研究,但无法得到明确的答案。

我应该为 php 中的数据库访问选择什么类结构?

  1. 类 DatabaseObject 和每个表一个子类以及类 DatabaseObjectArray ,它扩展了 ArrayObject 并允许一次加载多个 DatabaseObjects。(我需要能够使用 foreach 或类似方法对其进行迭代) DatabaseObject 具有函数 load() 和 store()。

  2. 类 Database 和接口 DatabaseObject 其中每个表都与一个实现接口的类相关联。数据库可用于一次加载一个对象或数组中的多个对象。

sql应该在哪里完成?

如果我选择选项一,我会在 DatabaseObject 和 DatabaseObjectArray 之间有一些重复的代码,那么使用扩展的 PDO 类会更好吗?

例如,我想要一个名为 $conditions 的数组以及一个 addCondition($key, $value, $operator = '=') 函数,以便我可以首先定义条件,然后将数据加载()到对象中。 (sql 查询是根据 $conditions 组装的)我应该在 DatabaseObject 和 DatabaseObjectArray 中单独定义这些还是在 PDO 的扩展中定义这些?

  1. 或者我应该定义一个名为 DatabaseAccess 的特征,该特征将用于表类或选项 1 的两个基类中。

标签: phpmysqloop

解决方案


扩展PDO从来都不是“最佳实践”。实际上恰恰相反。并且特征只是一种代码气味,因为它们是解释器驱动的复制粘贴。

恕我直言,最好的方法是将业务逻辑和持久性逻辑分开。例如:您有一个执行用户逻辑的类和一个保存或填充此用户类实例的单独类。这种模式称为数据映射器

基本上设置是这样的:

$user = new Entity\User($id);
$mapper = new Mapper\User($pdo);

$mapper->fetch($user);
if ($user->isBanned() && $user->hasExpiredBan(new DateTimeImmutable)) {
    $user->removeBan();
    $mapper->store($user);
}

在这种情况下,映射器不会扩展 PDO,而是将其用作依赖项。至于如何与多个映射器共享同一个 PDO 实例,您可以查看这个旧帖子

对于如何实现映射器本身的简单示例,您可以查看此示例


推荐阅读