OOP设计:如何将DB处理合并到应用程序对象中

Álv*_*lez 5 php database oop

这是我经常遇到的设计问题,我想找到关于这个主题的一些一般见解.这里提供的代码只是一个例子.

在设计阶段,很容易确定您需要一个对象:

User
==========
Unique ID
Login name
Password
Full name
Run Code Online (Sandbox Code Playgroud)

并且很容易将其转换为数据库对象:

CREATE TABLE user (
    user_id INT NOT NULL PRIMARY KEY,
    username VARCHAR(15) NOT NULL UNIQUE,
    password_hash CHAR(32) NOT NULL,
    full_name VARCHAR(50)
);
Run Code Online (Sandbox Code Playgroud)

我怀疑从PHP级别开始.明显的转换是:

<?php
class User{
    public $user_id, $username, $full_name;
}
?>
Run Code Online (Sandbox Code Playgroud)

但是,我应该如何填写实际值?

我可以保持类DB不可知:

<?php
class User{
    public $user_id, $username, $full_name;
    public function __construct($user_id, $username, $full_name){
        $this->user_id = $user_id;
        $this->username = $username;
        $this->full_name = $full_name;
    }
}
?>
Run Code Online (Sandbox Code Playgroud)

但后来我需要在其他地方运行查询......

我可以将它封装在类构造函数中:

<?php
class User{
    public $user_id, $username, $full_name;
    public function __construct($user_id){
        $sql = 'SELECT username, full_name FROM user WHERE user_id=?';
        $parameters = array($user_id);
        $res = get_row_from_db($sql, $parameters);

        $this->user_id = $user_id;
        $this->username = $res['username'];
        $this->full_name = $res['username'];
    }
}
?>
Run Code Online (Sandbox Code Playgroud)

这看起来很优雅,但它阻止我在课堂上做很多东西:

  • 通过用户名和密码验证用户($ user_id尚未知)
  • 从论坛帖子打印用户信息(我无法承受100个查询以显示100个用户)

最有可能的是,我需要定义几个类,但我不确定如何组织它.一个基类和许多子类?独立课程?单班有特定方法吗?也许这是一个众所周知的设计模式,但我教过程序编程.

我也很感激一些想法:

  • 处理用户集合
  • 在会话中存储信息,因此不需要在每个页面请求上查询数据库

====记录====

我已经标记了戈登的答复,因为答案提供了有趣的阅读.无论如何,值得注意的是,我在PHP手册的对象序列化页面中的一个用户注释中找到了一个非常具有说明性的代码片段,可以总结如下:

  • 它使用一个类.
  • 实例表示特定用户.
  • 构造函数被提供用户详细信息.
  • 该类提供了在能够拥有实例之前所需的功能的静态方法,例如,通过ID或名称从DB获取用户.
  • 用户实例可以序列化为会话数据.

不是OOP大师,我发现它非常简单但干净且有用.OOP文本倾向于使简单任务过于复杂,我的日常工作主要包括小项目.

Gor*_*don 7

这取决于您的架构.四种常见的数据源架构模式中可以找到马丁·福勒企业应用架构模式:

  • 表数据网关

    充当数据库表的网关的对象.一个实例处理表中的所有行.

  • 行数据网关

    一个对象,充当数据源中单个记录的网关.每行有一个实例.

  • 积极记录

    在数据库表或视图中包装行的对象,封装数据库访问,并在该数据上添加域逻辑.

  • 数据映射器

    一层Mappers,它在对象和数据库之间移动数据,同时保持它们彼此独立以及映射器本身.

更多模式: