欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

ThinkPHP框架的執(zhí)行流程有哪些

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)ThinkPHP框架的執(zhí)行流程有哪些,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

十余年品牌的成都網(wǎng)站建設(shè)公司,1000多家企業(yè)網(wǎng)站設(shè)計(jì)經(jīng)驗(yàn).價(jià)格合理,可準(zhǔn)確把握網(wǎng)頁設(shè)計(jì)訴求.提供定制網(wǎng)站建設(shè)、商城網(wǎng)站開發(fā)、成都微信小程序、響應(yīng)式網(wǎng)站開發(fā)等服務(wù),我們?cè)O(shè)計(jì)的作品屢獲殊榮,是您值得信賴的專業(yè)網(wǎng)絡(luò)公司。

一、框架執(zhí)行流程之初始化應(yīng)用的數(shù)據(jù)設(shè)置

這里的內(nèi)容跟容器的內(nèi)容有點(diǎn)重復(fù),因?yàn)閳?zhí)行流程是從入口文件開始的,并且最后也是通過容器執(zhí)行的。

ThinkPHP框架的執(zhí)行流程有哪些

然后就會(huì)進(jìn)入到文件thinkphp/library/think/App.php的run方法,在這個(gè)方法中主要就是下圖框出來的地方,執(zhí)行的initialize方法。

ThinkPHP框架的執(zhí)行流程有哪些 來到initialize這個(gè)方法,先看上半部分。

  • microtime(true);返回的是unix的微秒數(shù)

  • memory_get_usage返回的是分配給PHP的內(nèi)存量,單位為字節(jié)

  • 在接下來就是對(duì)框架的幾個(gè)路徑進(jìn)行設(shè)置

  • static::setInstance($this);這里是將app這個(gè)實(shí)例設(shè)置為容器實(shí)例

  • $this->instance('app', $this);這個(gè)在之前容器章節(jié)就提到了,就是為了把a(bǔ)pp這個(gè)類綁定到容器里邊去,也就是注冊(cè)樹模式。

ThinkPHP框架的執(zhí)行流程有哪些 這里有一個(gè)小的問題點(diǎn)給大家提出來,在初始化應(yīng)用的這個(gè)方法里邊存在這樣一行代碼。

有沒有小伙伴對(duì)這個(gè)$this->env和下邊的$this->config這倆個(gè)調(diào)用有疑惑。

如果你有疑惑那就跟著咔咔一起來看,沒疑惑的就可以繼續(xù)往下看了。

App這個(gè)類是繼承的容器類,那么這個(gè)env和config不論是在app還是container類中都是沒有這倆個(gè)屬性的。

那么怎么就可以直接調(diào)用呢!而且代碼追蹤都會(huì)追蹤到env類和container類中。

需要知道這個(gè)源頭就需要我們?nèi)ピ诖笾碌目匆槐閏ontainer類的代碼。

ThinkPHP框架的執(zhí)行流程有哪些

經(jīng)過一番苦讀之后,可以看到下圖的幾行代碼。這幾行代碼全部使用的是魔術(shù)方法。

當(dāng)訪問env類不存在的時(shí)候就會(huì)去執(zhí)行make方法。

make這個(gè)方法在容器那一章節(jié)進(jìn)行的細(xì)的不能再細(xì)的解讀了。

這個(gè)make方法最終會(huì)返回一個(gè)類的實(shí)例,并且還會(huì)存到容器里邊。

ThinkPHP框架的執(zhí)行流程有哪些 這里只放一個(gè)make方法的代碼,如果有不會(huì)的可以去看之前的文章。

ThinkPHP框架的執(zhí)行流程有哪些 最后就是加載一系列的數(shù)據(jù),加載詳情請(qǐng)看前言的思維導(dǎo)圖。

ThinkPHP框架的執(zhí)行流程有哪些

二、如何查看一個(gè)方法都在哪里執(zhí)行了

在閱讀源碼的過程中,有一個(gè)很難把控的問題就是一個(gè)方法在不同的地方進(jìn)行了調(diào)用,但是咱們確一時(shí)半會(huì)根本不知道都在哪里調(diào)用了。

這里用init方法來做一個(gè)演示。

init方法是初始化應(yīng)用或者模塊的一個(gè)方法,但是這里的module參數(shù)確實(shí)一個(gè)空值。

ThinkPHP框架的執(zhí)行流程有哪些 先做一個(gè)斷點(diǎn)查看一下相關(guān)的數(shù)據(jù)信息。

