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中文网,转载请注明出处,感谢您的尊重!

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

  1. LAMP环境中如何重新部署一个Yii2.0 web项目

    使用Yii2.0 framework开发的项目,使用Github进行版本控制,现在要把这个项目部署到一个新的电脑/系统中: (1)安装LAMP (2)在/var/www/html目录下执行 git c ...

  2. java web开发初学_2018年学习Web开发的绝对初学者指南

    java web开发初学 This post was originally published on Coder-Coder.com. 该帖子最初发布在Coder-Coder.com上 . If yo ...

  3. 好程序员Web前端教程分享Vue学习心得

    为什么80%的码农都做不了架构师?>>>    好程序员Web前端教程分享Vue学习心得,Vue是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向 ...

  4. 正则至少一个数字_好程序员web前端培训分享JavaScript学习笔记之正则

    好程序员web前端培训分享JavaScript学习笔记之正则,正则表达式,又名 "规则表达式" 由我们自己来书写 "规则",专门用来检测 字符串 是否符合 &q ...

  5. react组件卸载调用的方法_好程序员web前端培训分享React学习笔记(三)

    好程序员web前端培训分享React学习笔记(三),组件的生命周期 React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个阶段,初始化.运行中.销毁.错误处 ...

  6. Web前端开发基础三剑客学习知识分享

    Web前端开发基础知识学习路线分享,前端开发入门学习三大基础:HTML.CSS.JavaScript.除此之外还要学习数据可视化.Vue.React.Angular相关框架,熟练运用框架提升开发效率, ...

  7. WEB安全全基础漏洞学习

    本文省略了SQL注入和xss漏洞,需要的可以网上找资料,资料非常多 web安全全基础漏洞学习 CSRF 简介 跨站请求伪造 (Cross-Site Request Forgery, CSRF),也被称 ...

  8. 【ASP.NET Core Web API 6.0 基础学习】

    ASP.NET Core Web API 6.0 基础学习 半夏创建Web Api 6.0教程 返回时间格式化 Swagger注释和版本控制 使用appsetting.json的数据 IOC注入,使用 ...

  9. 基于web的c语言在线编译器的设计步骤,基于WEB的C语言在线学习系统毕业设计(全)..doc...

    PAGE 学科分类号 0806 本科生毕业设计 题目(中文):基于WEB的C语言在线学习系统的实现 (英文) The Implementation of an Online Learning Syst ...

最新文章

  1. 2022-2028年中国玻璃纤维毡热塑性塑料(GMT)行业市场研究及前瞻分析报告
  2. 自己试验写的一个文本转语音的一个小程序
  3. 教你查看Windows 7的详细系统版本号
  4. 关于oracle with as用法
  5. 万能的林萧说:我来告诉你,一个草根程序员如何进入BAT。 - 今日头条(www.toutiao.com)...
  6. 剑指offer面试题58 - I. 翻转单词顺序(双指针)
  7. Delphi XE不生成__history目录
  8. 基于新浪微博API生成短链接的15款在线工具
  9. 植物大战僵尸:实现灵魂收割者
  10. 扫描仪显示计算机繁忙或故障,为什么我的兄弟打印机每次扫描图像文件总是显示连接计算机,但是电脑就没有弹出那个框让我选择?请求高手...
  11. 求圆面积 输出精度要求
  12. matlab矩阵特征分解,用MATLAB实现矩阵分解
  13. 禁止浏览器返回登入页面
  14. Altium Designer 错误: Component U1 LM833MM has unused sub-part (2).
  15. S.M.A.R.T 参数详解及推荐指标
  16. 2022年阿里全球数学竞赛中的集福活动(附代码解答)
  17. 为XV6系统扩展一个系统调用需要修改的文件
  18. 移动机器人路径规划算法及思考——A*算法
  19. 迅雷投身区块链,两年投入3亿开发共享计算及区块链
  20. 2022年湖北助理工程师职称评审费用是多少?多久出证呢?甘建二

热门文章

  1. SampleGrabber开发问题与解决方案
  2. 腾讯T9级到底需要什么样的技术水平?我们又该如何学习?
  3. 服务器nvme硬盘识别不了,NVMe硬盘无法安装win7怎么办|安装win7找不到nvme硬盘解决方法...
  4. 智能车八邻域图像算法_二
  5. ubuntu 关闭 笔记本键盘背景灯
  6. 教你如何做出一份报表:流程分析之报表模板
  7. Mac电脑高效办公必备武器——雷神Thor
  8. linux环境安装部署RF+Jenkins+Git(非完整版)
  9. css3制作手风琴,CSS3制作手风琴——CSS3 :target的应用
  10. 飞腾桌面腾锐D2000 核心板