美文网首页
PHP-API接口版本控制的问题

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

作者: ambition_wy | 来源:发表于2017-12-18 15:39 被阅读0次

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

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/tcjmwxtx.html