溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何理解ThinkPHP框架設(shè)計及擴展

發(fā)布時間:2021-09-29 11:23:03 來源:億速云 閱讀:147 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“如何理解ThinkPHP框架設(shè)計及擴展”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“如何理解ThinkPHP框架設(shè)計及擴展”吧!

一、框架分層及url路由

框架的安裝非常簡單,下載后放入web服務(wù)器的目錄即可,但是建議大家不要用默認的入口文件位置,而是放入單獨的目錄,便于保護代碼和數(shù)據(jù)。例如我的入口文件和web服務(wù)器配置目錄在web目錄(外層框架里的index.php沒有刪除但是沒有使用):
如何理解ThinkPHP框架設(shè)計及擴展

同大多數(shù)MVC框架一樣,我們只需要按框架的目錄結(jié)構(gòu),擴展自己的Controller和View,一些頁面就開發(fā)完成了。ThinkPHP提供Module、Controller、Action三層結(jié)構(gòu)來組織自己的url(3.1版本叫分組、Action和method,3.2更加國際范),目錄結(jié)構(gòu)如下:
如何理解ThinkPHP框架設(shè)計及擴展

這里強烈建議大家:
1、業(yè)務(wù)單獨分層,不用放在Controller和Model里,例如我這里通過擴展函數(shù)庫Application/Common/Common/function.php強制定義業(yè)務(wù)層名稱為Service:

function service($name)
{
    return D($name, 'Service');
}

好處是復(fù)用性好,假如將來要開發(fā)wap頁面,寫了不同的Controller,就可以復(fù)用service,假如以后的數(shù)據(jù)存儲變了,比如把數(shù)據(jù)庫從mysql遷移到mongodb之類,那修改Model就可以,service還是不需要任何修改。

2、基礎(chǔ)模塊和業(yè)務(wù)模塊分開,不要相互引用。基礎(chǔ)模塊(例如用戶基本信息)只提供數(shù)據(jù)接口沒有Controller和View。
三層目錄已經(jīng)可以應(yīng)對一般的web應(yīng)用,更加復(fù)雜的web應(yīng)用我們可以定義不同的入口文件加載不同的Application來解決。更更復(fù)雜的應(yīng)用?門戶和超大規(guī)模網(wǎng)站么,那就不是一個php框架能解決所有問題的了,需要自己的中間件和定制框架。

ThinkPHP的支持4種url訪問模式,分別是:

1、普通模式,傳統(tǒng)url模式,所有參數(shù)分開,例如
http://localhost/tp/index.php?m=Ucai&c=User&a=index&para=xxx
路由參數(shù):m參數(shù)表示模塊,c表示控制器,a表示訪問方法
2、兼容模式
http://localhost/tp/index.php?s=/Ucai/User/index/para/xxx
路由參數(shù)通過s參數(shù)組裝,當(dāng)然數(shù)據(jù)參數(shù)也可以不必放在s參數(shù)里
3、pathinfo模式
http://localhost/tp/index.php/Ucai/User/index/para/xxx
這種模式把入口文件和真實腳本放在一起,含義明確,也便于SEO
4、rewrite模式
http://localhost/tp/Ucai/User/index/para/xxx
這種模式通過web服務(wù)器的rewrite配置隱藏入口文件,顯得更加友好
其中pathinfo和rewrite模式需要web服務(wù)器支持。ThinkPHP有個配置需要設(shè)置為哪種模式,其實是用在U方法里生成url鏈接的時候用到的,訪問的時候只要web服務(wù)器支持用哪種方式都可以。
也建議ThinkPHP其實不需要配置,而是記住用戶訪問的方式,只要第一個訪問用的是哪種模式,以后生成的url都用這種方式生成,因為用戶都已經(jīng)訪問到了就不存在支不支持的問題了。

如果正常的url不能達到我們的要求,還可以通過配置路由進一步優(yōu)化url,例如我們想把url配置的更加簡單
http://localhost/tp/Ucai/login/xxx
我們只需要在模塊配置文件中添加如下的路由配置即可,如果用正則表達式則可以更加簡化

'URL_ROUTE_RULES'   =>  array(
        'login/:para' => 'Ucai/User/index',
        'login' => 'Ucai/User/index',
    ),

到這里我們可以看到,ThinkPHP框架支持的層次結(jié)構(gòu)和url配置非常豐富,能滿足各種不同的需求。當(dāng)然我們建議大家不要濫用路由配置,適當(dāng)少量的配置能帶來更好的seo效果,但是大量的配置會給項目的維護和修改帶來困難。

二、ThinkPHP擴展

ThinkPHP本身含有豐富的組件和驅(qū)動,我們以數(shù)據(jù)庫驅(qū)動擴展和行為擴展為例來了解一下ThinkPHP的擴展設(shè)計。

三、數(shù)據(jù)庫驅(qū)動擴展

雖然ThinkPHP提供了眾多的數(shù)據(jù)庫驅(qū)動,但是也并不能滿足所有的需求。例如我們的數(shù)據(jù)很可能不是通過直接訪問數(shù)據(jù)庫去實現(xiàn),而是通過一些中間件(例如C程序)進行轉(zhuǎn)發(fā),從而獲得更好的性能,這時就需要擴展數(shù)據(jù)庫驅(qū)動來支持。
擴展非常簡單,在DB/Driver目錄下新建自己的驅(qū)動,例如Custom.php,然后實現(xiàn)request和execute方法擴展就算完成了,然后再配置文件里配置DB_TYPE='custom',就可以使用了。這里的request表示查詢,execute表示更改數(shù)據(jù),所有其他操作都會在Model里進行解析,包裝成sql語句調(diào)用這兩個方法執(zhí)行。
例如我所實現(xiàn)的最簡單的query方式,通過shell命令調(diào)用sqlite執(zhí)行sql語句:

