## 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.hmoore.net/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.實例演示