## Model.php 部分源码分析
* public function db($baseQuery=true):获取查询对象,用在普通方法中;
* public static function getDb():获取查询对象,用在静态方法中;
* public function __call($method,$args):魔术调用不存在方法;
* public static funciton __callStatic($method,$args):魔术静态调用不存在方法;
>[info] 这些方法之间的相互配合,最终完成了模型到数据库查询的映射!所以,数据库查询操作是模型操作的基础:
* 理达课堂数据库操作教程:http://www.kancloud.cn/ldkt/tp5_db :点击查看
* * * * *
#### 1. Model类部分方法介绍
1. db()方法源码:
* 功能:快速获取当前模型对应的数据库查询对象:Query。
* 备注:可以理解为【模型】与【数据库】之间的访问接口。
>[warning] 为了使学员更快的读懂源码,作者单独添加了大量注释
~~~
/**
* 获取当前模型的数据库查询对象
* 实现过程:通过Connect连接对象model方法获取Query对象,然后调用Query对象中
* 对应的方法如:setTable(设置默认表),name(设置无前缀表名),pk主键属性
* 注意:只需要设置【表名和主键】,就可实现与模型与对应表的绑定
* @access public
* @param bool $baseQuery 是否调用全局查询范围
* @return Query
*/
public function db($baseQuery = true)
{
//先获取到当前模型对象的类名做为模型名
//如:你自定义的模型类为:Staff.php,那么
// $this->class 就等于 :Staff
$model = $this->class;
if (!isset(self::$links[$model])) {
// 设置当前模型 确保查询返回模型对象
// Connection.php类中model方法:创建指定模型的查询对象
// Connection.php里model($model, $queryClass = '')
// $model 模型类名称 $queryClass 查询对象类名 返回:Query
$query = Db::connect($this->connection) //返回Connect类的对象例:创建连接
->model($model, $this->query);
// 设置当前数据表和模型名
if (!empty($this->table)) {
$query->setTable($this->table); //设置表全名
} else {
$query->name($this->name); //设置表简名(无后缀)
}
if (!empty($this->pk)) { //设置主键
$query->pk($this->pk);
}
//给数据库连接池中$model键赋值为当前对象
self::$links[$model] = $query;
}
// 全局作用域
if ($baseQuery && method_exists($this, 'base')) {
call_user_func_array([$this, 'base'], [ & self::$links[$model]]);
}
// 返回当前模型的数据库查询对象
// 注意返回值写法:当前类的静态属性,返回值为所有模型对象共享
//以后就可以直接用: 模型::数据库连贯方法,例如:Staff::where()->find();
return self::$links[$model];
}
~~~
>[warning] 虽然通过db( )方法获取了到了数据库查询对象,但是所调用的数据操作连贯方法返回的仍然是模型对象?这是为什么呢?因为连贯方法中最后都是返回当前调用对象:return $this; 而此时,调用这些方法的是模型对象,因此返回的也是模型对象,所以在后面仍然可以接着调用模型方法!
* * * * *
2. getDb( )方法源码
* 与db( )方法一样,也是返回一个数据库查询对象:Query
>[info] 由于 getDb( )是静态方法,可以用在模型静态调用中。而前面介绍的db( )方法是普通方法,不能用在模型静态调用中。
~~~
//与db()方法类似,同样返回一个数据库查询对象
protected static function getDb()
{
//获取调用该方法的模型类名:如User
$model = get_called_class();
//如果在数据库对象池中存在这个模型类
if (!isset(self::$links[$model])) {
//new static():获取当前模型对象,再调用db()方法创建查询对象
//本类静态属性$links[$model]中存入当前模型的查询对象
self::$links[$model] = (new static())->db();
}
//返回与当前模型关联的数据库查询对象
// self::$links[$model] 数组元素值是一个查询对象:(new Query)
return self::$links[$model];
}
~~~
* * * * *
3. __call( )方法
>[info] __call( )是PHP的魔术方法,当对象调用一个不存在的方法时,自动触发这个方法。该方法可以实现跨类动态调用,很实用。
~~~
//__call:当调用不存在的方法时,自动调用
public function __call($method, $args)
{
$query = $this->db();
if (method_exists($this, 'scope' . $method)) {
// 动态调用命名范围
$method = 'scope' . $method;
array_unshift($args, $query);
call_user_func_array([$this, $method], $args);
return $this;
} else {
return call_user_func_array([$query, $method], $args);
}
}
~~~
* * * * *
4. __callStatic( )
>[info] 与__call( )一样,也是PHP魔术方法。当调用的静态方法不存在或权限不足时,自动调用。这个方法与call_user_func_array( )结合,简直太奇妙了!
~~~
public static function __callStatic($method, $params)
{
//getDb()方法可获取查询对象,这里为什么不用db()方法呢?因为这是静态魔术方法
//静态方法内部,只能调用静态方法,所以要用:getDb()方法
$query = self::getDb();
//call_user_func_array([类,方法],参数数组):实现动态方法调用
return call_user_func_array([$query, $method], $params);
}
~~~
>[warning] 本章第3节有详细介绍,这里就不再多说了!
* * * * *
### 总结:
>[success] 本节精选了4个Model类的方法,很有代表性:
> 1. 二个普通方法:db( ),__call( ),二个静态方法;getDb( )和__callStatic( );
> 2. 普通魔术方法__call( )中调用普通方法db( ),来获取查询对象;
> 3. 静态魔术方法__callStatic( )中调用静态方法getDb( )来获取查询对象。
- 前言[随时更新]
- 开发环境
- 1.Mac环境
- 2.windows环境
- 模型对象
- 1.创建模型对象
- 2.模型初始化
- 数据对象
- 1.定义数据对象
- 2.创建数据对象
- 1.data方法
- 2.setAttr方法
- 3.__set方法
- 4.查询数据对象
- 1.getData方法
- 2.getAttr方法
- 3.__get方法
- OOP难点总结
- 1.get_class( )实例讲解
- 2.get_called_class( )实例讲解
- 3.__call( )实例讲解
- 3.__callStatic( )实例讲解
- 4.call_user_func_array函数[重点]
- 5.普通方法与静态方法
- 6.在Model源码中的应用
- 7.new static 延迟静态绑定
- PHP标准化规范
- 查询数据
- 1.获取单条:get静态方法
- 2.获取单条:对象查询
- 3.获取多条:all静态方法
- 4.获取多条:对象查询
- 5.获取字段值:value方法
- 6.获取列值:column方法
- 7.动态查询:getBy字段名
- 8.助手函数:model查询
- 9.加载器:Loader类查询
- 10.数据库与模型查询对比
- 新增数据
- 1.sava方法
- 2.savaAll方法
- 3.create静态方法
- 4.insert静态调用
- 更新数据
- 1.单条更新:save方法
- 2.批量更新:saveAll方法
- 3.静态更新:update方法
- 4.查询类Query直接更新
- 5. 闭包更新
- 删除数据
- 1.删除当前记录:delete
- 2.静态条件删除:destory
- 获取器
- 1.模型方法:set属性Attr
- 修改器
- 1.set属性Attr
- 时间戳
- 1.MySQL中日期类型复习
- 2.时间戳功能详解
- 软删除[重点]
- 1.traits详解[选学内容]
- 2.SoftDelet类源码分析
- 3. delete实例删除
- 4.destroy条件删除
- 5.restore恢复数据
- 类型转换
- 1. 规则设置
- 2. 实例演示
- 查询范围
- 1. 基本概念
- 2.实例演示