打印的結(jié)果就是空,這就是一些新學(xué)習(xí)的伙伴會(huì)犯的一個(gè)錯(cuò)誤,因?yàn)檫@個(gè)方法不可能只調(diào)用一次的。

如果初始化模塊都是空那么這個(gè)方法就沒有存在的必要了。

ThinkPHP框架的執(zhí)行流程有哪些 ThinkPHP框架的執(zhí)行流程有哪些 那么正確的斷點(diǎn)方式應(yīng)該是這個(gè)樣子的。

ThinkPHP框架的執(zhí)行流程有哪些 ThinkPHP框架的執(zhí)行流程有哪些 此時(shí)就會(huì)有一個(gè)問題,這個(gè)init方法明顯是被調(diào)用了倆次的,那么另一次調(diào)用的地方是在哪里呢!

如果在不知道新的技巧之前,就會(huì)進(jìn)行一系列的斷點(diǎn)打印,看在哪里進(jìn)行了執(zhí)行,比如在這個(gè)init的上層去打印。

也就是在initialize那個(gè)方法里邊去打印做斷點(diǎn),但是這樣很是麻煩的,而且很有可能浪費(fèi)了大量的時(shí)間還是找不到正確的地方。

小技巧之debug_backtrace()

這個(gè)方法會(huì)產(chǎn)生一條回溯追蹤,會(huì)顯示出一個(gè)方法所有的調(diào)用位置。

使用方式就是如下圖,只需要把debug_backtrace這個(gè)方法打印出來即可。

ThinkPHP框架的執(zhí)行流程有哪些 ThinkPHP框架的執(zhí)行流程有哪些 ThinkPHP框架的執(zhí)行流程有哪些

根據(jù)得到的數(shù)據(jù)信息,就可以非常快的進(jìn)行定位。

第一次就是在app類的215行。

ThinkPHP框架的執(zhí)行流程有哪些

第二次是在thinkphp/library/think/route/dispatch/Module.php類的60行

ThinkPHP框架的執(zhí)行流程有哪些

可以在這里做一個(gè)打印,看一下這個(gè)module是否為index

ThinkPHP框架的執(zhí)行流程有哪些 ThinkPHP框架的執(zhí)行流程有哪些 所以說有了這個(gè)方法就可以非??焖俚囟ㄎ徽{(diào)用位置。

三、框架執(zhí)行流程之初始化應(yīng)用init分析

上文給大家提供了一個(gè)小技巧debug_backtrace實(shí)戰(zhàn)演示了如何查看一個(gè)方法都在哪里執(zhí)行的。

并且案例也是使用的init這個(gè)方法來演示的,因?yàn)榻酉聛砭褪且獙?duì)init這個(gè)方法進(jìn)行深入的了解。

