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
            ],
        ],
    ],

你可能感兴趣的:(Yii2基于header实现版本控制)