yii浅析(二)

yii的入口文件
yii的入口文件

这里使用了一个第三方的配置管理插件:marcovwout,来管理Yii的配置,细节我就不说了。剩下的就是就是一些基本的全局变量设置了。往Yii::createWebApplication里面传入配置的数组,然后调用run方法,一个web应用是不是就这么跑起来了,是的,抽象到最高层就是这样:我往一个容器里面传入对应的配置,然后这个应用可以基于该配置正常运行起来。

说YiiBase中的两个比较重要的方法 (import,autoload)
YiiBase中的几个静态变量

然后看看YiiBase中的import方法就知道这些静态变量是干嘛用的了:

 /* Yii::import()
* $alias: 要导入的类名或路径
* $forceInclude false:只导入不include类文件,true则导入并include类文件
*/
  public static function import($alias, $forceInclude = false){    
  //Yii把所有的依赖放入到这个全局的$_imports数组中,名字不能重复
  //如果当前依赖已经被引入过了,那么直接返回
  if (isset(self::$_imports[$alias])) {        
        return self::$_imports[$alias];    
    }    
  //class_exists和interface_exists方法的第二个参数的值为false表示不autoload 
  if (class_exists($alias, false) || interface_exists($alias, false)) {        
      return self::$_imports[$alias] = $alias;    
  }    
  //如果传进来的是一个php5.3版本的命名空间格式的类(例如:\a\b\c.php)
  if (($pos = strrpos($alias, '\\')) !== false)  {        
    //$namespace = a.b
    $namespace = str_replace('\\', '.', ltrim(substr($alias, 0, $pos), '\\'));  
    //判断a.b这个路径是否存在,或者a.b只是alias里面的一个键,调用该方法返回这个键对应的值,比如'email' => realpath(__DIR__ . '/../vendor/cornernote/yii-email-module/email')
    if (($path = self::getPathOfAlias($namespace)) !== false) {      
       $classFile = $path . DIRECTORY_SEPARATOR . substr($alias, $pos + 1) . '.php';             
        if ($forceInclude) {                
          if (is_file($classFile)) {                    
              require($classFile);                
            } else {                    
            throw new CException(Yii::t('yii', 'Alias "{alias}" is invalid. Make sure it points to an existing PHP file and the file is readable.', array('{alias}' => $alias)));                
          }               
         self::$_imports[$alias] = $alias;            
         } else {                
          self::$classMap[$alias] = $classFile;            
        }           
       return $alias;        
    } else {            
// try to autoload the class with an autoloader            
    if (class_exists($alias, true)) {                
        return self::$_imports[$alias] = $alias;            
    } else {                
        throw new CException(Yii::t('yii', 'Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',                    array('{alias}' => $namespace)));            
    }        
   }    
 }    
if (($pos = strrpos($alias, '.')) === false) // a simple class name 
 {        
    // try to autoload the class with an autoloader if $forceInclude is true        
    if ($forceInclude && (Yii::autoload($alias, true) || class_exists($alias, true))) {            
      self::$_imports[$alias] = $alias;       
     }        
    return $alias;    
  }    
  $className = (string)substr($alias, $pos + 1);    
  
  $isClass = $className !== '*';   
  if ($isClass && (class_exists($className, false) || interface_exists($className, false))) {        
    return self::$_imports[$alias] = $className;    
  }    
  if (($path = self::getPathOfAlias($alias)) !== false) {        
      if ($isClass) {            
            if ($forceInclude) {                
                  if (is_file($path . '.php')) {                    
                          require($path . '.php');                
                  } else {                    
                          throw new CException(Yii::t('yii', 'Alias "{alias}" is invalid. Make sure it points to an existing PHP file and the file is readable.', array('{alias}' => $alias)));                
                          }                
                self::$_imports[$alias] = $className;            
          } else {                
                self::$classMap[$className] = $path . '.php';            
          }           
           return $className;       
       } 
       // $alias是’system.web.*’这样的已*结尾的路径,将路径加到include_path中
        else // a directory        
          {            
              if (self::$_includePaths === null) {       
                   self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path()));   
                     if (($pos = array_search('.', self::$_includePaths, true)) !== false) {                    
                unset(self::$_includePaths[$pos]);                
            }            
        }            
        array_unshift(self::$_includePaths, $path);            
        if (self::$enableIncludePath && set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) {                
          self::$enableIncludePath = false;            
          }            
          return self::$_imports[$alias] = $path;        
        }    
    } else {        
        throw new CException(Yii::t('yii', 'Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',            array('{alias}' => $alias)));    
        }
  }

是的,上面这个方法最后就把要加载的东西都放到$_imports,$_includePaths中去了。这就是Yii的import方法,好的,接下来我们看看autoload方法:

public static function autoload($className, $classMapOnly = false){    // use include so that the error PHP file may appear    
if (isset(self::$classMap[$className])) {              
    include(self::$classMap[$className]);    
} elseif (isset(self::$_coreClasses[$className])) {        
    include(YII_PATH . self::$_coreClasses[$className]);    
} elseif ($classMapOnly) {       
   return false;    
} else {        
  // include class file relying on include_path       
       if (strpos($className, '\\') === false) 
        // class without namespace        
        {            
            if (self::$enableIncludePath === false) {                
                  foreach (self::$_includePaths as $path) {                            
                        $classFile = $path . DIRECTORY_SEPARATOR . $className . '.php';                    
                        if (is_file($classFile)) {             
                             include($classFile);                        
                            if (YII_DEBUG && basename(realpath($classFile)) !== $className . '.php') {                            
                                throw new CException(Yii::t('yii', 'Class name "{class}" does not match class file "{file}".', array(                                '{class}' => $className,                                '{file}' => $classFile,                            )));                        
                            }                        
                            break;                    
                      }                
              }            
      } else {                
            include($className . '.php');            
              }        
  } else // class name with namespace in PHP 5.3       
     {            
          $namespace = str_replace('\\', '.', ltrim($className, '\\'));       
          if (($path = self::getPathOfAlias($namespace)) !== false) {   
           include($path . '.php');            
          } else {                
            return false;            
          }        
      }       
   return class_exists($className, false) || interface_exists($className, false);    }    return true;}

config文件中的 import 项里的类或路径在脚本启动中会被自动导入。用户应用里个别类需要引入的类可以在类定义前加入 Yii::import() 语句。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,183评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,850评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,766评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,854评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,871评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,457评论 1 311
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,999评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,914评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,465评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,543评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,675评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,354评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,029评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,514评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,616评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,091评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,685评论 2 360

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,711评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,859评论 6 342
  • 本文分为两部分:第一部分讲__autoload()函数实现的类自动加载。第二部分讲spl_autoload_reg...
    舒小贱阅读 2,559评论 1 4
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,166评论 30 470
  • 不能再这么没心没肺折腾下去了。 总不能一辈子不认识路一辈子依赖别人。
    嫩嫩的黄阅读 153评论 0 1