多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 创建core/database/model/Model.php ``` <?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 ``` <?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)