yii2 aliases web.php,Yii2的深入学习--别名(Aliases),yii2aliases

Yii2的深入学习--别名(Aliases),yii2aliases

在之前自动加载机制的文章中,我们有提到别名,提到 getAlias 方法,大家当时可能不太清楚,这到底是什么,今天我们就来说一下别名。

别名用来表示文件路径和 URL,这样就避免了将一些文件路径、URL以硬编码的方式写入代码中,或者多处出现一长串的文件路径、URL。

在 Yii2 中,一个别名必须以 @ 字符开头,Yii2 预定义了大量可用的别名,预定义的别名如下:

@yii 表示Yii框架所在的目录,也是 BaseYii.php 文件所在的位置

@app 表示正在运行的应用的根目录

@vendor 表示Composer 第三方库所在目录,一般是 @app/vendor 或 @app/../vendor

@bower 表示 Bower 第三方库所在目录,一般是 @vendor/bower

@npm 表示 NPM 第三方库所在目录,一般是 @vendor/npm

@runtime 表示正在运行的应用的运行时用于存放运行时文件的目录,一般是 @app/runtime

@webroot 表示正在运行的应用的入口文件 index.php 所在的目录,一般是 @app/web

@web URL别名,表示当前应用的根URL,主要用于前端

@common 表示通用文件夹

@frontend 表示前台应用所在的文件夹

@backend 表示后台应用所在的文件夹

@console 表示命令行应用所在的文件夹

其他使用Composer安装的Yii扩展注册的二级别名

其中的 @common @frontend @backend 和 @console 在 baisc 的项目中是不会存在的。在 advanced 的项目中通常是定义在 common\config\bootstrap.php 文件中,其内容如下:

php

Yii::setAlias('common', dirname(__DIR__));

Yii::setAlias('frontend', dirname(dirname(__DIR__)) . '/frontend');

Yii::setAlias('backend', dirname(dirname(__DIR__)) . '/backend');

Yii::setAlias('console', dirname(dirname(__DIR__)) . '/console');

Yii2 中关于别名的设置和获取的方法都放在 BaseYii 类中,其结构基本如下:

phpclassBaseYii

{/**

* @var array registered path aliases

* @see getAlias()

* @see setAlias()

* Yii 的路径别名的 Map, 默认 @yii 指向当前目录*/

public static $aliases = ['@yii' =>__DIR__];/**

* Translates a path alias into an actual path.

* 将别名转化为真实的路径*/

public static function getAlias($alias, $throwException = true)

{...}/**

* Registers a path alias.

* 用一个真实的路径注册一个别名*/

public static function setAlias($alias, $path)

{...}

}

这是简化之后的 BaseYii 类的结构,其中有一个重要的变量 $aliases,两个重要的方法 getAlias 和 setAlias。$aliases 是存储 Yii2 路径别名的一个数组,key 是别名,value 是真实路径。getAlias 方法是根据别名获取到真实的地址,setAlias 是用一个真实的地址去注册一个别名。

先来看下 setAlias 方法,其内容如下:

/**

* Registers a path alias.

*

* 用一个真实的路径注册一个别名

*

* A path alias is a short name representing a long path (a file path, a URL, etc.)

* For example, we use '@yii' as the alias of the path to the Yii framework directory.

*

* A path alias must start with the character '@' so that it can be easily differentiated

* from non-alias paths.

*

* Note that this method does not check if the given path exists or not. All it does is

* to associate the alias with the path.

*

* Any trailing '/' and '\' characters in the given path will be trimmed.

*

* @param string $alias the alias name (e.g. "@yii"). It must start with a '@' character.

* It may contain the forward slash '/' which serves as boundary character when performing

* alias translation by [[getAlias()]].

* @param string $path the path corresponding to the alias. If this is null, the alias will

* be removed. Trailing '/' and '\' characters will be trimmed. This can be

*

* - a directory or a file path (e.g. `/tmp`, `/tmp/main.txt`)

* - a URL (e.g. `http://www.yiiframework.com`)

* - a path alias (e.g. `@yii/base`). In this case, the path alias will be converted into the

* actual path first by calling [[getAlias()]].

*

* @throws InvalidParamException if $path is an invalid alias.

* @see getAlias()*/

