“
終于快來到框架解析的結(jié)尾了,本文將會(huì)帶領(lǐng)大家領(lǐng)略框架中的模型以及視圖的奧秘。
”
前言
在日常開發(fā)過程中模型的使用是非常之多的,但是在開發(fā)過程只知道如何使用,并不知道內(nèi)在是如何實(shí)現(xiàn)的,模型是不管接口還是后臺(tái)都會(huì)使用到的東西。
關(guān)于視圖在前后臺(tái)分離的大趨勢下,框架存在視圖大多數(shù)還是針對于后臺(tái)開發(fā)的使用。
本文也是對框架解讀快到最后階段了,接下來咔咔將帶領(lǐng)大家一起學(xué)習(xí)關(guān)于在框架中Db類的奧秘。
下圖為咔咔提供的腦圖可以根據(jù)這個(gè)腦圖進(jìn)行閱讀文章。
一、Db操作類和其它類對應(yīng)關(guān)系解刨
在學(xué)習(xí)模型之前一定要知道的就是DB這個(gè)類,這個(gè)類也是對數(shù)據(jù)庫的操作。
在框架中存在這樣一個(gè)配置文件,在這個(gè)配置文件里邊會(huì)存在關(guān)于數(shù)據(jù)庫配置的一系列信息。
在接下來的過程中咔咔也會(huì)簡單的創(chuàng)建一個(gè)數(shù)據(jù)庫來做演示。
同樣在框架的核心層存在倆個(gè)類,分別為Db類和Model類,這倆個(gè)類就是接下來的解析對象。
在解析Db操作類和其它類對應(yīng)關(guān)系解刨之前,我們先創(chuàng)建一個(gè)數(shù)據(jù)庫作為演示使用。
首先先來看一下Db類的信息。
通過上圖我們可以看到關(guān)于Db類的一部分信息,就是使用Db類的一些查詢方法。
但是來到Db類的最后可以看到一個(gè)熟悉的方法__callStatic。
這個(gè)方法在一直讀咔咔文章的讀者應(yīng)該已經(jīng)很是熟悉了,這個(gè)方法在門面源碼解析那一節(jié)中進(jìn)行過深入的了解。
對于這個(gè)方法只需要記住的是在調(diào)用沒有聲明的靜態(tài)方法時(shí)會(huì)進(jìn)行調(diào)用。
至于call_user_func_array這個(gè)函數(shù)的使用可以理解為,這個(gè)方法是內(nèi)置函數(shù),可以直接調(diào)用函數(shù)運(yùn)行,也就是可以直接運(yùn)行方法。
在通過剛剛的查看Db類的注釋信息時(shí)可以看到Db類是使用著Connection這個(gè)類,也就是連接數(shù)據(jù)庫類。
進(jìn)入到這個(gè)類里邊簡單的看一下構(gòu)造函數(shù)即可,至于是怎么一個(gè)運(yùn)行順序會(huì)在下文進(jìn)行講解。
在框架中操作控制器有倆大場景,第一中為Db類操作,第二種就是Model操作。
其中Connection·為連接器,Query為查詢器,Builder為sql生成器,exception為異常類。
知道了以上的幾個(gè)信息,在接下來的理解過程中會(huì)有一定的幫助,在下一節(jié)中將會(huì)對Db類庫場景分析。
二、Db類庫場景分析
先從一個(gè)簡單的案例進(jìn)行解析,先來看一下數(shù)據(jù)庫的數(shù)據(jù)。
然后來到控制器寫一個(gè)簡單的查詢案例,在創(chuàng)建控制器之前先使用命令進(jìn)行創(chuàng)建一個(gè)測試控制器。
在這個(gè)控制器進(jìn)行簡單的查詢數(shù)據(jù)。
查詢結(jié)果如下
在這個(gè)案例中,可以看到使用的是Db::query這種查詢方式,接下來對于這種查詢方式進(jìn)行簡單的剖析。
接著執(zhí)行流程就會(huì)來到Db這個(gè)類,在這個(gè)類中可以看到關(guān)于當(dāng)對象訪問不存在的靜態(tài)方法時(shí),__callStatic()方法會(huì)被自動(dòng)調(diào)用。
這個(gè)方法在之前門面的講解中進(jìn)行了深度講解。
從上圖可以看到當(dāng)執(zhí)行訪問對象不存在的靜態(tài)方法時(shí)會(huì)執(zhí)行到call_user_func_array調(diào)用回調(diào)函數(shù),并把一個(gè)數(shù)組參數(shù)作為回調(diào)函數(shù)的參數(shù)
接著代碼就會(huì)執(zhí)行到static::connect()這行代碼,由于本類Db沒有繼承任何的類,所以對于static這個(gè)的使用就是調(diào)用本類。
如果當(dāng)Db類繼承了其它類那么就會(huì)有一定的區(qū)別,這個(gè)區(qū)別就是關(guān)于static關(guān)鍵字,給大家做的一點(diǎn)點(diǎn)冷門知識(shí)得補(bǔ)充,當(dāng)一個(gè)類繼承一個(gè)類時(shí),在父類實(shí)用static關(guān)鍵字時(shí),默認(rèn)調(diào)用的子類的方法。
切換數(shù)據(jù)庫連接
因?yàn)闆]有任何繼承,所以會(huì)來到本類的connect這個(gè)方法。
在這個(gè)類里邊首先會(huì)返回結(jié)果為數(shù)據(jù)庫配置信息。
然后會(huì)從配置信息中獲取到query這個(gè)索引,最終返回thinkdbQuery這個(gè)字符串,這里一定要注意返回的是字符串,不是這個(gè)類的實(shí)例。
緊接著就會(huì)執(zhí)行到第三步創(chuàng)建數(shù)據(jù)庫連接對象實(shí)例,接下里將會(huì)對這一步進(jìn)行解析。
緊接著會(huì)來到文件實(shí)際執(zhí)行的為 new thinkdbQuery,最終會(huì)返回執(zhí)行查詢 返回?cái)?shù)據(jù)集,返回?cái)?shù)據(jù)為返回 object(thinkdbQuery)
關(guān)于這個(gè)$this->connection是在本類的構(gòu)造函數(shù)進(jìn)行設(shè)置的。
先簡單的看一下這個(gè)構(gòu)造函數(shù),在這個(gè)構(gòu)造函數(shù)中直接就設(shè)置了connection這個(gè)屬性的值,所以在上圖中可以使用。
在這里執(zhí)行完成之后就會(huì)將返回的值給從一開始就解析的這個(gè)調(diào)用未聲明的靜態(tài)方法會(huì)進(jìn)行調(diào)用。
其中static::connect()就是最終返回的值static::connect() 返回 object(thinkdbQuery)。
所以接下來代碼會(huì)執(zhí)行到 ?thinkphp/library/think/db/Query.php 的 query方法
$sql 就是在Db::query()中傳遞的sql語句,并且執(zhí)行查詢 返回?cái)?shù)據(jù)集
最后這段代碼會(huì)執(zhí)行thinkdbconnectorMysql的query方法
接下來來到thinkdbconnectorMysql的query方法
在這個(gè)方法中主要做了三件事情。
-
$this->initConnect 初始化數(shù)據(jù)庫連接 -
$this->PDOStatement->execute(); 執(zhí)行查詢 -
return $this->getResult($pdo, $procedure); 返回結(jié)果集
解析$this->initConnect 初始化數(shù)據(jù)庫連接
在這個(gè)方法中可以看到是進(jìn)行了一次配置信息獲取,首先需要明白這個(gè)配置信息是什么。
這個(gè)配置項(xiàng)是在配置文件database中配置的,根據(jù)注釋提供的信息可以看到主要是關(guān)于主從服務(wù)器設(shè)置的。
一般情況下是不會(huì)在框架中配置主從信息的,這里就不去解析框架是如何實(shí)現(xiàn)數(shù)據(jù)庫的主從配置了。
在這個(gè)判斷中在進(jìn)行了一次判斷當(dāng)前數(shù)據(jù)庫連接的id,然后執(zhí)行了連接數(shù)據(jù)庫方法。
這個(gè)方法最終會(huì)返回object(PDO)#33的一個(gè)實(shí)例信息。
$this->PDOStatement->execute(); 執(zhí)行查詢
第二件事情做的就是執(zhí)行查詢,接下來我們來詳細(xì)說明一下這個(gè)到底是如何執(zhí)行的。
在返回pdo實(shí)例時(shí),將這個(gè)實(shí)例賦值給了$this->PDOStatement這個(gè)屬性,所以會(huì)去PDO類中進(jìn)行執(zhí)行。
在這里大家需要明白一件事情就是關(guān)于execute這個(gè)方法,用于執(zhí)行返回多個(gè)結(jié)果集、多個(gè)更新計(jì)數(shù)或二者組合的語句。
第三件事情返回結(jié)果集
直到這里就是執(zhí)行的最后一步就是返回結(jié)果集。
這里使用的方法都是查詢底層,就在去解析了,在這里就會(huì)返回最終查詢結(jié)果。
最終結(jié)果就會(huì)返回給這里__callStatic方法,并且返回給上層的$res變量。
直到這里關(guān)于使用Db查詢的執(zhí)行流程就解析完了, 但是框架給封裝的方法不僅僅只有query,其它的查詢方式可以按照咔咔的這個(gè)流程在進(jìn)行簡單的分析。
最后執(zhí)行的都會(huì)是這一節(jié)的最后幾個(gè)流程,只是前邊執(zhí)行會(huì)有一點(diǎn)點(diǎn)區(qū)別而已。
“
堅(jiān)持學(xué)習(xí)、堅(jiān)持寫博、堅(jiān)持分享是咔咔從業(yè)以來一直所秉持的信念。希望在偌大互聯(lián)網(wǎng)中咔咔的文章能帶給你一絲絲幫助。我是咔咔,下期見。
”