【北哥工兵连】10分钟教你理解Yii的别名机制 - set&get [ 技术分享 ]
这一章我们继续寻找它们。
老规矩先来一个目录
- setAlias函数
- getAlias函数
setAlias函数
通过对上一篇的学习,我们知道在一个yii application对象生成的过程中就已经通过setAlias方法对预定义的别名进行了初始化工作,在以后的程序代码中,可以随时使用它们,那么setAlias到底将这些别名放到了哪里那?
我们现在来揭开setAlias的面纱,根据Yii2的约定,setAlias被设计在YiiBase.php
@@nai8@@
//路径 vendor/yiisoft/yii2/BaseYii.php
public 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会这样存储它们:
个别名
Yii::setAlias('@abei/world/child','/web/child');
Yii::setAlias('@abei/world/father','/web/father');
并不会存为二维数组,而依然是一维数组。
义的别名,我说的不是变为空,而是彻底的注销。
你只要按照下面的代码就可以
Yii::setAlias('@webroot',null);
是的,设置为空,则@webroot将从别名数组中将消失、是消失、是消失。 此刻你在运行
$a = Yii::getAlias('@webroot');
echo $a;
一个报错出现了,它验证了我说明的:
iases变量中
- 当自定义的别名被/分隔的时候,Yii会以数组形式将其存放到$aliases变量中
- 如果我们想注销一个已经存在的别名,需将其设置为null
我建议大家带着对setAlias的理解再学习下上一篇,别名的初始化,你会有更深刻的理解。
getAlias 函数
上面我们学习了将一个别名进行set,现在我们在说下Yii2是如何读取一个别名的那?
getAlias仍然在YiiBase.php文件中,代码如下:
//路径 vendor/yiisoft/yii2/BaseYii.php
public 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有一个整体的了解
含别名开头的路径。**
例如下面的格式都是合法的
//@webroot和@abei/world/child被预先定义
Yii::getAlias('@webroot');
Yii::getAlias('@webroot/abc');
Yii::getAlias('@abei/world/child');
但是你不能写
//@webroot被预先定义
Yii::getAlias('abc@webroot');//不进行解析,直接返回abc@webroot
Yii::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进行了如下图的操作
就是别名的定义和读取原则,当你读完后是否发现别名其实很easy,别想的太复杂~~
更多yii视频和干货欢迎来我的小站 nai8.me
共 0 条回复
abei1982 河南洛阳
最后登录:2020-04-14
在线时长:128小时48分
- 粉丝307
- 金钱4935
- 威望50
- 积分6715