多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## 1 新模型解读 TP5RC3中重点更新了Model的功能。 新的Model是**TP5设计目标——为API开发而设计**的核心功能。 新的Model与以前版本的功能完全不同,下面进行分析。 ## 2 新模型源代码 ### 2-1 Model类的声明 ~~~ ;声明Model为抽象类并实现序列化接口和数组访问接口功能 abstract class Model implements \JsonSerializable, \ArrayAccess {} ~~~ ### 2-2 成员变量 ~~~ ;数据库模型数组,数据库连接配置,模型操作的表,回调事件 private static $links = []; protected static $connection = []; protected static $table; protected static $event = []; ;模型操作表的主键,数据表操作的错误信息,自定义模型名称,字段验证规则 protected $pk; protected $error; protected $name; protected $validate; ;字段属性信息数组,待操作数据数组,缓存数据数组,修改字段数组 protected $field = []; protected $data = []; protected $cache = []; protected $change = []; ;自动完成数组,新增自动完成数组,更新自动完成数组,自动写入时间戳数组,时间戳默认格式 protected $auto = []; protected $insert = []; protected $update = []; protected $autoTimeField = ['create_time', 'update_time', 'delete_time']; protected $dateFormat = 'Y-m-d H:i:s'; ;字段类型或格式转换数组,是否为更新操作,模型对应关联对象,当前模型的父模型,模型实例数组 protected $type = []; protected $isUpdate = false; protected $relation; protected $parent; protected static $initialized = []; ~~~ ### 2-3 public成员方法 #### 1 __construct() 创建模型实例 ~~~ public function __construct($data = []) ~~~ > $data 模型的数据参数 ~~~ ;创建对象传入$data参数 $user = new User(['name'=>'thinkphp','email'=>'thinkphp@qq.com']); $user->save(); ;实例化模型,设置$this->data['name']为'thinkphp',调用save()更新数据 $user = new User; $user->name= 'thinkphp'; $user->save(); ~~~ #### 2 data() 设置数据对象值 ~~~ public function data($data = '') ~~~ > $data 操作数据参数 ~~~ ;设置模型的$data $user = new User; $user->data(['name'=>'thinkphp','email'=>'thinkphp@qq.com']); $user->save(); ~~~ #### 3 getData() 获取对象原始数据 ~~~ public function getData($name = '') ~~~ > $name 数据的键名 在定义了getXXAttr()时使用获取原始数据 #### 4 toArray() 将数据转换为数组 ~~~ public function toArray() ~~~ #### 5 getPk() 获取模型的主键信息 ~~~ public function getPk($table = '') ~~~ #### 6 save() 更新数据到数据库 ~~~ public function save($data = [], $where = [], $getInsertId = true) ~~~ > $data 插入的数据 > $where 更新条件 > $getInsertId 是否获取自增主键 ~~~ ;传入数据更新 $user = new User; $user->save(['name' => 'thinkphp'],['id' => 1]); ;使用模型数据更新 $user = User::get(1); $user->name = 'thinkphp'; $user->save(); ;使用闭包实现复杂条件 $user = new User; $user->save(['name' => 'thinkphp'],function($query){ // 更新status值为1 并且id大于10的数据 $query->where('status',1')->where('id','>',10); }); ~~~ #### 7 saveAll() 修改多个数据到数据库 ~~~ public function saveAll($dataSet) ~~~ > $dataSet 待插入数据集合 #### 8 allowField() 设置运行更新的字段 ~~~ public function allowField($field) ~~~ #### 9 isUpdate() 检查当前操作是否为更新操作 ~~~ public function isUpdate($update = true) ~~~ #### 10 delete() 对数据进行删除处理 ~~~ public function delete() ~~~ ~~~ ;删除模型数据 $user = User::get(1); $user->delete(); ~~~ #### 11 auto() 设置自动完成字段,在autoCompleteData中检查 ~~~ public function auto($fields) ~~~ ~~~ class User extends Model{ protected $auto = [ 'update_time']; protected $insert = [ 'create_time','name','status'=>1 ]; protected $update = ['name']; protected function setNameAttr($value){ return strtolower($value); } } $user = new User; $user->name = 'ThinkPHP'; $user->save(); echo $user->name; // thinkphp echo $user->create_time; // 14601053899 ~~~ #### 12 validate() 设置自动验证规则 ~~~ public function validate($rule = true, $msg = []) ~~~ > $rule 验证规则 > $msg 提示信息 使用见 验证类分析 #### 13 validateData() 对当前data进行验证处理 ~~~ public function validateData() ~~~ #### 14 getError() 获取操作错误信息 ~~~ public function getError() ~~~ #### 15 event() 注册事件回调接口 ~~~ public static function event($event, $callback, $override = false) ~~~ >$event 事件名称 > 支持的事件类型,在模型操作过程中会进行回调before_delete、after_delete、before_write、after_write、before_update、after_update、before_insert、after_insert > $callback 事件回调接口 ~~~ ;注册before_insert事件, User::event('before_insert',function($user){ if($user->status != 1){ return false; } }); ~~~ #### 16 create() 写入数据 ~~~ public static function create($data = []) ~~~ > $data 待写入数据 ~~~ User::create(['name'=>'thinkphp','email'=>'thinkphp@qq.com']); ~~~ #### 17 update() 更新数据 ~~~ public static function update($data = [], $where = []) ~~~ > $data 待更新数据 > $where 更新条件 ~~~ User::where('id',1)->update(['name' => 'thinkphp']); ~~~ #### 18 get() 数据查询 ~~~ public static function get($data = '', $with = [], $cache = false) ~~~ ~~~ $user = User::get(1); echo $user->name; // 使用闭包查询 $user = User::get(function($query){ $query->where('name','thinkphp'); }); echo $user->name; ~~~ #### 19 all() 查询多个记录 ~~~ public static function all($data = [], $with = [], $cache = false) ~~~ ~~~ // 根据主键获取多个数据 $list = User::all('1,2,3'); // 或者使用数组 $list = User::all([1,2,3]); foreach($list as $key=>$user){ echo $user->name; } // 使用闭包查询 $list = User::all(function($query){ $query->where('status',1)->limit(3)->order('id','asc'); }); foreach($list as $key=>$user){ echo $user->name; } ~~~ #### 20 destroy() 删除记录 ~~~ public static function destroy($data) ~~~ ~~~ User::destroy(1); // 支持批量删除多个数据 User::destroy('1,2,3'); // 或者 User::destroy([1,2,3]); ;闭包删除 User::destroy(function($query){ $query->where('id','>',10); }); ~~~ #### 21 scope() 设置命名范围 ~~~ public static function scope($name, $params = []) ~~~ ~~~ class User extends Model{ public function scopeThinkphp($query){ $query->where('name','thinkphp')->field('id,name'); } public function scopeAge($query){ $query->where('age','>',20)->limit(10); } } // 查找name为thinkphp的用户 User::scope('thinkphp')->get(); // 查找年龄大于20的10个用户 User::scope('age')->all(); // 查找name为thinkphp的用户并且年龄大于20的10个用户 User::scope('thinkphp,age')->all(); User::scope(function($query){ $query->where('age','>',20)->limit(10); })->all(); $user = new User; // 查找name为thinkphp的用户 $user->thinkphp()->get(); // 查找年龄大于20的10个用户 $user->age()->all(); // 查找name为thinkphp的用户并且年龄大于20的10个用户 $user->thinkphp()->age()->all(); ~~~ #### 22 has() hasWhere() 在关联中进行查找 ~~~ public static function has($relation, $operator = '>=', $count = 1, $id = '*') public static function hasWhere($relation, $where = []) ~~~ #### 23 relationQuery() 执行关联查询 ~~~ public function relationQuery($relations) ~~~ #### 24 getRelationInfo() 获取关联信息 ~~~ public function getRelationInfo($name = '') ~~~ #### 25 eagerlyResultSet() eagerlyResult()预载入关联查询 ~~~ public function eagerlyResultSet($resultSet, $relation) public function eagerlyResult($result, $relation) ~~~ #### 26 hasOne() belongsTo() hasMany() belongsToMany() 关联定义 ~~~ ;一对一关联 public function hasOne($model, $foreignKey = '', $localKey = '') ;相对关联 public function belongsTo($model, $foreignKey = '', $otherKey = '') ;一对多关联 public function hasMany($model, $foreignKey = '', $localKey = '') ;多对多关联 public function belongsToMany($model, $table = '', $localKey = '', $foreignKey = '') ~~~ ~~~ ;一对一关联 class User extends Model { public function profile() { return $this->hasOne('Profile'); } } $user = User::find(1); // 输出Profile关联模型的email属性 echo $user->profile->email; ;自定义关联外键 namespace app\index\model; use think\Model; class User extends Model { public function profile() { return $this->hasOne('Profile','uid'); } } ;关联查询 // 查询有档案记录的用户 $user = User::has('profile')->find(); // 查询年龄是20岁的用户 $user = User::hasWhere('profile',['age'=>'20'])->select(); ;关联新增 $user = User::find(1); // 如果还没有关联数据 则进行新增 $user->profile->email = 'thinkphp'; $user->profile->save(); // 或者 $user->profile->save(['email' => 'thinkphp']); ;关联更新 $user = User::find(1); $user->profile->email = 'thinkphp'; $user->profile->save(); // 或者 $user->profile->save(['email' => 'thinkphp']); ~~~ ~~~ ;相对关联定义 class Profile extends Model { public function user() { return $this->belongsTo('User'); } } 相对关联查询 $profile = Profile::find(1); // 输出User关联模型的属性 echo $profile->user->account; ~~~ ~~~ ;一对多关联定义 class Article extends Model { public function comments() { return $this->hasMany('Comment'); } } ;一对多自定义主键 class Article extends Model { public function comments() { return $this->hasMany('Comment','art_id'); } } ;关联查询 $article = Article::find(1); // 获取文章的所有评论 dump($article->comments); // 也可以进行条件搜索 dump($article->comments()->where('status',1)->select()); // 查询评论超过3个的文章 $list = Article::has('comments','>',3)->select(); // 查询评论状态正常的文章 $list = Article::hasWhere('comments',['status'=>1])->select(); ;关联新增 $article = Article::find(1); // 增加一个关联数据 $article->comments()->save(['content'=>'test']); // 批量增加关联数据 $article->comments()->saveAll([ ['content'=>'thinkphp'], ['content'=>'onethink'], ]); ~~~ ~~~ ;多对多关联 class User extends Model { public function roles() { return $this->belongsToMany('Role'); } } ;关联查询 $user = User::get(1); // 获取用户的所有角色 dump($user->roles); // 也可以进行条件搜索 dump($user->roles()->where('name','admin')->select()); ;关联新增 $user = User::get(1); // 增加关联数据 会自动写入中间表数据 $user->roles()->save(['name'=>'管理员']); // 批量增加关联数据 $user->roles()->saveAll([ ['name'=>'管理员'], ['name'=>'操作员'], ]); ;单独新增中间表 $user = User::get(1); // 仅增加关联的中间表数据 $user->roles()->save(1); // 或者 $role = Role::get(1); $user->roles()->save($role); // 批量增加关联数据 $user->roles()->saveAll([1,2,3]); ;单独更新中间表 $user = User::get(1); // 增加关联的中间表数据 $user->roles()->attach(1); // 传入中间表的额外属性 $user->roles()->attach(1,['remark'=>'test']); // 删除中间表数据 $user->roles()->detach([1,2,3]); ~~~ #### 27 db() 初始化模型的数据库对象 ~~~ public static function db() ~~~ #### 28 __call() __callStatic() __set() __get() __isset() __unset() __toString() __wakeup()拦截方法 ~~~ ;实例对象调用支持 public function __call($method, $args) ;类静态调用支持 public static function __callStatic($method, $params) ;修改数据$this->data public function __set($name, $value) ;获取数据$this->data public function __get($name) ;检查数据是否存在 public function __isset($name) ;删除数据 public function __unset($name) ;字符串输出 public function __toString() ;解序列化后处理 public function __wakeup() ~~~ #### 29 jsonSerialize() 序列化接口实现 ~~~ public function jsonSerialize() ~~~ > json序列化输出数据$data ~~~ echo json_encode(User::find(1)); {"id":"1","name":"","title":"","status":"1","update_time":"1430409600","score":"90.5"} ~~~ #### 30 offsetSet() offsetExists() offsetUnset() offsetGet()数组访问支持 ~~~ public function offsetSet($name, $value) public function offsetExists($name) public function offsetUnset($name) public function offsetGet($name) ~~~ ~~~ $user = User::find(1); echo $user->name ; // 有效 echo $user['name'] // 同样有效 $user->name = 'thinkphp'; // 有效 $user['name'] = 'thinkphp'; // 同样有效 $user->save(); ~~~ ### 2-4protected成员方法 ~~~ protected function initialize() ;模型初始化接口 protected static function init() ;模型初始化回调 protected function isPk($key) ;判断$key是否为主键 protected function autoCompleteData($auto = []) ;处理字段更新字段列表 protected function trigger($event, &$params) ;触发注册的事件回调 protected static function parseQuery(&$data, $with, $cache) ;分析查询表达式 protected function parseModel($model) ;解析模型的命名空间 ~~~ ## 3 新模型总结