abei1982 2017-04-28 02:40:18 2515次浏览 1条回复 6 5 0

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

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

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

预定义的别名

  • 表示Yii框架所在的目录,也是 yii\BaseYii 类文件所在的位置(vendor/yiisoft/yii2/BaseYii.php)
  • 表示正在运行的应用的根目录(非网站根目录)
  • @vendor 表示Composer第三方库所在目录,你通过composer下载的库,包含yiisoft核心库都在这里。
  • @bower 表示Bower第三方库所在目录,一般在vendor/bower里(该库主要存放一些例如jquery的库文件)
  • @npm 表示npm第三方库所在目录,一般是 @vendor/npm
  • @runtime 表示正在运行的应用的运行时用于存放运行时文件的目录,比如缓存、日志等等。
  • @webroot 表示正在运行的应用的入口文件 index.php 所在的目录,一般是 @app/web.记住,这是物理路径。
  • URL别名,表示当前应用的根URL,主要用于前端;(末尾没有斜杠/)

下面4个你会将在yii高级版中看到,基础版请飞过。

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

关于这12个别名,北哥提醒的是@web,这是所有预定于别名中唯一一个URL类型的(其他均为服务器物理路径),记住@web代表应用的URL,且后面没有/斜杠。

可能你还会说,这老多,我记不住啊.....

记不住就不记啊~

Yii::$aliases;

将上线的数组var_dump出来,用自己需要的就好了。

有了上面的开胃小菜,下面开始正题,说说别名的思路和运行轨迹。

为何全局都可以用?

是的,如果想全局使用,那就要在入口或yii这个应用建立之时就开始定义它们,只有这才可以,北哥以yii-basic作为例子,高级版请大家根据basic版本举一反三。

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

  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\Controller 进行集成然后实例化为各种场景下的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函数的,阿北这里不进行说明,请你按类的继承关系进行分析,就知道咋回事了。

一不小心又写了这么长,“寻找它们”就到这里,下一篇将为你讲解 getAliassetAlias 来个别名核心函数。

我的yii小站 http://nai8.me/sapper-index.html

觉得很赞
您需要登录后才可以回复。登录 | 立即注册