Yii2 官方给出的方案是基于url的版本控制,但是我们的versoin放在header里面,需要通过header来进行版本控制,实现如下: 首先在基类中实现actions,actions是针对controller的action扩展,看源码可以知道,在createAction中会先检查actionMap,而actionMap=actions(),也就是说actions里面的配置优先于controller的inline actions,这样我们就可以更改action了

public function actions()
{
$parent = parent::actions();
//通过Version类去统一控制,传递$this,使得调用对应action时能找到对应的类
$actions = (new Version())->convertActionMap($this);
return array_merge($parent, $actions);
}

  

Version类的实现

class Version
{
//改成你们hearder中的version标识字段
public $versionParam = "Appver";
public $actionMap = null; public function getVersion()
{
return Yii::$app->getRequest()->getHeaders()->get($this->versionParam);
} public function getActionMap()
{
if ($this->actionMap === null) {
$version = $this->getVersion();
$controller = Yii::$app->controller->id;
//version的配置我是放到了params里面,如果实现不一样,可以自己修改成方法调用
$version_map = Yii::$app->params['version_map'] ?? [];
$version_map = $version_map[$version] ?? [];
$this->actionMap = $version_map[$controller] ?? [];
}
return $this->actionMap;
} // 这个方法是给actions()调用的方法,需要传递具体的类$class,不然在执行action的时候会找不到对应的类报错
public function convertActionMap($class) {
$action_map = $this->getActionMap();
// 组装映射格式
foreach ($action_map as $key => $map) {
if (strpos($map, 'action') === false) {
$map = 'action' . trim($map);
}
$action_map[$key] = [$class, $map];
} return $action_map;
}
}

  

params的配置

'version_map' => [
// version
'1.1.1' => [
// 对应的controllerId
'login' => [
// 端上访问的action => 根据版本控制实际访问的action
'index' => 'index1',
],
],
],

  

这样当版本号是1.1.1时访问 your_host/login/index 实际调用的是your_host/login/index1 非1.1.1版本 还是调用your_host/login/index

Yii2 基于header 实现接口版本控制的更多相关文章

  1. Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试 (转)

    环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewrite_module modules/mod_ ...

  2. Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试

    环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewrite_module modules/mod_ ...

  3. Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试【转】

    环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewrite_module modules/mod_ ...

  4. SpringBoot系统列 5 - 接口版本控制、SpringBoot FreeMarker模板引擎

    接着上篇博客的代码继续写 1.接口版本控制 一个系统上线后会不断迭代更新,需求也会不断变化,有可能接口的参数也会发生变化,如果在原有的参数上直接修改,可能会影响线上系统的正常运行,这时我们就需要设置不 ...

  5. ASP.NET Core WebApi基于JWT实现接口授权验证

    一.ASP.Net Core WebApi JWT课程前言 我们知道,http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再 ...

  6. apiAutoTest:基于mitmproxy实现接口录制

    目录 apiAutoTest 目前功能 重大更新(个人认为) 本次更新 契机 根本 如何录制 录制的用例 执行录制的用例 执行结果 实现源码 参考资料 apiAutoTest 先软文介绍下:apiAu ...

  7. Django(70)接口版本控制

    前言   在RESTful规范中,有关版本的问题,用restful规范做开放接口的时候,用户请求API,系统返回数据.但是难免在系统发展的过程中,不可避免的需要添加新的资源,或者修改现有资源.因此,改 ...

  8. Matlab与.NET基于类型安全的接口混合编程入门

    原文:[原创]Matlab与.NET基于类型安全的接口混合编程入门 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标. [原创分享]Matlab.NET混编调用Figure窗体 ...

  9. 用yii2给app写接口(下)

    上一节里我们讲了如何用Yii2搭建一个能够给App提供数据的API后台应用程序.那么今天我们就来探讨下授权认证和通过API接口向服务器提交数据以及如何控制API接口返回那些数据,不能返回那些数据. 授 ...

随机推荐

  1. DCL:管理用户

    1. 管理用户 (1) 查询用户 MySQL把用户的数据存放在 "mysql" 数据库的 "user" 表中. SELECT * FROM user; (2) ...

  2. Go 与 JSON

    Go 中通过标准库encoding/json.encoding.xml.encoding/asn1和其他库对 JSON.XML.ASN.1 和其他类型的标准的编码和解码提供了良好的支持,这里对使用最多 ...

  3. C#中 Dictionary<>的使用及注意事项

    1,如果在主体代码中使用,直接在初始化中生成就行 2如果在其他层,比如逻辑层,要注意在事件内部定义,在外部的话,重复调用就会提示“”“已经定义了相同的KEY”,见例子 (例子是转的) Dictiona ...

  4. 两个ESP8266一个作为服务器一个作为客户端实现互相通讯

    两个ESP8266一个作为服务器一个作为客户端实现互相通讯

  5. android滑动标题栏渐变实现

    import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.sup ...

  6. ubuntu 12.04 以固定 IP 地址连接网络并配置DNS

    sudo vim /etc/network/interfaces auto eth0 iface eth0 inet static address 192.168.2.155 netmask 255. ...

  7. VisualStudio版本号

    VisualStudio的工程文件,后面的数字对应的VS的版本号, 71表示的VS2003, 80表示VS2005, 90表示VS2008, 10表示VS2010等.

  8. osg::Camera example

    #ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include<iostream> #include <osgV ...

  9. pycharm调用shell命令

    在pycharm中调用shell命令 1.调用普通命令 # -*- coding:UTF-8 -*- import subprocess subprocess.call(["ls /home ...

  10. Node.js中使用pipe拷贝大文件不能完全拷贝的解决办法

    原来的代码如下: var readable = fs.createReadStream( filepath ); var writable = fs.createWriteStream( outFil ...