在init方法里邊主要做的事情在上邊的腦圖已經(jīng)描述的很清楚了。

  • 從一開始就對(duì)模塊的定位,就是在第二節(jié)中的對(duì)init方法的調(diào)用,會(huì)傳入對(duì)應(yīng)的模塊

  • 加載app目錄下的tags文件,在tags文件里邊就是對(duì)行為擴(kuò)展定義的文件。在之前門面的文章中定義鉤子執(zhí)行就在這個(gè)文件中設(shè)置的。

  • 加載common文件,也就是公共文件,所以說公共文件就是在這里進(jìn)行加載的。

  • 加載助手函數(shù)文件helper,在助手函數(shù)里邊有一個(gè)大家特別熟悉的一個(gè)方法,那就是dump。這就是為什么在有的地方使用dump會(huì)報(bào)錯(cuò)的原因。

  • 加載中間件文件,這里的直接給出的是直接加載app目錄下的中間件文件,但是在框架中我們需要在定義一個(gè)目錄為http,在這個(gè)目錄下定義中間件文件。

  • 注冊(cè)服務(wù)的容器對(duì)象實(shí)例,這里注冊(cè)就使用的是容器類中的bindTo方法進(jìn)行綁定注冊(cè)的。

  • 讀取配置文件,這段在配置文件加載那一節(jié)中已經(jīng)進(jìn)行深入的說明了, 這里就不提了。配置文件會(huì)讀取倆個(gè)地方一個(gè)是第一步模塊下的config文件,另一個(gè)就是config目錄下的配置文件。

  • 設(shè)置模塊路徑,會(huì)把第一步獲取到的模塊進(jìn)行env環(huán)境變量配置里邊

  • 最后一步就是對(duì)容器中的對(duì)象實(shí)例進(jìn)行配置更新,具體更新了什么在后文中給大家詳細(xì)說來。

    /**
     * 初始化應(yīng)用或模塊
     * @access public
     * @param  string $module 模塊名
     * @return void
     */
    public function init($module = '')
    {
        // 定位模塊目錄
        $module = $module ? $module . DIRECTORY_SEPARATOR : '';
        /**
         * 第一次:D:\phpstudy_pro\WWW\ThinkPHPSourceCodeAnalysis\application\
         * 第二次:D:\phpstudy_pro\WWW\ThinkPHPSourceCodeAnalysis\application\index\
         */
        $path   = $this->appPath . $module;

        // 加載初始化文件
        if (is_file($path . 'init.php')) {
            include $path . 'init.php';
        } elseif (is_file($this->runtimePath . $module . 'init.php')) {
            include $this->runtimePath . $module . 'init.php';
        } else {
            // 加載行為擴(kuò)展文件
            if (is_file($path . 'tags.php')) {
                $tags = include $path . 'tags.php';
                if (is_array($tags)) {
                    $this->hook->import($tags);
                }
            }

            // 加載公共文件
            if (is_file($path . 'common.php')) {
                include_once $path . 'common.php';
            }

            if ('' == $module) {
                // 加載系統(tǒng)助手函數(shù)
                include $this->thinkPath . 'helper.php';
            }

            // 加載中間件
            if (is_file($path . 'middleware.php')) {
                $middleware = include $path . 'middleware.php';
                if (is_array($middleware)) {
                    $this->middleware->import($middleware);
                }
            }

            // 注冊(cè)服務(wù)的容器對(duì)象實(shí)例
            if (is_file($path . 'provider.php')) {
                $provider = include $path . 'provider.php';
                if (is_array($provider)) {
                    $this->bindTo($provider);
                }
            }

            /**
             * $path : "D:\phpstudy_pro\WWW\ThinkPHPSourceCodeAnalysis\application\"
             *          "D:\phpstudy_pro\WWW\ThinkPHPSourceCodeAnalysis\application\index\"
             */
            // 自動(dòng)讀取配置文件
            if (is_dir($path . 'config')) {
                $dir = $path . 'config' . DIRECTORY_SEPARATOR;
            } elseif (is_dir($this->configPath . $module)) {
                // D:\phpstudy_pro\WWW\ThinkPHPSourceCodeAnalysis\config\
                $dir = $this->configPath . $module;
            }
            // scandir:以升序的方式讀取目錄中的文件
            // 返回就是config目錄中的所有文件
            $files = isset($dir) ? scandir($dir) : [];

            foreach ($files as $file) {
                /**
                 * $this->configExt:配置文件的后綴
                 * pathinfo返回的是文件后綴,關(guān)于pathinfo共有三個(gè)可選的參數(shù)PATHINFO_DIRNAME、PATHINFO_BASENAME、PATHINFO_EXTENSION,分別為只返回文件名,文件目錄名,文件擴(kuò)展
                 */
                if ('.' . pathinfo($file, PATHINFO_EXTENSION) === $this->configExt) {
                    /**
                     * 倆個(gè)參數(shù)分別為
                     * 1.目錄+config目錄下的文件
                     * 2.config目錄下文件名
                     */
                    $this->config->load($dir . $file, pathinfo($file, PATHINFO_FILENAME));
                }
            }
        }

        $this->setModulePath($path);

        if ($module) {
            // 對(duì)容器中的對(duì)象實(shí)例進(jìn)行配置更新
            $this->containerConfigUpdate($module);
        }
    }

這里附帶上一份代碼,可以對(duì)著代碼看上邊的執(zhí)行流程,對(duì)每一步都做了簡單的說明。

咔咔個(gè)人見解對(duì)源碼進(jìn)行優(yōu)化

在設(shè)置模塊的這步代碼咔咔感覺不是很是嚴(yán)謹(jǐn),因?yàn)閕nit方法會(huì)在倆個(gè)地方進(jìn)行執(zhí)行。

第一次的模塊為空,這塊代碼執(zhí)行是沒有任何意義的。

下面在對(duì)容器的對(duì)象實(shí)例進(jìn)行配置更新時(shí)進(jìn)行了一次判斷,判斷模塊的這個(gè)參數(shù)是否為空,如果不為空才會(huì)執(zhí)行。