public function query($str) {
        $cmd = sprintf('sqlite3 %s "%s"', $this->config['params']['dbfile'], $str);
        exec($cmd, $arr);
}

當(dāng)然這個只是示例,ThinkPHP本身就支持sqlite3,通過pdo的方式去連接就可以。實際的應(yīng)用環(huán)境可能是通過連接4層協(xié)議訪問中間層端口獲取數(shù)據(jù)。

四、Behavior行為擴展

Behavior行為設(shè)計是ThinkPHP框架的核心,通過行為配置和擴展,為系統(tǒng)的伸縮性和定制性提供了最大的支持。
假如我們要加入登錄驗證的功能,按照常規(guī)我們會設(shè)計自己的父類Controller,然后所有其他的Controller都從這里繼承。但有了Behavior會變得更加簡單和靈活,我們只需要在tags.php(沒有的話在配置目錄新建)添加一個Behavior就可以了:

return array(
    'action_begin' => array('Ucai\Behavior\AuthBehavior'),
    'view_begin' => array('Ucai\Behavior\OutputBehavior'),
);

程序在執(zhí)行到action_begin流程時就會調(diào)用這個Behavior,我們可以根據(jù)狀態(tài)進行跳轉(zhuǎn)或終止執(zhí)行。

namespace Ucai\Behavior;
class AuthBehavior {
     // 行為擴展的執(zhí)行入口必須是run
     public function run(&$return) {
        //不需要驗證的action設(shè)置為true
         if (!$return['AUTH_PUBLIC']) {
            if (service('User')->checkLogin())
            {
                $return = true;
            }
            else
            {
                header('Content-Type: text/html; charset=utf-8');
                redirect(U('User/index', array('url' => $_SERVER['HTTP_REFERER'])), 5, '需要登錄,5秒后跳轉(zhuǎn)。。。');
            }
         }
     }
}

對于不需要登錄的頁面我們可以在Controller里添加配置,所有不配置的都會要求登錄驗證。

public $config = array('AUTH_PUBLIC' => true);

這里大家對繼承和Behavior實現(xiàn)登錄驗證做一個對比,可能覺得區(qū)別不大。但是在一個復(fù)雜的項目里,這種功能會非常多,如果每個功能都放到父類里,就會非常龐大,并且部分子類可能又不需要,這時候用Behavior去定制流程就會顯得游刃有余。
在上面的配置中我們還發(fā)現(xiàn)了一個配置OutputBehavior更能說明問題,大家有沒有猜到,這個Behavior我是用來在view里輸出一些共有變量,例如jscss的域名和路徑等。在沒有Behavior之前,大家是不是需要一個公共方法,然后每個頁面都去調(diào)用一次,或者改寫View的類代碼?有了Behavior就顯得方便許多。

namespace Ucai\Behavior;
class OutputBehavior {
     public function run(&$return) {
        $view = \Think\Think::instance('Think\View');
        $view->assign('STATIC_URL', 'http://p3.ucai.cn/static');
     }
}

擴展總結(jié):通過Behavior擴展和數(shù)據(jù)庫驅(qū)動擴展大家可以看到,ThinkPHP提供了很靈活的擴展和增強機制,能滿足眾多需求。其他存儲、緩存、日志、模板引擎等如果需要也能很方便的擴展。

五、源碼分析與不足

首先我們來分析一下框架執(zhí)行的大致流程:
index.php(入口、調(diào)試模式、應(yīng)用路徑)
--> ThinkPHP.php(定義路徑與訪問模式)
--> Think\Think(類加載器、異常處理、讀取共有配置)
--> Think\App(請求url調(diào)度解析、執(zhí)行調(diào)度解析結(jié)果)
--> exec 執(zhí)行用戶定義的Controller的Action方法
--> Think\Dispatcher(根據(jù)url模式解析M、C、A和參數(shù),加載模塊配置)
--> Think\Controller(調(diào)用視圖、包裝和重定向)
可以看到,框架的內(nèi)部流程其實比較簡單,還有2個很重要的類:
Think\Hook: 監(jiān)聽App、Action、View的各個階段,執(zhí)行Behavior
Think\Behavior: 可配置(配置文件)可增刪(代碼)

在分析源代碼的過程中,我們也看到了一些不足:

1、宏定義過多,難于維護和修改
建議:只在個別文件定義極少數(shù)幾個宏,其余用類常量包裝
2、面向過程代碼過多,封裝不清晰
建議:用面向?qū)ο笏枷氚b
例如:url的解析和包裝,現(xiàn)在是在Dispatcher里生成APP宏,然后在U方法里讀取宏并生成最終url。其實完全可以定義一個類來包裝例如UrlHelper,而類的二個方法parse和generate分別負責(zé)解析和生成url,這樣代碼結(jié)構(gòu)會清晰很多。
3、有的函數(shù)和類代碼封裝過多,復(fù)用和改進不方便
建議:用組合來封裝獨立功能內(nèi)容
例如:Model的校驗功能,完全可以獨立成類,也可以用于非Model對象調(diào)用。而現(xiàn)在的校驗接口是Model的保護性方法,只能在Model的create函數(shù)調(diào)用,外面必須通過create方法才能校驗。
4、代碼規(guī)范和風(fēng)格問題
希望代碼風(fēng)格能更加規(guī)范和標(biāo)準(zhǔn),例如DB類作為模板方法的父類,應(yīng)該用抽象方法或拋出異常形式定義所有Model需用到的方法。事實上有些方法子類是不需要的,而Db類卻沒有實現(xiàn)。

到此,相信大家對“如何理解ThinkPHP框架設(shè)計及擴展”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI