Yii2中设置与获取别名的函数(setAlias和getAlias)用法分析


Posted in PHP onJuly 25, 2016

本文实例讲述了Yii2中设置与获取别名的函数(setAlias和getAlias)用法。分享给大家供大家参考,具体如下:

首先说说什么是别名

在Yii中有很多的路径,在开发的过程当前我们也会使用一些路径。一般来说都需要使用绝对路径,但绝对路径都很长。

所以,为了方便的使用路径,可以在Yi中i给每个路径起个名称,这个名称就是别名。

别名的格式:

别名必须以"@"字符开头,别名中还可以包含"/"。如("@www"为根别名,"@www/test"就为子别名)
别名最后的目录分隔符("\"或者"/")都将去掉(如果有的情况下)

别名的路径有以下几个格式:

目录路径或者文件的路径(`/tmp`, `/tmp/main.txt`)
URL(`http://www.yii2.com`)
另一个别名路径(`@yii/base`),这样会调用getAlias(),解析里面的别名。

设置别名:

Yii::setAlias("@www", "C:\www\");
Yii::setAlias("@data", "C:\www\data");
Yii::setAlias("@data/attach", "C:\www\data\attach\icon.png");
Yii::setAlias("@home", "www.yiifans.com\");
Yii::setAlias("@admin", "@www\admin");

设置别名的时候,如果路径里面包含别名那么会调用getAlias(),解析里面的别名。
如:别名@yii 对应的路径为/xxx/yii,那么@yii/base将会解析为/xxx/yii/base

获取别名:

获取别名路径的时候按如下顺序来:

如果别名不以"@"开头,直接返回别名,不作处理
查找相匹配的最长的别名,然后用别名路径来替换传入的参数中的别名。

如设置了两个别名"@foo"=>"my""@foo/test"=>"my/test"

如果用@foo/test/config来获取对应的路径,结果为"my/test/config"
如果用@foo/testtst/config来获取对应的路径,结果为"my/testtst/config"
如果用@foo/config来获取对应的路径,结果为"my/config"

即在匹配的时候会以"/"作为分隔符,先匹配最长的别名

上面设置的别名的结果分别为:

Yii::getAlias("@www");
//输出:C:\www
Yii::getAlias("@data");
//输出:C:\www\data
Yii::getAlias("@data/attach");
//输出:C:\www\data\attach\icon.png
Yii::getAlias("@home");
//输出:www.yiifans.com
Yii::getAlias("@admin");
//输出:C:\www\admin

设置别名函数源码:setAlias

public static function setAlias($alias, $path)
{
 if (strncmp($alias, '@', 1)) {
  //如果不是@开头,则自动在前面加上@
  $alias = '@' . $alias;
 }
 //查找别名中的"/"
 $pos = strpos($alias, '/');
 //如果别名中没有"/",则根别名就是所输入的别名,否则从截取"/"前面的作为根别名
 //如:@www,根别名就为@www;
 //如:@www/data,那么根别名截取为@www。
 $root = $pos === false ? $alias : substr($alias, 0, $pos);
 if ($path !== null) {
  /*
   * 如果路径中包含有别名,另直接调用getAlias来解析得到路径。
   * 否则去掉结尾的"/"、"\"
   */
  $path = strncmp($path, '@', 1) ? rtrim($path, '\\/') : static::getAlias($path);
  if (!isset(static::$aliases[$root])) {
   /*
    * 如果还没有设置过这个根别名(@www)
    *
    * 如果别名就是根别名(参数就是@www),则直接设置别名对应的路径(['@www'=>'路径'])
    * 否则生成路径为一个数组(['@www'=>['@www/data'=>'路径'])
    *
    * @www   ['@www'=>'xxxx']
    * @www/a   ['@www'=>['@www/a'=>xxxa]]
    * @www/b   ['@www'=>['@www/b'=>xxxb]]
    * @www/a/b   ['@www'=>['@www/a/b'=>xxxc]]
    *
    * 注:上面的这4中只会注册其中的一个,因为在上面判断了有没有注册@www
    */
   if ($pos === false) {
    static::$aliases[$root] = $path;
   } else {
    static::$aliases[$root] = [$alias => $path];
   }
  } elseif (is_string(static::$aliases[$root])) {
   /*
    * 注册过根别名(只有注册过根别名,对应的值才会是字符串)
    *
    * 如果当前注册的是根别名,直接覆盖旧值。
    * ['@www']=xxx
    *
    * 否则把当前别名和根别名添加到根别名数组中
    * @www/a  ['@www']=['@www/a'=>xxxa,'@www'=>'xxx']
    *
    */
   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]);
  }
 }
}

例如:

@www=>xxx        ['@www']=xxx
@www=>yyy        ['@www']=yyy
@www/a=>yyya      ['@www']=['@www/a'=>yyya,'@www'=>yyy]
@www/b=yyyb       ['@www']=['@www/a'=>yyya,'@www'=>yyy,'@www/b'=>yyyb]

也就是说,会把所有的相同根别名的数据,放到一个以根别名为键的数组中,而且对键进行逆向排序

获取别名函数源码:getAlias

public static function getAlias($alias, $throwException = true)
{
 //如果不是为@开头,直接返回alias
 if (strncmp($alias, '@', 1)) {
  // not an alias
  return $alias;
 }
 //获取根别名,和setAlias相同
 $pos = strpos($alias, '/');
 $root = $pos === false ? $alias : substr($alias, 0, $pos);
 if (isset(static::$aliases[$root])) {
  //如果根别名的值为字符串,即只设置了一个根别名(['@www'=>xxx])
  if (is_string(static::$aliases[$root])) {
   /*
    * 如果获取的名称为根别名,直接返回根别名对应的路径,
    * 否则返回值为根别名路径+去掉别名之后的路径
    *
    * 如:
    * @www,直接返回 xxx
    * @www/aaa/bbb 返回xxx/aaa/bbb
    */
   return $pos === false ? static::$aliases[$root] : static::$aliases[$root] . substr($alias, $pos);
  } else {
   /* 遍历子别名
    *
    * @www=>xxx  ['@www']=xxx
    * @www=>yyy  ['@www']=yyy
    * @www/a=>yyya  ['@www']=['@www/a'=>yyya,'@www'=>yyy]
    * @www/b=>yyyb  ['@www']=['@www/a'=>yyya,'@www/b'=>yyyb,'@www'=>yyy]
    * @www/a/c=>yyyac  ['@www']=['@www/a/c'=>yyyac,'@www/a'=>yyya,'@www/b'=>yyyb,'@www'=>yyy]
    */
   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;
 }
}

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

PHP 相关文章推荐
关于UEditor编辑器远程图片上传失败的解决办法
Aug 31 PHP
php网页病毒清除类
Dec 08 PHP
php使用curl打开https网站的方法
Jun 17 PHP
我整理的PHP 7.0主要新特性
Jan 07 PHP
PHP使用数组依次替换字符串中匹配项
Jan 08 PHP
PHP根据session与cookie用户登录状态操作类的代码
May 13 PHP
PHP与服务器文件系统的简单交互
Oct 21 PHP
微信封装的调用微信签名包的类库
Jun 08 PHP
PHP多进程编程之僵尸进程问题的理解
Oct 15 PHP
PHP封装的mysqli数据库操作类示例
Feb 16 PHP
浅谈php://filter的妙用
Mar 05 PHP
php模拟实现斗地主发牌
Apr 22 PHP
详解PHP实现定时任务的五种方法
Jul 25 #PHP
Yii2中YiiBase自动加载类、引用文件方法分析(autoload)
Jul 25 #PHP
PHP中session跨子域的三种实现方法
Jul 25 #PHP
Yii2创建控制器(createController)方法详解
Jul 23 #PHP
Yii2主题(Theme)用法详解
Jul 23 #PHP
Yii2创建表单(ActiveForm)方法详解
Jul 23 #PHP
Yii2验证器(Validator)用法分析
Jul 23 #PHP
You might like
什么是MVC,好东西啊
2007/05/03 PHP
PHP中文URL编解码(urlencode()rawurlencode()
2010/07/03 PHP
PHP日期处理函数 整型日期格式
2011/01/12 PHP
CI框架中libraries,helpers,hooks文件夹详细说明
2014/06/10 PHP
php抛出异常与捕捉特定类型的异常详解
2016/10/26 PHP
Yii2框架BootStrap样式的深入理解
2016/11/07 PHP
Js+Dhtml:WEB程序员简易开发工具包(预先体验版)
2006/11/07 Javascript
document.compatMode介绍
2009/05/21 Javascript
jquery 注意事项与常用语法小结
2010/06/07 Javascript
重构Javascript代码示例(重构前后对比)
2013/01/23 Javascript
JS获取农历日期具体实例
2013/11/14 Javascript
用js传递value默认值的示例代码
2014/09/11 Javascript
jquery实现鼠标滑过显示提示框的方法
2015/02/05 Javascript
AngularJS 如何在控制台进行错误调试
2016/06/07 Javascript
React实现双向绑定示例代码
2016/09/19 Javascript
详解require.js配置路径的用法和css的引入
2017/09/06 Javascript
react 实现页面代码分割、按需加载的方法
2018/04/03 Javascript
vue watch普通监听和深度监听实例详解(数组和对象)
2018/08/16 Javascript
Vue一个案例引发的递归组件的使用详解
2018/11/15 Javascript
JS实现深度优先搜索求解两点间最短路径
2019/01/17 Javascript
浅谈vue单页面中有多个echarts图表时的公用代码写法
2020/07/19 Javascript
Element Dialog对话框的使用示例
2020/07/26 Javascript
python在windows下实现备份程序实例
2014/07/04 Python
Python基于twisted实现简单的web服务器
2014/09/29 Python
对Pandas DataFrame缺失值的查找与填充示例讲解
2018/11/06 Python
Python reversed函数及使用方法解析
2020/03/17 Python
墨西哥运动服饰和鞋网上商店:Netshoes墨西哥
2016/07/28 全球购物
澳大利亚家具和家居用品在线商店:Interiors Online
2018/03/05 全球购物
EJB2和EJB3在架构上的不同点
2014/09/29 面试题
大学生学习生活的自我评价
2013/11/01 职场文书
迟到检讨书1000字
2014/01/15 职场文书
运动会800米加油稿
2014/02/22 职场文书
金融系应届毕业生求职信
2014/05/26 职场文书
音乐之声音乐广播稿
2014/09/10 职场文书
论文答辩开场白大全
2015/05/27 职场文书
解决IDEA翻译插件Translation报错更新TTK失败不能使用
2022/04/24 Python