溫馨提示×

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

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

PHP接口版本如何控制兼容多端接口

發(fā)布時(shí)間:2020-09-10 14:21:56 來(lái)源:億速云 閱讀:233 作者:小新 欄目:編程語(yǔ)言

這篇文章主要介紹PHP接口版本如何控制兼容多端接口,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

                                                       

PHP接口版本如何控制兼容多端接口

在對(duì)接第三方接口的時(shí)候,總是會(huì)看到接口后綴會(huì)帶著v1,v2這樣的標(biāo)識(shí),我們知道這些都是接口版本的概念,那么如果我方需要提供對(duì)外的接口,或者對(duì)接web端和APP端的時(shí)候,希望公用同一個(gè)接口,但是接口所渲染的數(shù)據(jù)表現(xiàn)形式不太一致,以及接口授權(quán)也不太一致的情況下,如何做到使用不同版本,且不同版本直接互不影響且同時(shí)共存呢?

首先筆者在考慮到接口設(shè)計(jì)時(shí),有幾大模塊:

  • 控制器層(controller):筆者將其定義為入口層(相當(dāng)于java的dao層)

  • 服務(wù)層(services):邏輯服務(wù)層,控制器入口層通過(guò)版本號(hào)標(biāo)識(shí)轉(zhuǎn)接到不同的服務(wù)層,具體的代碼邏輯實(shí)現(xiàn)都在此處編寫

  • 行為層(behavior):也可理解為事件層,服務(wù)中間件,行為鉤子都將在此處控制,入口權(quán)限過(guò)濾校驗(yàn),對(duì)接第三方服務(wù)擴(kuò)展通過(guò)行為鉤子抽出,不讓其加大服務(wù)層的代碼臃腫

  • 模型層(model):該層根據(jù)實(shí)際業(yè)務(wù)和開發(fā)習(xí)慣而定,可要可不要

  • 校驗(yàn)層(validate):筆者認(rèn)為很有必要,所有獨(dú)立拉出一個(gè)目錄來(lái)做相關(guān)校驗(yàn),不管是獨(dú)立校驗(yàn),校驗(yàn)引擎,還是框架自帶校驗(yàn)都在該目錄定義,方便維護(hù)和擴(kuò)展

  • 公共層(common):系統(tǒng)公共代碼,比如附件上傳,下載等

  • 配置層(config):內(nèi)部配置,根據(jù)需求自定義是否需要

  • 語(yǔ)言包(lang):根據(jù)需求而定

  • 復(fù)用層(tarits):根據(jù)實(shí)際需求而定

  • 任務(wù)層(job):根據(jù)實(shí)際需求而定

目錄層級(jí)如圖所示:
PHP接口版本如何控制兼容多端接口

那么在入口層如何轉(zhuǎn)接到服務(wù)層呢?因?yàn)樵谶@過(guò)程我們會(huì)將接口中的版本號(hào)轉(zhuǎn)接到不同的版本服務(wù)層。
首先在控制器入口層寫一個(gè)基類控制器,后續(xù)所有的控制器都將會(huì)繼承該類,在構(gòu)造函數(shù)中調(diào)取行為類中的解析服務(wù)層代碼,將服務(wù)層類初始化給基類變量!

    public $service = null;

    /**
     * 構(gòu)造函數(shù)處理頭部請(qǐng)求
     *
     * @return void
     */
    public function __construct($type = 0, Request $request)
    {
        // 登錄跳過(guò)
        if (!$type) {
            // 注冊(cè)行為監(jiān)聽(tīng)
            Hook::add('app_init', [
                // 校驗(yàn)請(qǐng)求接口的身份(身份驗(yàn)證)
                'app\\saas\\behavior\\AuthToken'
            ]);
            Hook::listen('app_init', []);
        }
        // 立即執(zhí)行初始化控制器服務(wù)應(yīng)用
        $this->service = Hook::exec('app\\saas\\behavior\\InitializtionService', ['tag' => $type, 'request' => $request]);
    }

服務(wù)InitializtionService解析路由,判斷,將服務(wù)層實(shí)例化

    public function run($params)
    {
        // 兼容控制器分層,優(yōu)化控制器目錄結(jié)構(gòu)
        $controller = request()->controller();
        $controllerArray = explode('.', $controller);
        $controllerLength = count($controllerArray);
        $appendControllerName = '';
        if ($controllerLength == 1) {
            $appendControllerName = $controllerArray[0];
        } else {
            for ($i = 0; $i < $controllerLength - 1; $i++) {
                $appendControllerName .= strtolower($controllerArray[$i]) . '\\';
            }
            $appendControllerName .= ucfirst($controllerArray[($controllerLength - 1)]);
        }

        // $controller =  '\\app\\saas\\controller\\' . request()->controller();
        $controller =  '\\app\\saas\\controller\\' . $appendControllerName;
        $verion = request()->param('version');
        $init_service = function () use ($controller, $verion, $params) {
            // dump($controller);
            // $controller = '\app\saas\controller\test\Test';
            $reflection = new \ReflectionClass($controller);

            if (property_exists($controller, 'versions')
                && isset($reflection->getStaticProperties()['versions'][$verion])
            ) {
                // 默認(rèn)規(guī)則返回,在前在后不允許返回其他信息
                $service = $reflection->getStaticProperties()['versions'][$verion];
                // 判斷控制器服務(wù)文件是否存在
                return class_exists($service) ? new $service($params['tag'], $params['request']) : Merror::getInstance()->jsonApi(40006);
            } else {
                Merror::getInstance()->jsonApi(40001);
            }
        };

        return is_null($verion) ? Merror::getInstance()->jsonApi(40002) : $init_service();
    }

這樣在控制器中文件定義如下調(diào)用服務(wù)層邏輯代碼,而不用關(guān)心是屬于哪個(gè)服務(wù)層類,服務(wù)層代碼只和版本有關(guān)

 class Sysorder extends Saas
 {
    /**
     * 版本服務(wù)調(diào)度屬性--必須默認(rèn)一個(gè)且是v1
     *
     * @var     array
     */
    protected static $versions = [
        'v1' => \app\saas\services\syscenter\Sysorder::class,
    ];

    /**
     * 獲取信息集權(quán)限目錄
     *
     * @method  POST|GET
     * @name    getSubMenuListCate
     */
    public function getSubMenuListCate()
    {
        return json($this->service->getSubMenuListCate());
    }

    /**
     * 獲取列表
     *
     * @method  POST|GET
     * @name    getSysOrderList
     */
    public function getSysOrderList()
    {
        return json($this->service->getSysOrderList());
    }

以上是PHP接口版本如何控制兼容多端接口的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

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

AI