public static function setAlias($alias, $path)

{if (strncmp($alias, '@', 1)) {//如果不是以 @ 开头,就将 @ 拼到开头

$alias = '@' . $alias;

}//获取 / 在 $alias 中首次出现的位置

$pos = strpos($alias, '/');//如果 / 不存在,$root 就是整个 $alias,否则就是 $alias 中 / 前的内容

$root = $pos === false ? $alias : substr($alias, 0, $pos);if ($path !== null) {//如果 $path 以 @ 开头,使用 getAlias 去获取路径,否则,就去除掉最右边的 /

$path = strncmp($path, '@', 1) ? rtrim($path, '\\/') : static::getAlias($path);if (!isset(static::$aliases[$root])) {//如果不存在这个 $root 的别名

if ($pos === false) {//没有 /,就将 $path 直接赋值以为 $root 别名对应的路径

static::$aliases[$root] = $path;

}else{//否则,就将 $path 直接赋值为 $root 下的 $alias 的路径

static::$aliases[$root] = [$alias => $path];

}

}elseif (is_string(static::$aliases[$root])) {//如果存在,而且是个string类型

if ($pos === false) {//没有 /,意味着 $alias 就是 $root,直接覆盖即可

static::$aliases[$root] = $path;

}else{//否则,就合并到一起

static::$aliases[$root] =[$alias => $path,

$root => static::$aliases[$root],];

}

}else{//这种,正常是个 array 类型

// 直接添加进去即可

static::$aliases[$root][$alias] = $path;//krsort — 对数组按照键名逆向排序

// 可以做到优先匹配长的别名

krsort(static::$aliases[$root]);

}

}elseif (isset(static::$aliases[$root])) {//$path 为空且对应的别名有值存在,就是要移除相应的别名

if (is_array(static::$aliases[$root])) {//如果 $root 的别名对应一个 array,就只移除掉对应的别名即可

unset(static::$aliases[$root][$alias]);

}elseif ($pos === false) {//如果 $root 的别名对应不是一个 array 而且 $root 就是 $alias,就移除这个 $root 的别名

unset(static::$aliases[$root]);

}

}

}

下面举几个例子来说明,别名写入后,$aliases 中的内容变化。

//初始 BaseYii::aliases['@foo'] = 'path/to/foo'

Yii::setAlias('@foo', 'path/to/foo');//直接覆盖 BaseYii::aliases['@foo'] = 'path/to/foo2'

Yii::setAlias('@foo', 'path/to/foo2');/**

* 新增

* BaseYii::aliases['@foo'] = [

* '@foo/bar' => 'path/to/foo/bar',

* '@foo' => 'path/to/foo2',

* ];*/Yii::setAlias('@foo/bar', 'path/to/foo/bar');//初始 BaseYii::aliases['@bar'] = ['@bar/qux' => 'path/to/bar/qux'];

Yii::setAlias('@bar/qux', 'path/to/bar/qux');//直接覆盖 BaseYii::aliases['@bar'] = ['@bar/qux' => 'path/to/bar/qux2'];

Yii::setAlias('@bar/qux', 'path/to/bar/qux2');/**

* 新增

* BaseYii::aliases['@bar'] = [

* '@bar/foo' => 'path/to/bar/foo',

* '@bar/qux' => 'path/to/bar/qux2',

* ];*/Yii::setAlias('@bar/foo', 'path/to/bar/foo');/**

* 新增

* BaseYii::aliases['@bar'] = [

* '@bar/foo' => 'path/to/bar/foo',

* '@bar/qux' => 'path/to/bar/qux2',

* '@bar' => 'path/to/bar',

* ];*/Yii::setAlias('@bar', 'path/to/bar');/**

* 删除

* BaseYii::aliases['@bar'] = [

* '@bar/foo' => 'path/to/bar/foo',

* '@bar' => 'path/to/bar',

* ];*/Yii::setAlias('@bar/qux', null);/**

* 删除

* BaseYii::aliases['@bar'] = [

* '@bar/foo' => 'path/to/bar/foo',

* ];*/Yii::setAlias('@bar', null);

