10分钟教你理解Yii的别名机制 - 寻找它们

10分钟了解yii2 别名机制

要先说一句,不要尝试修改yii预定义的别名,除非你的脑袋被驴踢了

由于开发需要,我们有时需要将一些路径或url保存起来,避免直接写入代码中,于是我们一定了一个类似于常量的变量,在全局均可以使用,这个变量就叫别名,当然你也可以在配置文件中
进行设置。

在yii中我们可以人为指定别名并使用它们,并且、yii框架还默认提供了12个预定义的别名,即使你没看懂本文,记住这12个别名,也能极大的提高编码质量。

预定义的别名

  • @yii表示yii框架所在目录,也就是yii\BaseYii类文件所在的位置(vendor/yiisoft/yii2/BaseYii.php)
  • @app 表示应用运行的根目录、非web目录;
  • @vendor 表示composer第三方库安装目录,你通过composer安装,包括yiisoft核心库都在这里;
  • @bower 表示bower第三方库安装目录,一般在vendor/bower里(该库主要存放一些例如jquery的库文件);
  • @npm 表示npm第三方库安装目录,一般为vendor/npm;
  • @runtime 表示正在运行的应用的运行时用于存放运行时文件的目录,比如缓存、日志等等
  • @webroot 表示正在运行的应用的入口文件index.php文件所在的目录,一般是指@app/web,记住这里指的是物理路径;
  • @web 表示当前运行的Web应用程序的 base URL。它的值与 yii\web\Request::$baseUrl 相同,主要用于前端(末尾不带/)

一下4个只会在yii高级版本中看到,基础版请飞过

  • @common 表示通用文件夹
  • @frontend 表示前台应用所在的文件夹
  • @backend 表示后台应用所在的文件夹
  • @console 表示命令行应用所在文件夹

对于这12个预定义别名,重点关注的是@web,它是唯一一个url类型的,其他均为服务器物理路径,@web代表应用的url,且后面不带/斜杠

为何全局能用

是的,如果想全局使用,那就要在入口或yii这个应用建立之时就开始定义它们,只有这才可以。

那我就一步一步开始吧,首先我们访问入口文件,入口文件做了两件事

  1. 加载应用配置文件
  2. 将配置文件传递给application,生成一个 yii application

当程序执行了

(new yii\web\Application($config))->run();

我们解释就是$config传递给Application类,并且生成一个应用对象,这个新建过程由Application的构造函数完成。
而你也发现Application本身并没有构造函数,那么他使用的是其父类\yii\base\Application 的构造函数

public function __construct($config = [])
{
    Yii::$app = $this;
    static::setInstance($this);

    $this->state = self::STATE_BEGIN;

    $this->preInit($config);

    $this->registerErrorHandler($config);

    Component::__construct($config);
}

preInit 关键就在于preInit这个函数,它完成了类似@vendor、@runtime等预定义别名的定义工作,例如@vendor

public function setVendorPath($path)
    {
        $this->_vendorPath = Yii::getAlias($path);
        Yii::setAlias('@vendor', $this->_vendorPath);
        Yii::setAlias('@bower', $this->_vendorPath . DIRECTORY_SEPARATOR . 'bower');
        Yii::setAlias('@npm', $this->_vendorPath . DIRECTORY_SEPARATOR . 'npm');
    }

因为这些操作都是在入口文件实例化Application类的时候建立,因此在之后的所有操作中都可以直接使用预定义别名。

到此时你可能明白为何可以全局使用了吧。

非也,你会发现@web和@webroot并没有一个函数去定义它们!没错,因为\yii\base\Application 是yii抽象出来的基本Application类,实际运行中会有类似yii\web\Application、yii\console\Application进行继承然后实例化为各种场景的Application。

说到这里你不难理解没有@web和@webroot的预定义了吧,\yii\base\Application仅仅负责yii最基本的预定义别名的定义,而@web和@webroot属于web的东东,应该由子类yii\web\Application来定义,那么我们开始寻找它。

眼神1.5的你一定在 yii\web\Application 中发现了下面的代码

protected function bootstrap()
{
    $request = $this->getRequest();
    Yii::setAlias('@webroot', dirname($request->getScriptFile()));
    Yii::setAlias('@web', $request->getBaseUrl());

    parent::bootstrap();
}

是滴,我们的确找到了答案,现在所有的预定于别名都找到了出处,至于当我们建立Application对象的时候是如何调用bootstrap函数的,这里不进行说明,请你按类的继承关系进行分析,就知道咋回事了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值