php模型映射接口,M 模型实现 (数据映射 + 原型 模式)

这篇博客介绍了如何创建一个自定义的ORM(对象关系映射)模型类和查询构造器,用于操作数据库。`Model.php`类包含了数据库连接、表名绑定、属性处理等核心功能,如设置和获取属性、跟踪数据变化。`Builder.php`类提供了查询构建功能,包括设置模型、执行SQL查询并把数据映射回模型实例。通过这种方式,可以方便地对数据进行操作,如`User`模型的实例可以直接调用查询方法。
摘要由CSDN通过智能技术生成

## 创建core/database/model/Model.php

```

namespace core\database\model;

class Model

{

// 绑定的数据库连接

protected $connection;

protected $table; // 表

protected $paimaryKey; // 主键

protected $timestamps = true; // 是否自动维护时间字段

/*

为什么要分开两个属性?

$orginal 原的数据

$attriubte 原数据的复制版 用户只能修改这个 !

然后跟$original相比较 得出用户修改的数据字段

*/

protected $original;

protected $attribute;

public function __construct()

{

// 给当前模型绑定一个数据库连接

$this->connection = \App::getContainer()->get('db')->connection(

$this->connection

);

}

// 获取表名称 没有表名称 就返回 模型(小写)+s

public function getTable()

{

if( $this->table)

return $this->table;

$class_name = get_class($this);

$class_arr = explode('\\',$class_name);

$table = lcfirst(end(

$class_arr

));

return $table .'s';

}

public function setOriginalValue($key, $val)

{

if(! $this->original)

$this->original = new \stdClass();

$this->original->$key = $val;

}

public function setAttribute($key, $val)

{

if(! $this->attribute)

$this->attribute = new \stdClass();

$this->attribute->$key = $val;

}

// 见最上面的说明

public function __set($key, $value)

{

$this->setAttribute($key, $value);

}

// 属性 同步 original

public function syncOriginal()

{

$this->attribute = $this->original;

}

/**

* 返回用户改过的数据

* @return array

* @example ['id' => 3,'user_id' => '3']

*/

public function diff()

{

$diff = [];

if( $this->attribute == $this->original) // 没改变

return $diff;

foreach ($this->original as $origin_key => $origin_val)

if( $this->attribute->$origin_key != $origin_val) // 改变了

$diff[$origin_key] = $this->attribute->$origin_key;

return $diff;

}

public function __get($name)

{

return $this->attribute->$name;

}

// 托管到 __call

//因此: User::where() 与 (new User)->where() 是一样的

public static function __callStatic($method, $args)

{

return (new static())->$method(...$args);

}

public function __call($method, $args)

{

return (new Builder(

$this->connection->newBuilder()

))

->setModel($this)

->$method(...$args);

}

}

````

## 创建core/database/model/Builder.php

```

namespace core\database\model;

class Builder

{

protected $query;

protected $model;

public function __construct($query)

{

$this->query = $query;

}

public function setModel(Model $model)

{

$this->model = $model;

return $this;

}

public function __call($method, $args)

{

$this->query->$method(...$args);

return $this;

}

public function get($columns = ['*'])

{

if(! is_array($columns))

$columns = func_get_args();

$this->query->columns = $columns;

$this->query->table( $this->model->getTable());

$sql = $this->query->toSql();

return $this->bindModel(

$this->query->runSql($sql)

);

}

// 数据映射模式 把数据映射到模型

//模型的本质: 每条数据都是一个模型(对象)

protected function bindModel($datas)

{

if(! is_array($datas))

$datas[] = $datas;

$models = [];

foreach ($datas as $data){ // 多少条数据就多少个模型

$model = clone $this->model; // 原型模式

foreach ($data as $key => $val)

$model->setOriginalValue($key, $val);

$model->syncOriginal(); // 把attriubtes = orginal

$models[] = $model;

}

return $models;

}

}

```

## 编辑app/User.php 继承模型基础类

![](https://img.kancloud.cn/a4/69/a469507e60982a6a0754d7e25682e78a_1311x630.png)

## 运行

由于每条数据都是一个类,所以可以调用方法。

![](https://img.kancloud.cn/8c/ed/8cedf0e02c378211d95918bf102adc13_553x156.png)

![](https://img.kancloud.cn/29/b3/29b33c1d7d2d2eec98d116a89372dd80_595x268.png)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值