thinkphp5原始碼解析 1 資料庫

2022-01-20 02:21:20 字數 2881 閱讀 2640

tp5的資料庫操作全部通過db類完成,比較符合國人的習慣,比如簡單的db::query()、db::execute(),還有複雜的鏈式操作db::table('user')->where('id=1')->select(),下面就通過原始碼來了解其工作流程

假定配置檔案設定驅動為mysql,當執行以下**時,tp5的資料庫類是怎麼工作的?

db::query("select * from user where id=?", [1]);
為了節省篇章以及更好地理解流程,下面只展示核心**,部分**被簡化或改造,我們來看看db類:

class db

else

return $config;

}public static function connect($config = )

return self::$instance[$name];

}public static function __callstatic($method, $params)

}

因為db類沒有定義query(),所以觸發了__callstatic(),__callstatic()又呼叫自身的connect(),connect()例項化mysql聯結器(傳入資料庫配置$options),然後儲存到$instance(資料庫連線例項陣列),再來看看mysql聯結器:

namespace think\db\connector;

class mysql extends connection

mysql聯結器也沒有定義query()呀,它繼承了connection,看看connection有沒有:

abstract class connection

}protected function getresult()

protected function bindvalue(array $bind = )

$result = $this->pdostatement->bindvalue($param, $val[0], $val[1]);

} else }}

public function connect()

return $this->linkid;

}public function query($sql, $bind = )

$this->bindvalue($bind);

$this->pdostatement->execute();

return $this->getresult();}}

結論

db::query()觸發db::__callstatic(),例項化mysql聯結器並呼叫mysql->query(),而mysql聯結器繼承了connection,所以實際上是呼叫了connection->query()

db和mysql聯結器都沒有定義table()方法,發現connection也有個__call():

protected function getquery()

public function __call($method, $args)

所以db::table('user')實際上是觸發了__call()魔術方法,然後例項化了乙個query物件(建構函式傳入當前mysql聯結器物件),看看query裡面做了什麼:

namespace think\db;

class query

protected function setbuilder()

public function table($table)

public function where($where)

public function query($sql)

public function select()

}

首先建構函式儲存了當前的mysql聯結器物件,並例項化think\db\builder\mysql

query->table()把表名儲存到$options陣列,然後返回$this(當前例項)從而實現鏈式操作,where()同樣,重點看看select(),它拿到$options之後把它清空以便下次使用,然後呼叫了builder->select()拿到拼裝好的sql,交由connection->query()查詢資料庫獲得結果集,整個流程到此結束,那麼builder是怎麼拼裝sql的呢?

namespace think\db\builder;

class mysql extends builder

}

think\db\builder\mysql並沒有定義select(),不過它繼承了builder,看看builder**:

namespace think\db;

abstract class builder

}

builder通過$options替換sql模板拿到sql

結論db::table()觸發了__callstatic()例項化connection並呼叫table(),由於connection也沒有定義table(),又觸發了自身的__call()例項化query並呼叫table(),table()返回$this實現鏈式操作db::table()->where()->select(),而select又呼叫builder->select()拿到sql,最終呼叫connection->query()獲取查詢結果,固完整的類圖表示如下:

thinkphp5原始碼解析 2 控制器

入口檔案index.php 定義應用目錄 載入框架引導檔案 require dir thinkphp start.php 引導檔案start.php namespace think 載入基礎檔案 require dir base.php 執行應用基礎檔案base.php defined think ...

ThinkPHP5使用快取

cache 使用復合快取型別 type complex 預設使用的快取 default 驅動方式 type file 在這設定換人的快取方式 快取儲存目錄 path cache path,檔案快取 file 驅動方式 type file 設定不同的快取儲存目錄 path runtime path f...

thinkphp5內建標籤

知道內建標籤怎麼用,查手冊的時候好查 卻功能的時候在裡面找著來用 1 內建標籤23 變數輸出使用普通標籤就足夠了,但是要完成其他的控制 迴圈和判斷功能,就需要借助模板引擎的標籤庫 4功能了,系統內建標籤庫的所有標籤無需引入標籤庫即可直接使用。5內建標籤包括 6標籤名作用包含屬性 7include 包...