那么同樣的道理,咔咔感覺在設(shè)置模塊路徑這塊也應(yīng)該在這個(gè)判斷里邊。

雖說第二次執(zhí)行會(huì)把第一次的結(jié)果覆蓋掉,但是咔咔感覺下圖這樣使用才會(huì)更好。

ThinkPHP框架的執(zhí)行流程有哪些

四、對(duì)容器中的對(duì)象實(shí)例進(jìn)行更新配置

在上一節(jié)中這里就是最后的內(nèi)容,那這個(gè)對(duì)實(shí)例進(jìn)行更新配置,到底更新了什么,怎么更新沒有說明。

在這一小節(jié)中就會(huì)做出說明,同樣可以配合著前言的思維導(dǎo)圖看。

  • 先會(huì)把config目錄下的所有配置信息全部獲取出來

  • 從app配置文件中將注冊(cè)異常處理類

  • 第三大塊是把第一步獲取出來的所有配置信息給對(duì)應(yīng)的類進(jìn)行注冊(cè)配置。

  • 第四步就是在把模塊確定下來之后加載對(duì)應(yīng)的語言包,語言包功能就可以實(shí)現(xiàn)多語言功能,之前咔咔寫過一篇文章實(shí)現(xiàn)多語言功能,如果感興趣的可以去查看。

  • 最后一步就是根據(jù)app配置文件中的三個(gè)屬性進(jìn)行緩存的處理

在這一節(jié)中咔咔感覺最重要的就是下圖的內(nèi)容了。

ThinkPHP框架的執(zhí)行流程有哪些 我們可以隨意追蹤一到倆個(gè)方法查看一下那邊到底執(zhí)行了什么方法。

追蹤方法Db::init()

追蹤方法過來后可以看到就是對(duì)Db類中的config屬性進(jìn)行賦值,把database中的值賦值給Db類中的config屬性。

ThinkPHP框架的執(zhí)行流程有哪些 追蹤方法$this->middleware->setConfig()

來到中間件這個(gè)類里邊,可以看到就是把本類的配置和傳遞過來的參數(shù)類進(jìn)行合并,同樣也是進(jìn)行config屬性的賦值。

跟上邊案例的Db類的init方法實(shí)現(xiàn)的效果是一致的。

這里在提一嘴就是在對(duì)容器中的對(duì)象實(shí)例進(jìn)行更新配置這一幅圖中可以看到紫色部分是在本類中沒有引用的。

那么這是怎么可以進(jìn)行執(zhí)行的呢!是因?yàn)锳pp類繼承了容器類,容器類中有四個(gè)魔術(shù)方法,其中有一個(gè)__get方法,就是在獲取不存在的屬性時(shí)會(huì)執(zhí)行那個(gè)方法。

在魔術(shù)方法__get方法中執(zhí)行了一個(gè)make方法,這個(gè)make方法說了好多次了,這個(gè)方法最終會(huì)返回一個(gè)應(yīng)用的實(shí)例,然后用這個(gè)實(shí)例調(diào)用對(duì)應(yīng)實(shí)例類的方法。

這一塊一定要理解好,閱讀源碼就是這個(gè)樣子,我們需要對(duì)一切未知的進(jìn)行的解決,只有這樣才能提高我們的編程能力和思想。

ThinkPHP框架的執(zhí)行流程有哪些

五、淺談?wù){(diào)試模式以及代碼冗余

本節(jié)會(huì)對(duì)調(diào)試模式做出簡單的說明,并且會(huì)對(duì)框架代碼冗余情況進(jìn)行簡單的提出。

沒有人寫的代碼是沒有漏洞的,如果有那就是你還沒有達(dá)到一定的造詣。

調(diào)試模式

在第一節(jié)中只提到了initialize方法的上半部分,因?yàn)樵谶@一節(jié)之前聊的都是關(guān)于應(yīng)用初始化init的內(nèi)容。

接下來會(huì)對(duì)這一塊的內(nèi)容進(jìn)行簡單的說明。

  • 從app配置文件中獲取到app_debug的配置項(xiàng)

  • 給環(huán)境變量設(shè)置debug級(jí)別

  • 當(dāng)框架中的debug是關(guān)閉狀態(tài)時(shí)會(huì)執(zhí)行ini_set這個(gè)方法,這個(gè)方法是為一個(gè)配置選項(xiàng)進(jìn)行賦值。

