Yii2基于header实现版本控制

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

基类actions实现

public function actions()
{
    $parent = parent::actions();
    $actions = (new Version())->convertActionMap();
    return array_merge($parent, $actions);
}

Version类的实现

class Version extends Object
{
    // 根据自己的header版本标识相应改动
    public $versionParam = "Appver";
    public $actionMap = null;
    // 外部扩展action接口,可以放到配置中去
    public $class = 'frontend\models\VersionControl';

    public function getVersion()
    {
        return Yii::$app->getRequest()->getHeaders()->get($this->versionParam);
    }

    public function getActionMap()
    {
        if ($this->actionMap === null) {
            $version = $this->getVersion();
            $now = '';
            $action_map = [];
            $version_map = Yii::$app->params['version_map'] ?? [];
            foreach ($version_map as $v => $map) {
                if ($version >= $v) {
                    if ($v >= $now) {
                        $action_map = ArrayHelper::merge($map, $action_map);
                    } else {
                        $action_map = ArrayHelper::merge($action_map, $map);
                    }
                    $now = $v;
                }
            }
            $controller = Yii::$app->controller->id;
            $this->actionMap = $action_map[$controller] ?? [];
        }

        return $this->actionMap;
    }

    public function convertActionMap() {
        $action_map = $this->getActionMap();
        foreach ($action_map as $key => $map) {
            $action_map[$key] = [
                'class' => $this->class,
                'action' => $map,
            ];
        }

        return $action_map;
    }
}

VersionControl的实现

class VersionControl extends Action
{
    public $action;

    public function run()
    {
        // 只是一层跳转从端上访问的action跳到别的action
        return $this->controller->runAction($this->action);
    }
}

Params的配置

'version_map' => [
        '1.1.1' => [  // 版本
            'login' => [  // 控制器id
                'index' => 'index1',  // 旧action => 新action
            ],
        ],
    ],
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,803评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,901评论 25 709
  • 小的时候,大家都一样。在一起的时候很快乐,因为我们对这个世界的认知是懵懂的。 长大后,因为比较,因为面子,因为压力...
    黛儿阅读 2,801评论 0 0
  • 在Tableau制作过程中设置参数应该会经常用到,并且用参数可以解决很多特别麻烦的问题,接下来就见识一下参数的威力...
    小小韩_小小红阅读 35,013评论 4 16
  • 昨天开门红,恭喜一下。掌声在哪里٩(๑^o^๑)۶٩(๑òωó๑)۶ 昨晚打开网站准备娱乐的时候显示没比赛,今天下...
    我是壹根棍阅读 3,421评论 4 1

友情链接更多精彩内容