Yii的版本化

本文连接:https://www.cnblogs.com/alanabc/p/10246023.htmlhtml

讲解思路

把关系提到前面来说,但愿可以大体说清楚吧:web

  • 版本化须要路由支持,这样才能从URL中解析并定位到方法;
  • 定位方法须要先定位到控制器;
  • 控制器有两种:
    • 一种是默认的,经过controllerNamespace进行指定
    • 另外一种是组件里的,经过组件的“加载”进行指定

Yii的版本化,说白了就是经过路由,把URL定位到对应的方法去。浏览器

咱们这里用Yii的基础版(basic)做为讲解模板吧。服务器

路由机制

路由机制的工做过程,简单来讲就是:yii2

  • 当客户端(好比浏览器)发起请求时,先经过URL定位文件,而后把请求送达这个文件进行处理和响应。
  • 若没法经过URL直接定位到文件,则经过index.php来接收请求(这里可能须要配置一下你的web服务器)。app

  • index.php接收到请求后,先送达路由管理器,经过路由解析出URL对应的方法,而后送达这个方法,由方法受理请求并做出响应。框架

  • 当没法定位到文件也没法解析出方法时,通常来讲作404错误处理,表示资源不存在。yii

如何定位

在框架中,除了静态资源是直接定位文件,其余的请求都是路由到某个方法进行处理。Yii是一个面向对象的框架,路由表经过命名空间来一步一步的解析class、action,肯定处理请求的方法。好比,在基础版中,请求URL<域名>/index.php?r=site/index,定位到SiteControlleractionIndex方法。ide

那么路由表是怎么知道,URL里的site指的就是SiteController呢?继续看:

控制器命名空间 - controllerNamespace

Yii的配置文件里,有一项很重要的配置是controllerNamespace,顾名思义就是控制器的命名空间。在基础版里,它大概是这么配置的:'controllerNamespace' => 'app\controllers',根据这个命名空间,路由就能找到控制器的目录,而后就能定位到控制器和方法了。固然,你看不到它,由于这是核心框架的默认配置。若是你想要验证个人说法,那么:

vendor\yiisoft\yii2\base\Application.php line 95

/**
 * @var string the namespace that controller classes are located in.
 * This namespace will be used to load controller classes by prepending it to the controller class name.
 * The default namespace is `app\controllers`.
 *
 * Please refer to the [guide about class autoloading](guide:concept-autoloading.md) for more details.
 */
public $controllerNamespace = 'app\\controllers';

当你请求URL<域名>?r=site/index时,路由会去寻找app\controllers\SiteController这个类(其实就是去应用根目录下的controllers里寻找SiteController.php文件),而后找到里面的actionIndex方法。

凭什么site就对应SiteController类,index就对应actionIndex方法?它也是默认的配置!不过那就是另外一件话题了。

模块 - modules

你使用过Yii自带的debug组件吗?若是没有,那你应该知道,当启用了这个组件,你就有两种方式能够使用它:一是在页面的右下角,会有一个Yii的小logo,展开它就是debug组件;二是经过<域名>/index.php?r=debug/default/index,直接打开debug页面。

yii-debug组件必然是有处理请求的方法的,但是为啥上面这个URL能够准肯定位到方法呢,controllerNamespace里没有配置过它呀?

其实yii-debug是一个组件(module),每个组件都由控制器、模型、视图等构成,是一个独立的小应用。对于这样的组件,咱们要在$config['modules']里配置,而后就能挂载它,你就能够正常使用了。也正是这个“挂载”的过程,框架寻找到了对应的命名空间,就能够准确的找到控制器和方法了。

1547022485527.png

咱们来找找这个组件吧:vendor\yiisoft\yii2-debug,会找到文件Module.php

<?php
namespace yii\debug;
//use ...
class Module extends \yii\base\Module implements BootstrapInterface
{
    //...
}

它继承了\yii\base\Module类,这是一个模块类,你只须要知道,继承模块类的文件在对应的目录时,会被自动加载。

模块和版本化

组件的“挂载”大体就是这样。但是这和版本化有什么关系?关系可大了,咱们的版本化,就是依靠组件实现的。

先来梳理一下:

  • 版本化须要路由支持,这样才能从URL中解析并定位到方法;
  • 定位方法须要先定位到控制器;
  • 控制器有两种:
    • 一种是默认的,经过controllerNamespace进行指定
    • 另外一种是组件里的,经过组件的“加载”进行指定

动手作

咱们在上面看到,yii-debug组件是在配置项的$config['modules']里多加了一个debug组件,而且指明了'class' => 'yii\debug\Module'

仍然是拿Yii基础版来,作个简单的“版本化”:我如今打算增长一个version1应用,算是加了一个“版本1”吧。

编写配置

首先在配置文件web.php里:

$config = [
    //略...
    'modules' => [
        //这里class指定的是模块类,看下文
        'version1' => ['class' => 'app\version1\Version1'],
    ],
];

编写模块

上面配置里的class可不是乱写的哦!是有依据的。

在应用根目录下新建文件夹version1vendor同一级,兄弟文件夹),在文件夹内新建文件Version1.php做为一个模块类,继承\yii\base\Module。在这个类里面还指定了$controllerNamespace,注意跟上文提到的不同:上文指定的是整个应用的,这里指定的是组件本身的:

<?php
namespace app\version1;

class Version1 extends \yii\base\Module
{
    //这里指定的是组件本身的控制器命名空间
    public $controllerNamespace = 'app\version1\controllers';

    public function init()
    {
        parent::init();
    }
}

接下来在version1文件夹里继续新建三个子文件夹:

  • controllers:控制器文件夹。里面的控制器文件,命名空间要写成namespace app\version1\controllers;
  • models:模型文件夹。里面的模型文件,命名空间要写成namespace app\version1\models;
  • views:视图文件夹

你只要像正常的那样在这三个文件夹里写你的代码就能够了。

编写路由

最后,去配置一下路由:

'urlManager' => [
    'enablePrettyUrl' => true,
    'enableStrictParsing' => true,
    'showScriptName' => false,
    'rules' => [
        'version1/<controller:[\w-]+>/<action:[\w-]+>'
            => 'version1/<controller>/<action>', //version1路由
        '<controller:[\w-]+>/<action:[\w-]+>'
            => '<controller>/<action>', //原有应用的路由(好比本来URL:<域名>/index.php?r=site/index,如今URL:<域名>/site/index)
        //其余略...
    ],
],

这样,访问URL<域名>/version1/site/index的时候,就路由到version1SiteControlleractionIndex方法进行处理。

结语

语言组织的不够好见谅!

API的版本化和上面的也没什么太大的区别,你能够试着把API作个版本化;还能够试着把Yii基础版配置成Yii高级版的样子,这样能够加深理解。

相关文章
相关标签/搜索