博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
10分钟教你理解Yii的别名机制 - set&get
阅读量:5899 次
发布时间:2019-06-19

本文共 4387 字,大约阅读时间需要 14 分钟。

这一章我们继续寻找它们。

老规矩先来一个目录

  • setAlias函数

  • getAlias函数

setAlias函数

通过对上一篇的学习,我们知道在一个yii application对象生成的过程中就已经通过setAlias方法对预定义的别名进行了初始化工作,在以后的程序代码中,可以随时使用它们,那么setAlias到底将这些别名放到了哪里那?

我们现在来揭开setAlias的面纱,根据Yii2的约定,setAlias被设计在YiiBase.php

//路径 vendor/yiisoft/yii2/BaseYii.phppublic static function setAlias($alias, $path){    if (strncmp($alias, '@', 1)) {        $alias = '@' . $alias;    }    $pos = strpos($alias, '/');    $root = $pos === false ? $alias : substr($alias, 0, $pos);    if ($path !== null) {        $path = strncmp($path, '@', 1) ? rtrim($path, '\\/') : static::getAlias($path);        if (!isset(static::$aliases[$root])) {            if ($pos === false) {                static::$aliases[$root] = $path;            } else {                static::$aliases[$root] = [$alias => $path];            }        } elseif (is_string(static::$aliases[$root])) {            if ($pos === false) {                static::$aliases[$root] = $path;            } else {                static::$aliases[$root] = [                    $alias => $path,                    $root => static::$aliases[$root],                ];            }        } else {            static::$aliases[$root][$alias] = $path;            krsort(static::$aliases[$root]);        }    } elseif (isset(static::$aliases[$root])) {        if (is_array(static::$aliases[$root])) {            unset(static::$aliases[$root][$alias]);        } elseif ($pos === false) {            unset(static::$aliases[$root]);        }    }}

现在通过对setAlias的分析来教大家如何设置一个别名。

if (strncmp($alias, '@', 1)) {    $alias = '@' . $alias;}

看完上面代码后你应该知道我们设置一个别名的时候Yii::setAlias($name,$val),$name可以不以@开头,Yii会自动去添加,当然如果你填了也没关系。

比如下面两个别名的设置是一个意思。

Yii::setAlias('@abei','/web/static');Yii::setAlias('abei','/web/static');

另外setAlias会将所有有效的别名存到YiiBase的$aliases变量中,并且它会将具有相同规范的别名放到一个别名数组中,这一点要注意,而setAlias的大部分逻辑也是在分析这个别名数组,它首先通过"/"标记符来分析别名名称,具体代码

$root = $pos === false ? $alias : substr($alias, 0, $pos);

例如我们设置如下的别名

Yii::setAlias('@abei','/web');Yii::setAlias('@abei/father','/web/father');

Yii会这样存储它们:

图片描述

还有我们如果设置了如下别名

Yii::setAlias('@abei/child','/web/child');Yii::setAlias('@abei/father','/web/father');

Yii会这样存储它们:

要注意:虽然setAlias通过"/"标记符来规划别名数组,但是只是受限于第一层,例如我们写了如下另个别名

Yii::setAlias('@abei/world/child','/web/child');Yii::setAlias('@abei/world/father','/web/father');

并不会存为二维数组,而依然是一维数组。

alt

到此刻你应该明白了具有相同前缀的别名在yii中的存在形式,还有一个很需要注意的事情,就是你如何注销一个已经定义的别名,我说的不是变为空,而是彻底的注销。

你只要按照下面的代码就可以

Yii::setAlias('@webroot',null);

是的,设置为空,则@webroot将从别名数组中将消失、是消失、是消失。

此刻你在运行

$a = Yii::getAlias('@webroot');echo $a;

一个报错出现了,它验证了我说明的:

alt

到此为止,北哥给你说了setAlias的一个实现思路,我们总结一下

  • 别名存放到了YiiBase的$aliases变量中

  • 当自定义的别名被/分隔的时候,Yii会以数组形式将其存放到$aliases变量中

  • 如果我们想注销一个已经存在的别名,需将其设置为null

我建议大家带着对setAlias的理解再学习下上一篇,别名的初始化,你会有更深刻的理解。

getAlias 函数

上面我们学习了将一个别名进行set,现在我们在说下Yii2是如何读取一个别名的那?

getAlias仍然在YiiBase.php文件中,代码如下:

//路径 vendor/yiisoft/yii2/BaseYii.phppublic static function getAlias($alias, $throwException = true){    if (strncmp($alias, '@', 1)) {        // not an alias        return $alias;    }    $pos = strpos($alias, '/');    $root = $pos === false ? $alias : substr($alias, 0, $pos);    if (isset(static::$aliases[$root])) {        if (is_string(static::$aliases[$root])) {            return $pos === false ? static::$aliases[$root] : static::$aliases[$root] . substr($alias, $pos);        }        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");    }    return false;}

当我们对setAlias函数了解后,对于getAlias变得再简单不过了,它只不过是对字符串类型的别名(如@wwwroot)和数组型别名(如@abei/world/child)的解析罢了。

我们先通过下图对getAlias有一个整体的了解

alt

通过上面代码知道,你在使用getAlias的时候一定要记住一点的是传递给getAlias应是一个别名或包含别名开头的路径。

例如下面的格式都是合法的

//@webroot和@abei/world/child被预先定义Yii::getAlias('@webroot');Yii::getAlias('@webroot/abc');Yii::getAlias('@abei/world/child');

但是你不能写

//@webroot被预先定义Yii::getAlias('abc@webroot');//不进行解析,直接返回abc@webrootYii::getAlias('@webrootabc');//报错,提示不存在改别名

最后要注意一点的就是,对于数组类型的别名,yii2会遍历整个数组,然后依次进行匹配,知道匹配到第一个和传递的参数吻合的后返回。

例如我们定义了2个别名

Yii::setAlias('@abei/world/child','/web/child');Yii::setAlias('@abei/world/father','/web/father');

然后我们在代码里使用的别名如下

Yii::getAlias('@abei/world/father/abc');

则Yii2进行了如下图的操作

alt

要记住的一点:匹配的是@xxxx/,末尾有个反斜杠哦。具体为何请自行思考,结合setAlias思考。

以上就是别名的定义和读取原则,当你读完后是否发现别名其实很easy,别想的太复杂~~

转载地址:http://eiesx.baihongyu.com/

你可能感兴趣的文章
[T-SQL]从变量与数据类型说起
查看>>
occActiveX - ActiveX with OpenCASCADE
查看>>
BeanUtils\DBUtils
查看>>
python模块--os模块
查看>>
Java 数组在内存中的结构
查看>>
《关爱码农成长计划》第一期报告
查看>>
学习进度表 04
查看>>
谈谈javascript中的prototype与继承
查看>>
时序约束优先级_Vivado工程经验与各种时序约束技巧分享
查看>>
minio 并发数_MinIO 参数解析与限制
查看>>
flash back mysql_mysqlbinlog flashback 使用最佳实践
查看>>
mysql存储引擎模式_MySQL存储引擎
查看>>
python类 del_全面了解Python类的内置方法
查看>>
java jni 原理_使用JNI技术实现Java和C++的交互
查看>>
java 重写system.out_重写System.out.println(String x)方法
查看>>
配置ORACLE 11g绿色版客户端和PLSQL远程连接环境
查看>>
ASP.NET中 DataList(数据列表)的使用前台绑定
查看>>
Linux学习之CentOS(八)--Linux系统的分区概念
查看>>
System.Func<>与System.Action<>
查看>>
asp.net开源CMS推荐
查看>>