
2014-06-26 |$↑ 發布者:梁國(guó)芳δσ✔↕ | 查看 ≈(kàn):3320次
ThinkphpThinkPHP從(cóng)3.0版本開(kāi)始引入了(≥∞ ≈le)全新的(de)CBD(核心Core+行(xíng)為(wèi)Be₹≤•havior+驅動Driver)架 構模式,因為(wèi)從(cóng)底層開(∑ε∞₩kāi)始,框架就(jiù)采用(yòng)核心+行(xΩ∞π≥íng)為(wèi)+驅動的(de)架構體(tǐ)系,核心保留了(le)最✔關鍵的(de)部分(fēn),并在重要(yàoαβδ∏)位置設置了(le)标簽用(yòng)以标記,其£¥♥±他(tā)功能(néng)都(dōu)采用(yòng)行(xíng)為(wèi§¶)擴展和(hé)驅 動的(de)方式組合,開(kāi)發人(r↔α₩≈én)員(yuán)可(kě)以根據自(zì)己的(de)需要(yβ∞ào),對(duì)某個(gè)标簽位置進行(xíng)行(xíngγ&¥)為(wèi)擴展或者替換,就(jiù)可(kě)以方>≥σ便的(de)定制(zhì)框架底層,也(yě)可(kě)→λ以在應用(yòng)層添加自(zì)己的(de)标簽位置和(hé) ±&添加應 用(yòng)行(xíng)為(wèi)。而标簽位置類似于A₩↑♣®OP概念中的(de)“切面”,行(✘↔xíng)為(wèi)都(dōu)是(shì)& ✔圍繞這(zhè)個(gè)“切面”來(lái)¥&進行(xíng)編程。
ThinkPHP的(de)核心部分(fēn)包括核心函數(shù)庫、慣例配←¥§≤置、核心類庫(包括基礎類和(hé)內(nβ©÷↓èi)置驅動及核心行(xíng)為(wèi)),這(zhè)些(xi>>©"ē)是(shì)ThinkPHP必不(bù)可(↑¶←¥kě)少(shǎo)的(de)部分(fēn)。
ThinkPHP/Common/functions.php // 核心函數(shù)庫ThinkPHP/Conf/convention.php // 慣例配置文(wén)件(jiàn)ThinkPHP/Conf/debug.php // 慣例調試配置文(wén)件(jiàn)ThinkPHP/Mode/common.php // 普通(tōng)模式定義文(wén)件(jià§αn)ThinkPHP/Library/Think // 核心類庫包ThinkPHP/Library/Behavior // 系統行(xíng)為(wèi)類庫ThinkPHP/Library/Think/App.class.php // 核心應用(yòng)類ThinkPHP/Library/Think/Behavior.class.php // 基礎行(xíng)為(wèi)類ThinkPHP/Library/Think/Cache.class.php // 核心緩存類ThinkPHP/Library/Think/Controller.class.php // 基礎控制(zhì)器(qì)類ThinkPHP/Library/Think/Db.class.php // 數(shù)據庫操作(zuò)類ThinkPHP/Library/Think/Dispatcher.class.php // URL解析調度類ThinkPHP/Library/Think/Exception.class.php // 系統基礎異常類ThinkPHP/Library/Think/Hook.class.php // 系統鈎子(zǐ)類ThinkPHP/Library/Think/Log.class.php // 系統日(rì)志(zhì)記錄類ThinkPHP/Library/Think/Model.class.php // 系統基礎模型類ThinkPHP/Library/Think/Route.class.php // 系統路(lù)由類ThinkPHP/Library/Think/Storage.class.php // 系統存儲類ThinkPHP/Library/Think/Template.class.php // 內(nèi)置模闆引擎類ThinkPHP/Library/Think/Think.class.php // 系統引導類ThinkPHP/Library/Think/View.class.php // 系統視(shì)圖類
Behavior目錄下(xià)面是(shì)系統內(nèi)置的(de)↓←一(yī)些(xiē)行(xíng)為(wèi)類庫,內(nα≈₹©èi)置驅動則分(fēn)布在各個(gè)不( &πbù)同的(de)驅動目錄下(xià)面(參考下(xià)面的✔∏(de)驅動部分(fēn))。
3.2在架構設計(jì)上(shàng)更加強化( '₩huà)了(le)驅動的(de)設計(jì),替代了(le)之前的(≥¶>de)引擎和(hé)模式擴展,并且改進了(le)行(xín ↑δ£g)為(wèi)的(de)設計(jì),使得(de)框架整體(tǐ€δ)更加靈活,并且由于在需要(yào)寫入數(shù)據的(de)功 αγ能(néng)類庫中都(dōu)采用(yòng)了(le)驅動化(ε≥•huà)的(de)設計(jì)思想,所以使得(de)新的(de)β←♥框架能(néng)夠輕松滿足分(fēn)布式部署±₹♥的(de)需求,對(duì)雲平台的(de)支持可(kě)以更簡單的(σ♦✘δde)實現(xiàn)了(le)。因此,在新版的(de¶φ♣ )擴展裡(lǐ)面,已經取 消了(le)引擎擴展和≈∞≤(hé)模式擴展,改成配置不(bù)同的(de)應用™♣&©(yòng)模式即可(kě)。
驅動包括
ThinkPHP/Library/Think/Cache/Driver // 緩存驅動類庫ThinkPHP/Library/Think/Db/Driver // 數(shù)據庫驅動類庫ThinkPHP/Library/Think/Log/Driver // 日(rì)志(zhì)記錄驅動類庫ThinkPHP/Library/Think/Session/Driver // Session驅動類庫ThinkPHP/Library/Think/Storage/Driver // 存儲驅動類庫ThinkPHP/Library/Think/Template/Driver // 第三方模闆引擎驅動類庫ThinkPHP/Library/Think/Template/TagLib // 內(nèi)置模闆引擎标簽庫擴展類庫
行(xíng)為(wèi)(Behavior)是(εφ¶shì)ThinkPHP擴展機(jī)制(zhì)中比較關鍵的(de)≠×一(yī)項擴展,行(xíng)為(wèi)既可(kě)以獨$β♦Ω立調用(yòng),也(yě)可(kě)以綁定到(dào)某個(gè)♦ 标簽(位)中進行(xíng)偵聽(tīng)。這(zhè≤≠×™)裡(lǐ)的(de)行(xíng) 為(wèi)指•≥的(de)是(shì)一(yī)個(gè)比→γα較抽象的(de)概念,你(nǐ)可(kě€'₽)以想象成在應用(yòng)執行(xín∞g)過程中的(de)一(yī)個(gè)動作(zuò)&¥₹≠或者處理(lǐ),在框架的(de)執行(xíng λ∞♦)流程中,各個(gè)位置都(dōu)可(kě)以<₽♦有(yǒu)行(xíng)為(wèi)産生(shēn₽•α±g),例如(rú)路(lù)由檢測是(shì)一εε(yī)個(gè)行(xíng) 為(wèi),靜(jìng)态緩Ω₽存是(shì)一(yī)個(gè)行(xíng)為(wèi•'¥),用(yòng)戶權限檢測也(yě)是(shì)行(xíng)為(wèi>✘β₹),大(dà)到(dào)業(yè)務邏輯,小(xiǎo)βγ到(dào)浏覽器(qì)檢測、多(duō)語↔₽言檢測等等都(dōu)可(kě)以當做(zuò)是(shì)一(y§™↔ī)個(gè)行(xíng)為(wèi),甚至說(shu ←β∑ō)你(nǐ)希望給你(nǐ)的(de)網站(zhàn)用(yòng)戶₹®<的(de)第一(yī) 次訪問(wèn)彈出δ'Hello,world!這(zhè)些(xi✘≥×ē)都(dōu)可(kě)以看(kàn)成是(shì'×<∏)一(yī)種行(xíng)為(wèi),行(xíng±β®)為(wèi)的(de)存在讓你(nǐ)無需改動框架和(hé)應用(yò₽Ωng),而在外(wài)圍通(tōng)過擴展或者配置來(lá $€✘i)改變或者增加一(yī)些(xiē)功能(néng)。
而不(bù)同的(de)行(xíng)為(w↕↑èi)之間(jiān)也(yě)具有(yǒu)位置共同性,比如(rú),有←$•(yǒu)些(xiē)行(xíng)為(wèi)的(de)↔€≈作(zuò)用(yòng)位置都(dōu)是(shì)在應用(yò∏§ £ng)執行(xíng)前,有(yǒu)些(xiē)行(xíng)為(wèi)♦ >都(dōu)是(shì)在模闆輸出之後,我們把這(zhè)些(xiē)行(x≠₩$∑íng)為(wèi)發生(shēng)作(zuò€π♦)用(yòng)的(de)位置稱之為(wèi)标簽(位),也(yě)可(kě)以稱之為(wèi)鈎子(zǐ),當應用(yòn✔®∞↔g)程序運行(xíng)到(dào)這(zhè)'£✘個(gè)标簽的(de)時(shí)候,就(jiù)會(huì)被攔截下(xi•®≥à)來(lái),統一(yī)執行(xí©≠←ng)相(xiàng)關的(de)行(xíng)為(wèi),類似于AOP編程®☆✔中的(de)“切面”的(de)概念,給某一(yī)®&↕個(gè)标簽綁定相(xiàng)關行(xíng)為(wèi)就( ±₩≠jiù)成了(le)一(yī)種類AOP編程的(de)思想。
系統核心提供的(de)标簽位置包括(按照(zhào)↑σ≥←執行(xíng)順序排列):
在每個(gè)标簽位置,可(kě)以配置多(dδφ₩uō)個(gè)行(xíng)為(wèi),行(xíng)↑₹為(wèi)的(de)執行(xíng)順序按照(zhào)定義的(de)順序依♣§次執行(xíng)。除非前面的(de)行(xíng)為(wèi)裡(l←&αǐ)面中斷執行(xíng)了(le)(某些(xiē)行(xí≈ ng)為(wèi)可(kě)能(néng)需要(yào₽)中斷執行(xíng),例如(rú)檢測機(jī)器(qì)人(rén)或者非×€法執行(xíng)行(xíng)為(wèi)),否則會(huì $←₹)繼續下(xià)一(yī)個(gè)行(xíng<✔)為(wèi)的(de)執行(xíng)。
除了(le)這(zhè)些(xiē)系統內(nèi)置标簽之外(wài),開→₩(kāi)發人(rén)員(yuán)還(hái)可(kě)以在∏© ×應用(yòng)中添加自(zì)己的(de)應用(yòng)标簽,在任何需要↕¶₩(yào)攔截的(de)位置添加如(rú)下(xià)代碼即 ∏☆可(kě):
tag('my_tag'); // 添加my_tag 标簽偵聽(tīng)// 下(xià)面的(de)寫法作(zuò)用¶↕↑₽(yòng)一(yī)緻\Think\Hook::listen('my_tag');
tag函數(shù)用(yòng)于設置某個(gè)标簽位,可(kě)以傳入并✘↑且隻接受一(yī)個(gè)參數(shù↑×♦ε),如(rú)果需要(yào)傳入多(duō∏&×)個(gè)參數(shù),請(qǐng)使↕÷£用(yòng)數(shù)組,
tag('my_tag',$params); // 添加my_tag 标簽偵聽(tīng←•Ω)
該參數(shù)為(wèi)引用(yòng)傳值,所以隻能(néδ✔♦<ng)傳入變量,因此下(xià)面的(de)傳值是(shì)錯(cuò) ♣<Ω誤的(de):
tag('my_tag','param'); // 添加my_tag 标簽偵聽(tīng)
系統的(de)很(hěn)多(duō)核心←₩β"功能(néng)也(yě)是(shì)采用(yòng)行(x¥¶♣íng)為(wèi)擴展組裝的(de),對(duì)于滿足項目日(rì)益紛繁↑↕ 複雜(zá)的(de)需求和(hé)定制(zhì)底層↑←↑框架提供了(le)更多(duō)的(de)方便和(hé)可(k₹ ě)能(néng)性。
核心行(xíng)為(wèi)位于 ThinkPHP/Behavior/ 目錄下(xià)面,框架核心內(nèi)'♣置的(de)行(xíng)為(wèi)包括如(rú)下(xià):
| 行(xíng)為(wèi)名稱 | 說(shuō)明(míng) | 對(duì)應标簽位置 |
|---|---|---|
| BuildLite | 生(shēng)成Lite文(wén)件(jiàn$₹✘π)(3.2.1版本新增) | app_init |
| ParseTemplate | 模闆文(wén)件(jiàn)解析,并支持第三方模闆引擎驅動♦₩ | view_parse |
| ShowPageTrace | 頁面Trace功能(néng)行(xíng)為(×™¥wèi),完成頁面Trace功能(nén€☆&g) | view_end |
| ShowRuntime | 運行(xíng)時(shí)間(jiān©≥ε)顯示行(xíng)為(wèi),完成運行(€ γδxíng)時(shí)間(jiān)顯示 | view_filter |
| TokenBuild | 令牌生(shēng)成行(xíng)為(wèi)₩←☆,完成表單令牌的(de)自(zì)動生(shēng)成 | view_filter |
| ReadHtmlCache | 讀(dú)取靜(jìng)态緩存行(xínπ÷π↑g)為(wèi) | app_init |
| WriteHtmlCache | 生(shēng)成靜(jìng)态緩存行(xíng)為(wèi) | view_filter |
自(zì)定義的(de)擴展行(xíng)為(wèi)可(k♥×↑ě)以放(fàng)在核心或者應用(yò★ β₹ng)目錄,隻要(yào)遵循命名空(kōng∏®∑)間(jiān)的(de)定義規則即可(kě)。 行(xíng)¶±為(wèi)類的(de)命名采用(yònβ$g):行(xíng)為(wèi)名稱(駝峰σ "&法,首字母大(dà)寫)+Behavior 行(xíng)為(wπ£♠èi)類的(de)定義方式如(rú)下(xià):
namespace Home\Behavior;use Think\Behavior;class TestBehavior extends Behavior {// 行(xíng)為(wèi)擴展的(de)執行(xíng∏'₽←)入口必須是(shì)runpublic function run(&$params){if(C('TEST_PARAM')) {echo 'RUNTEST BEHAVIOR '.$params;}}}
3.2.1版本開(kāi)始,行(xíng)為(wèi)™"₹類的(de)定義無需繼承Think\Behavior類,所以,上(shàng)面的(de)定義₩ε可(kě)以簡化(huà)為(wèi):
namespace Home\Behavior;class TestBehavior {// 行(xíng)為(wèi)擴展的(de)執行(xíng< )入口必須是(shì)runpublic function run(&$params){if(C('TEST_PARAM')) {echo 'RUNTEST BEHAVIOR '.$params;}}}
行(xíng)為(wèi)類必須定義執行(xíng)入口方"法run,由于行(xíng)為(wèi)的(de)調用(yòng)機(jī)制∑"(zhì)影(yǐng)響,run方法不(bù)需要♠¥ (yào)任何返回值,所有(yǒu)返回都(dōu)通(tōng×→♦∞)過引用(yòng)返回。
run方法的(de)參數(shù)隻允許一(yī)個(gè),&±α₽但(dàn)可(kě)以傳入數(shù)組。
行(xíng)為(wèi)定義完成後,就(j ↓iù)需要(yào)綁定到(dào)某個(gè)标簽位置才能(néng)生 ≈(shēng)效,否則是(shì)不(bù)會(hu왩β∏)執行(xíng)的(de)。
我們需要(yào)在應用(yòng)的(de)行(xíπ∞×ng)為(wèi)定義文(wén)件(jiàn)tags.php文(wén)件(jiàn)中進行(xíng)行(xí★≤≈ng)為(wèi)和(hé)标簽的(de)位置定義,>© 格式如(rú)下(xià):
return array('标簽名稱1'=>array('行(xíng)為(wèi)名1','行(xíng)為(wèi)名2',...),'标簽名稱2'=>array('行(xíng)為(wèi)名1','行(xíng)為(wèi)名2',...),);
标簽名稱包括我們前面列出的(de)系統标簽和(hé)應用(yòng)中自(zì↕&δ)己定義的(de)标簽名稱,比如(rú)你(nǐ)需要(yào)在apβ✘✘p_init标簽位置定義一(yī)個(gè)Chec★♣γ↓kLangBehavior行(xíng)為(wèi)類的(de)話(huà™¥),可(kě)以使用(yòng):
return array('app_init'=>array('Home\Behavior\CheckLang'),// **如(rú)果是(shì)3.2.1版本 需要(yào)改成(後面不 £(bù)再重複說(shuō)明(míng)) &∞**// 'app_init'=>arra≠∞y('Home\Behavior\CheckLangBehavior♣≈¶€'),);
可(kě)以給一(yī)個(gè)标簽位定義多(duō)個(gè)行(xí€♠♥ng)為(wèi),行(xíng)為(wèi)的(d $e)執行(xíng)順序就(jiù)是(shì)定義的(de)先後順↔♠序,例如(rú):
return array('app_init'=>array('Home\Behavior\CheckLang','Home\Behavior\CronRun'),);
默認情況下(xià)tags.php中定義的(de)行(xíng←♠ו)為(wèi)會(huì)并入系統行(x§↑>íng)為(wèi)一(yī)起執行(xíng★↕£),也(yě)就(jiù)是(shì)說(shu©σ→ō)如(rú)果系統的(de)行(xíng)為(wèi)±↔&★定義中app_init标簽中已經定義了(le)其他(€tā)行(xíng)為(wèi),則會(hu®β¥ì)首先執行(xíng)系統行(xíng)為(wèi)擴展中定<↓義的(de)行(xíng)為(wèi),然後再執行(xíng)'≈項目行(xíng)為(wèi)中定義的(de)行(xíng)為(≤•§wèi)。例如(rú): 系統行(xíng)為(wèi)®γ ¶定義文(wén)件(jiàn)中定義了(le):
'app_begin' => array('Behavior\ReadHtmlCache', // 讀(dú)取靜(jìng)态緩存),
而應用(yòng)行(xíng)為(wèi)定義文(wén)件(jiàn)有≠•€ε(yǒu)定義:
'app_begin' => array('Home\Behavior\CheckModul☆<÷₹e','Home\Behavior\CheckLang',),
則最終執行(xíng)到(dào)app_begin标簽(位)的∞£₩®(de)時(shí)候,會(huì)依次執行(xíng):
Library\Behavior\ReadHtmlCacheHome\Behavior\CheckModuleHome\Behavior\CheckLang
三個(gè)行(xíng)為(wèi)(除非中間(jiān)某個(gè)¥φ行(xíng)為(wèi)有(yǒu)中止執行(xínλ>∑g)的(de)操作(zuò))。
如(rú)果希望應用(yòng)的(de)行(xíng)為(wèi)配置文 (wén)件(jiàn)中的(de)定義覆蓋系統的(de)行(xíng)為(w≤<φèi)定義,可(kě)以改為(wèi)為(wèi)如(rú)下(xià)方式→↑:
'app_begin' => array('Home\Behavior\CheckModu♦§£le','Home\Behavior\Check∏Lang','_overlay' => true,),
則最終執行(xíng)到(dào)app_begin标簽(位)的(de)Ω×'時(shí)候,會(huì)依次執行(xíng)下(xià)面兩個(gè)行→×β(xíng)為(wèi):
Home\Behavior\CheckModuleHome\Behavior\CheckLang
應用(yòng)行(xíng)為(wèi)的(de)定✘☆✘義沒有(yǒu)限制(zhì),你(nǐ)Ω α可(kě)以把一(yī)個(gè)行(xíng)為(wèi)綁定到(♦§dào)多(duō)個(gè)标簽位置執行(xíng),例如(rú):
return array('app_begin'=>array('Home\Behavior\Test'), // 在app_begin 标簽位添加Test行∏♣€±(xíng)為(wèi)'app_end'=>array('Home\Behavior\Test'), // 在app_end 标簽位添加Test行(xíngλ€)為(wèi));
行(xíng)為(wèi)的(de)調用(yòng)不(bù↓÷×δ)一(yī)定要(yào)放(fàng)到(dà♦ ∏o)标簽才能(néng)調用(yòng),如(rú)果需要(yào)的(de)β¶話(huà),我們可(kě)以在控制(zhì)器(qì)中≥λ§或者其他(tā)地(dì)方直接調用(yòng)行(δ±xíng)為(wèi)。例如(rú),我們可(kě)以把用(yòng)戶權限♣檢測封裝成一(yī)個(gè)行(xíng÷∞ )為(wèi)類,例如(rú):
namespace Home\Behavior;use Think\Behavior;class AuthCheckBehavior extends Behavior {// 行(xíng)為(wèi)擴展的(de)執行(÷× •xíng)入口必須是(shì)runpublic function run(&$return){if(C('USER_AUTH_ON')) {// 進行(xíng)權限認證邏輯 如(r©♣∞ú)果認證通(tōng)過 $return = tr ε$✔ue;// 否則用(yòng)halt輸出錯(cuò)誤信息}}}
定義了(le)AuthCheck行(xí♦>ng)為(wèi)後,我們可(kě)以在控制(zhì)器(qì)的('♦de)_initialize方法中直接用♣≠(yòng)下(xià)面的(de)方式調用(yòng):
B('Home\Behavior\AuthCheck'¥<♠→);
