【问题标题】:How to query database from a OOP point-of-view如何从 OOP 的角度查询数据库
【发布时间】:2017-08-07 11:23:52
【问题描述】:

大家好

我知道 Stackoverflow 可能不是问的正确地方,如果有另一个 Stackexchange 组在哪里 这个问题比较合适,那么请告诉我。

所以,我正在努力学习 OOP。我想我理解得很好,但有一件事我真的想不通 找出正确的方法是什么,那就是数据库的处理。

所以,我有点困惑应该在哪个班级上学。

假设我有一个 db 类。在这个类中,我在构造函数中连接到数据库。现在让我们说 我有一个用户类。

那么现在的问题是: 我应该在哪里输入查询,例如创建一个新用户?我应该在用户类中创建一个方法, 或者我应该在 DB 类中创建一个方法?如果在 DB 类中,它真的应该是像create_user() 这样的方法吗? 或者它应该更像是query 这样的全球性的东西,我可以在其中传递我想要的任何查询。

这里,例如来自 Github 的一个项目:

https://github.com/christran/PHP-OOP-Login-Register-System/blob/master/classes/user.php

如您所见,所有查询方法都在 db.php 中,而从 user.php 他只是在调用这些方法。那么这是正确的方法吗?

或者根本不重要?可能,这些方法中的任何一个都比另一个“更多”OOP?

这实际上让我很困惑,我不明白有什么更好的方法。我搜索了很多,但从来没有 找到一篇关于这个特定问题的文章。

所以我做了什么,我在 Github 上寻找项目并查看他们的代码,他们是如何解决问题的...... 但是使用这种方法,我只会更加困惑,因为你看到了两者。

这只是编码人员的偏好吗?

非常感谢您的帮助。祝你今天过得愉快! :)

这是我的意思的一个小例子:

在用户类中查询:

class user {
    private function createUser() {
        //SQL Query here (prepared statements etc...)
    }
}

或者:

class user {

    private function createUser() {
        // Call to db.class to insert_method() ...
    }
}

【问题讨论】:

  • 对象关系映射不是 OOP。 OOP 是将系统分解为可通信的状态机。 ORM 是关于重塑网络数据模型的,因为开发人员不了解数据的关系模型。最好将数据库视为事实的代表,而不是对象的代表。

标签: php database oop mysqli pdo


【解决方案1】:

包含查询的 createUser 方法不应该是 User 对象的一部分,但也不应该是数据库对象的一部分。第一个用于业务逻辑。后者用于管理数据库方法并提供执行语句的通用功能。这些对象之间的不同对象应该是从用户对象获取数据并生成查询以将其存储在数据库中的对象。

我认为您在这里寻找的术语是ORM (Object-relational mapping)

这个概念是关于将对象映射到不同的、不兼容的结构,例如数据库。

有一些可用于 PHP 的 ORM 库/框架可以为您完成大部分工作,其中一些是流行的 MVC 框架的一部分,或者可以与 Eloquent ORM in Laravel 等流行的 MVC 框架一起使用。例如,他们通常会通过在您配置正确的数据库表后执行所需的 SQL 语句来提供基本的CRUD 操作。

就 OOP 而言,您通常会在其之上添加一个额外的层。所以你有一个业务对象用户,它包含用户的规则,例如它必须遵循的用户名规则。业务对象将强制执行这些规则并包含用户对象的一般行为。为了保存,您可以使用 ORM 将用户对象保存到特定数据库。数据库逻辑不在用户对象本身中。它不应该知道要保存自己的特定查询,也许它甚至不应该知道加载和保存之类的概念。它只包含逻辑和数据,实现的其他部分负责持久化该数据(可选地使用 ORM 框架使事情变得更容易)。

【讨论】:

    【解决方案2】:

    基本上,您正在研究 ORM。

    为了具体回答你的问题,

    我应该在用户类中创建一个方法

    这是可能的,称为活动记录模式,其中一个实体不仅包含与自身相关的方法(如$user->getBirthday()),还包含与数据库交互相关的方法(如$user->save())。

    或者我应该在 DB 类中创建一个方法?

    这是不可能的,因为这个类会变得非常庞大。

    但是,您可以为每个实体创建一个姊妹类,该类将负责数据库交互。这种方法称为数据映射器模式。例如,有一个 User 类,其中包含与用户相关的方法,还有一个 UserMapper 类,它继承自抽象映射器类,具有泛型方法$userMapper->save()$userMapper->find() 等。

    【讨论】:

    • 我有一个问题。我只是查看了来自 OP 的链接 github repo 并查看了 db 类。 github.com/christran/PHP-OOP-Login-Register-System/blob/master/… 这个类很短,因为他只有一个“插入”方法并将查询传递给方法。因此,所有查询的一种方法。这样一来,班级就不会变大。这是不好的做法吗?
    • @Twinfriends 对不起,我不明白你的问题。
    • 好的,让我再试一次。 :P 如果你继续我评论中链接的 git repo,你会看到一个 db.php 文件。向下滚动到第 73 行。有一个名为“insert”的方法 - 一种在 db 类中插入数据的方法。整个项目中的每一个查询都是由这种方法处理的。这是好还是坏的做法?如您所见,他将表名和键值对传递给函数。这是整个项目中唯一将数据插入数据库的功能。这就是我的问题,如果这是个好主意,或者我是否应该创建更多方法,如 createUser、createItem 等。
    • @Twinfriends 看起来不是很客观。据我所知,您不想使用 User 类,而只是使用 DB 类在整个代码中运行 SQL 查询。好吧,这当然是可能的,但这里的主题相当离题,因为 OP 正在专门询问他的 User 类。
    • 非常感谢您花时间回答我:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多