PHP-API接口版本控制的问题

api 接口版本控制找了一下资料总共有几种类型

  1. 不设定版本模式意味着每个API只提供一个版本,如果要修改本API, 所有的用户都必须使用最新的API,任何API的修改都会影响到所有的用户。
  2. API自带版本模式同一个名称的API可以建立多个版本,API调用方根据自己的需求选择使用对应的API版本。新版本与老版本共存,意味着老版本用户不会受新版本更新的影响。
  3. 兼容性版本模式每个API只有一个版本,API需要兼容以前老版本API的功能。所有版本用户都调用同一个API,通过内在代码保证兼容性。
    具体一些内容可以看一下介绍https://juejin.im/post/5977f8ba5188255b9a6ad820

解决版本控制有5种类型
1.url增加版本编号
http://localhost/index.php/home/v1/index/test
2.url增加版本信息
http://localhost/index.php/home/index/test/v1
3.新增接口
http://localhost/index.php/home/index/newTest
4.客户端在做请求的时候在HTTP HEAD里面中添加API-VERSION字段,标识出请求的是哪个接口:
-H "API-VERSION: v1"
-H "API-VERSION: v2"
5.不同版本使用不同的域名,这样:
v1.api.xxx.com
v2.api.xxx.com

以下代码是基于TP3.2.3修改的:

用的是第一种url增加版本编号:http://localhost/index.php/home/v1/index/test

修改这个代码做法是:url可以全部统一修改为最新版本,如果最新版本不存在会自动查找低版本的接口
在网上查找的资料都是可以用那几种类型,没有具体事例,下面是我自己想法修改出来的代码。
修改的tp入口文件名 app.class.php

 /**
     * 执行应用程序
     * @access public
     * @return void
     */
    static public function exec() {
    
        if(!preg_match('/^[A-Za-z](\/|\w)*$/',CONTROLLER_NAME)){ // 安全检测
            $module  =  false;
        }elseif(C('ACTION_BIND_CLASS')){
            // 操作绑定到类:模块\Controller\控制器\操作
            $layer  =   C('DEFAULT_C_LAYER');
            if(is_dir(MODULE_PATH.$layer.'/'.CONTROLLER_NAME)){
                $namespace  =   MODULE_NAME.'\\'.$layer.'\\'.CONTROLLER_NAME.'\\';
            }else{
                // 空控制器
                $namespace  =   MODULE_NAME.'\\'.$layer.'\\_empty\\';                    
            }
            $actionName     =   strtolower(ACTION_NAME);
            if(class_exists($namespace.$actionName)){
                $class   =  $namespace.$actionName;
            }elseif(class_exists($namespace.'_empty')){
                // 空操作
                $class   =  $namespace.'_empty';
            }else{

                E(L('_ERROR_ACTION_').':'.ACTION_NAME);
            }
            $module  =  new $class;
            // 操作绑定到类后 固定执行run入口
            $action  =  'run';
        }else{
            //创建控制器实例  
            /****以下是修改的代码******/
            $p =  CONTROLLER_NAME;
            $c = explode('/', $p);
            $mod = substr($c[0], 0,1);
            if ($mod!='V') {
                $action  =  $c[1];
                $p = 'V1/'.substr($p, 0,stripos($p,'/'));
            }
            if (!controller($p)) {
                $p = explode('/', $p);
                $n =  substr($p[0], 1);
                $b = 'V'.$n;
                while  (!controller($b.'/'.$p[1])) {
                    $n = --$n;
                    $b = 'V'. $n;  
                    if ($n==0) {
                        
                        break;
                    }                       
                    if (controller($b.'/'.$p[1])) {
                        $module  =  controller($b.'/'.$p[1]);
                        break;
                    }
                    
                }
            }else{ 
                // $module  =  controller(CONTROLLER_NAME,CONTROLLER_PATH);  
                $module  =  controller($p); 
                $p = explode('/', $p);
                $n =  substr($p[0], 1);
            }
                      
        }
        if(!$module) {
            if('4e5e5d7364f443e28fbf0d3ae744a59a' == CONTROLLER_NAME) {
                header("Content-type:image/png");
                exit(base64_decode(App::logo()));
            }

            // 是否定义Empty控制器
            $module = A('Empty');
            if(!$module){
                E(L('_CONTROLLER_NOT_EXIST_').':'.CONTROLLER_NAME);
            }
        }
        
        // 获取当前操作名 支持动态路由
        if(!isset($action)){
            $action    =   ACTION_NAME.C('ACTION_SUFFIX');
        }
        try{
            self::invokeAction($module,$action);
        } catch (\ReflectionException $e) { 
            // 方法调用发生异常后 引导到__call方法处理
            self::isAction($n,$p,$action);
            $method = new \ReflectionMethod($module,'__call');
            $method->invokeArgs($module,array($action,''));
        }
        return ;
    }
    
    //增加判断该方法不存在时 查找下一个控制
    public static function isAction($n,$p,$action){
            
        
        if ($n==1) {
            $module  =  controller($b.'/'.$p[1]);
            self::isController($module);
            try{
                self::invokeAction($module,$action);
            } catch (\ReflectionException $e) { 
                // 方法调用发生异常后 引导到__call方法处理
                $method = new \ReflectionMethod($module,'__call');
                $method->invokeArgs($module,array($action,''));
            }
        }    
        $b = 'V'.--$n;                  
        if (controller($b.'/'.$p[1])) {
            $module  =  controller($b.'/'.$p[1]);
            try{
                self::invokeAction($module,$action);
            } catch (\ReflectionException $e) { 
                // 方法调用发生异常后 引导到__call方法处理
                self::isAction($n,$p,$action);
                $method = new \ReflectionMethod($module,'__call');
                $method->invokeArgs($module,array($action,''));
            }
        }
        self::isAction($n,$p,$action);
 


    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342