再来看一下 getAlias 方法,其内容如下:

/**

* Translates a path alias into an actual path.

* 将别名转化为真实的路径

*

* The translation is done according to the following procedure:

*

* 1. If the given alias does not start with '@', it is returned back without change;

* 2. Otherwise, look for the longest registered alias that matches the beginning part

* of the given alias. If it exists, replace the matching part of the given alias with

* the corresponding registered path.

* 3. Throw an exception or return false, depending on the `$throwException` parameter.

*

* For example, by default '@yii' is registered as the alias to the Yii framework directory,

* say '/path/to/yii'. The alias '@yii/web' would then be translated into '/path/to/yii/web'.

*

* If you have registered two aliases '@foo' and '@foo/bar'. Then translating '@foo/bar/config'

* would replace the part '@foo/bar' (instead of '@foo') with the corresponding registered path.

* This is because the longest alias takes precedence.

*

* However, if the alias to be translated is '@foo/barbar/config', then '@foo' will be replaced

* instead of '@foo/bar', because '/' serves as the boundary character.

*

* Note, this method does not check if the returned path exists or not.

*

* @param string $alias the alias to be translated.

* @param boolean $throwException whether to throw an exception if the given alias is invalid.

* If this is false and an invalid alias is given, false will be returned by this method.

* @return string|boolean the path corresponding to the alias, false if the root alias is not previously registered.

* @throws InvalidParamException if the alias is invalid while $throwException is true.

* @see setAlias()*/

public static function getAlias($alias, $throwException = true)

{/**

* strncmp — 二进制安全比较字符串开头的若干个字符

* int strncmp ( string $str1 , string $str2 , int $len )

* 如果 $alias 不是以 '@' 开头的,就不是一个 Yii 的别名*/

if (strncmp($alias, '@', 1)) {//not an alias

return $alias;

}//获取 / 在 $alias 中首次出现的位置

$pos = strpos($alias, '/');//如果 / 不存在,$root 就是整个 $alias,否则就是 $alias 中 / 前的内容

$root = $pos === false ? $alias : substr($alias, 0, $pos);//如果存在 $root 的别名

if (isset(static::$aliases[$root])) {if (is_string(static::$aliases[$root])) {//如果 $root 对应的别名是一个字符串,之直接返回 $aliases[$root] 或者 $aliases[$root] . substr($alias, $pos)

// 当 $root 就是 $alias 返回 $aliases[$root], 否则就在拼接上 $alias 除去 $root 后,剩下的字符串

return $pos === false ? static::$aliases[$root] : static::$aliases[$root] . substr($alias, $pos);

}else{//否则,要遍历整个 $aliases[$root] 数组,找到 $name 与 $alias 相同的值,返回 $path . substr($alias, strlen($name))

// 其实是返回了 $path 拼接上 $alias 除去 $root 后,剩下的字符串

foreach (static::$aliases[$root] as $name => $path) {if (strpos($alias . '/', $name . '/') === 0) {return $path . substr($alias, strlen($name));

}

}

}

}if ($throwException) {throw new InvalidParamException("Invalid path alias: $alias");

}else{return false;

}

}

好了,关于别名就先说这么多~~

对 Yii2 源码有兴趣的同学可以关注项目 yii2-2.0.3-annotated,现在在上面已经添加了不少关于 Yii2 源码的注释,之后还会继续添加~

有兴趣的同学也可以参与进来,提交 Yii2 源码的注释。

相关标签:线面

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值