自動加載和攔截器

2018-11-21 21:29 更新

PHALAPI-進(jìn)階篇3(自動加載和攔截器)

前言

先在這里感謝phalapi框架創(chuàng)始人@dogstar,為我們提供了這樣一個優(yōu)秀的開源框架.

最近工作上的事情比較多,所以文檔更新得比較慢,還望大家見諒!接下來為大家?guī)淼氖菍Υ丝蚣茏詣蛹虞d機(jī)制的一個小的引導(dǎo),簡單地來聊聊它是如何實(shí)現(xiàn)此類機(jī)制的,并在了解之后要怎樣去使用。同時再探討一下如何使用自動加載來構(gòu)建自己的公用函數(shù)以及攔截器,包括如何使用攔截器等,在這里強(qiáng)調(diào)一下,在進(jìn)階篇中談?wù)撍枷霑容^多,大家可以慢慢去消化。涉及的很多地方都是此框架優(yōu)秀的地方所在,因此,拿出來分享是為了讓大家能夠更好的了解phalapi框架,并且可以運(yùn)用到自己的代碼中去!

附上:

喵了個咪的博客:w-blog.cn

官網(wǎng)地址:http://www.phalapi.net/

開源中國Git地址:http://git.oschina.net/dogstar/PhalApi/tree/release

1. 自動加載機(jī)制

關(guān)于自動加載,使用phalapi框架的大家應(yīng)該已經(jīng)非常熟悉了。三層結(jié)構(gòu)自動加載請求調(diào)用在大家看來基本上感覺不到自動加載機(jī)制的存在,其實(shí),它早就被注冊到接口文件里了,只是有一套完整的機(jī)制來封裝這類事務(wù)讓我們摸不著,我們的接口文件就是在index.php

//裝載你的接口
DI()->loader->addDirs(array('Demo', 'Library'));

大家不妨進(jìn)入到addDirs里面瞧瞧

public function addDirs($dirs) {
    if(!is_array($dirs)) {
        $dirs = array($dirs);
    }
    $this->dirs = array_merge($this->dirs, $dirs);
}

其實(shí),當(dāng)我們使用到addDirs的時候,框架內(nèi)部只是把我們定義好的路徑存了起來;其實(shí)關(guān)鍵的地方已經(jīng)在初始化PhalApi_Loader的時候被觸發(fā)了,我們來一起看下PhalApi_Loader的構(gòu)造函數(shù)

public function __construct($basePath, $dirs = array()) {
    $this->setBasePath($basePath);
    if (!empty($dirs)) {
        $this->addDirs($dirs);
    }
    spl_autoload_register(array($this, 'load'));
}

第一句方法的意思是設(shè)置根目錄,后面一個判斷條件和我們使用addDirs是一樣的作用,那么問題來了spl_autoload_register做了什么呢?官方給出的解釋是這樣的:

將函數(shù)注冊到SPL__autoload函數(shù)隊列中。如果該隊列中的函數(shù)尚未激活,則激活它們

參數(shù)

欲注冊的自動裝載函數(shù)。如果沒有提供任何參數(shù),則自動注冊autoload的默認(rèn)實(shí)現(xiàn)函數(shù)spl_autoload()

其實(shí)說白了就是當(dāng)實(shí)例化類的時候找不到可以用的類的時候,就會請求在spl_autoload_register中定義好的處理方法,在此框架中配置的處理函數(shù)也就是PhalApi_Loader/load函數(shù)。

關(guān)于具體是如何實(shí)現(xiàn)匹配,如何找到路徑,再如何引入,這里就不詳細(xì)說明了。當(dāng)我們每次去new一個類的時候,都會先去尋找有沒有匹配的類,當(dāng)沒有匹配到的情況下,我們new的類名就會傳遞到PhalApi_Loader/load函數(shù)中去處理,根據(jù)框架規(guī)則引入我們需要的文件.

2. 公用函數(shù)和攔截器

當(dāng)我們會使用自動加載機(jī)制了之后,我們就可以來構(gòu)建我們項(xiàng)目的公用函數(shù)和攔截器了,為什么要使用公用函數(shù)呢?在大部分請求下我們一套框架可能支持多個項(xiàng)目,當(dāng)然項(xiàng)目與項(xiàng)目之間會有不同的函數(shù)等等,但是也有公用的比如debug,發(fā)送短信等等一些所有項(xiàng)目都可能去用到的一些功能性函數(shù),或者是一些針對項(xiàng)目的攔截器。

2.1 公共函數(shù)

首先在我們的根目錄建立一個文件夾叫做General通用的意思,里面分別有兩個文件夾Common(受TP的影響)和Intercept兩個文件,我們在里面放入我們自己的文件,當(dāng)然需要按照正確的規(guī)則比如Common_Base等

然后我們要使用的時候,先加載這個general文件作為自帶加載文件,然后注冊自己需要用的類,如下:

//加載項(xiàng)目通用文件
DI()->loader->addDirs('General');
//通用函數(shù)基礎(chǔ)類
DI()->base = new Common_Base();

2.2 攔截器

對于API來說,攔截器的意義無疑是巨大的,為什么這么說呢,應(yīng)為API是提供服務(wù)器的,我們可以用攔截器做很多的限制,比如限制開放接口,參數(shù)轉(zhuǎn)移、json解包、請求解密,token校驗(yàn)等等。

//攔截器
$Intercept           = new Intercept_app_default();
//轉(zhuǎn)換參數(shù)
$_REQUEST            = $Intercept->turnparameter($_REQUEST);

作為參考,攔截器接收所有的post和get參數(shù)后在內(nèi)部統(tǒng)一做處理。參數(shù)轉(zhuǎn)換、請求解密、token校驗(yàn)等這些都是日常用到的,不詳提。這里拿一個有代表性的來說明一下就是json解包,為什么要json解包呢?因?yàn)樵诤芏喙臼褂谜埱髠鲄⒌臅r候,都是封裝成一個json請求過來的,框架接收是能接收到,但是無法使用框架自帶的參數(shù)做完整性校驗(yàn)了。令我非常難受(也有很多朋友也遇到此類問題),所以自己寫了一個解包方法:

//遞歸解包
function test($params, $server){
    if(is_array($params)){
        foreach($params as $k => $v){
            $server[$k] = $v;
            $server = test($v, $server);
        }
    }
    return $server;
}
//模擬一個json數(shù)組
$params = array(
    'a' => array(
        'c' => 3,
        'd' => 4
    ),
    'b' => 2,
);
$server = array();
var_dump(test($params, $server));

我們獲取到的返回結(jié)果是array(4) { ["a"]=> array(2) { ["c"]=> int(3) ["d"]=> int(4) } ["c"]=> int(3) ["d"]=> int(4) ["b"]=> int(2) }也就是把數(shù)組中的底層元素全部移到了和a,b同級的目錄,并且也保證了a的數(shù)組完整性,必須要注意同名的問題。

3. 總結(jié)

本小節(jié),主要講述了一下關(guān)于自動加載的機(jī)制,以及為什么要使用攔截器的原因和怎么讓json通過攔截器也能使用框架的校驗(yàn)機(jī)制。今天就先到這里了,希望此教程能夠給你們帶來幫助。在下一小節(jié)中將會對model層和事務(wù)進(jìn)行已經(jīng)深入的講述。祝大家天天開心~

注:筆者能力有限,有說的不對的地方,希望大家能夠指出,也希望多多交流!

官網(wǎng)QQ交流群:421032344 歡迎大家的加入!

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號