abei1982 2017-05-07 00:52:22 2453次浏览 0条回复 3 1 0

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

老规矩先来一个目录

  • 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会这样存储它们:

Snip20170506_15.png

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

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

Yii会这样存储它们:

Snip20170506_16.png

个别名

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

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

Snip20170506_17.png

义的别名,我说的不是变为空,而是彻底的注销。

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

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

是的,设置为空,则@webroot将从别名数组中将消失、是消失、是消失。 此刻你在运行

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

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

Snip20170506_18.png

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有一个整体的了解

Snip20170507_19.png

含别名开头的路径。**

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

//@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进行了如下图的操作

Snip20170507_21.png

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

更多yii视频和干货欢迎来我的小站 nai8.me

觉得很赞
    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册