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

2017-12-18  本文已影响0人  ambition_wy

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);
 


    }
上一篇 下一篇

猜你喜欢

热点阅读