接下來的內(nèi)容估計(jì)不是很好理解,都是平時(shí)在工作中根本使用不到的。

  • ob_get_level:返回輸出緩沖機(jī)制的嵌套級(jí)別,那么怎么去理解呢!其實(shí)就是當(dāng)緩存區(qū)不起作用時(shí)會(huì)返回0。

  • ob_get_clean:這個(gè)函數(shù)將會(huì)返回輸出緩沖的內(nèi)容并終止輸出緩沖。如果緩沖區(qū)沒有有效內(nèi)容則返回false。本質(zhì)上相當(dāng)于同時(shí)執(zhí)行了ob_getcontens()和ob_end_clean()。

  • ob_start:打開輸出控制緩沖

上邊這三個(gè)先暫時(shí)認(rèn)識(shí)就行,后期如果有機(jī)會(huì)會(huì)專門出一篇文章做解釋的。

ThinkPHP框架的執(zhí)行流程有哪些 關(guān)于框架代碼冗余

這里也僅僅代表咔咔個(gè)人的觀點(diǎn)。

可以先看看這部分的代碼,這倆處代碼是不是很是熟悉,沒錯(cuò)就是在上文的init方法中容器對(duì)象實(shí)例配置更新見到過。

ThinkPHP框架的執(zhí)行流程有哪些 如圖

ThinkPHP框架的執(zhí)行流程有哪些 這塊也就是咔咔個(gè)人提出的見解,由于咔咔式針對(duì)5.1做的源碼解讀,不太了解新版版是否做出了改動(dòng)。

六、總結(jié)

本節(jié)主要是針對(duì)框架執(zhí)行流程中的初始化應(yīng)用做了簡單的探討。

至于在app類的run方法下面還有很多的執(zhí)行過程在這一節(jié)中沒有做過多的解釋。

在閱讀源碼的過程中給大家提了一個(gè)很好得小技巧,那就是如何去查看一個(gè)方法都在哪里進(jìn)行了執(zhí)行。

這個(gè)方法為debug_backtrace,這個(gè)方法需要大家多使用幾次就知道怎么使用了,因?yàn)樵诖蛴〕鰜淼慕Y(jié)果中也存在很多無用的信息。

這個(gè)方法在調(diào)試源碼的過程中是非常有效的,一定要好好利用這個(gè)方法。

在就是對(duì)初始化應(yīng)用init方法進(jìn)行了特別詳細(xì)的介紹。

其中咔咔感覺這塊設(shè)計(jì)最好的就是在容器中的對(duì)象實(shí)例進(jìn)行更新配置那一塊,先讀取所有的配置,然后在通過各個(gè)類的方法進(jìn)行配置的設(shè)置。

這種代碼規(guī)劃和設(shè)計(jì)思路值得我們?nèi)W(xué)習(xí)。

最后聊到了調(diào)試模式和框架的代碼冗余問題,關(guān)于調(diào)試模式這里咔咔給大家提個(gè)醒項(xiàng)目在線上的調(diào)試模式一定要關(guān)閉。

否則你的項(xiàng)目就類似于裸奔的存在,沒有一點(diǎn)點(diǎn)的安全可言。

這塊有點(diǎn)不好理解的就是對(duì)于緩沖區(qū),關(guān)于這塊的內(nèi)容咔咔認(rèn)為暫時(shí)沒有必要去鉆牛角尖,先認(rèn)識(shí)認(rèn)識(shí)然后在進(jìn)行深入的研究。

緩沖區(qū)的這塊內(nèi)容估計(jì)工作了三四年的也很少有人使用,所以先認(rèn)識(shí),知道怎么一回事,咔咔后期學(xué)習(xí)了之后在給大家進(jìn)行補(bǔ)充。

直到這里關(guān)于框架的執(zhí)行流程之初始化應(yīng)用就結(jié)束了,這一節(jié)沒有過深需要學(xué)習(xí)的,主要是其中的代碼設(shè)計(jì)模式和實(shí)現(xiàn)思路。

最后這個(gè)圖大家一定要跟著源碼看一看哈!

ThinkPHP框架的執(zhí)行流程有哪些

上述就是小編為大家分享的ThinkPHP框架的執(zhí)行流程有哪些了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)站題目:ThinkPHP框架的執(zhí)行流程有哪些
分享網(wǎng)址:http://chinadenli.net/article42/gdogec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器定制網(wǎng)站、外貿(mào)建站、品牌網(wǎng)站設(shè)計(jì)、虛擬主機(jī)、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站