yii浅析(二)

2016-01-19  本文已影响170人  柏树_Jeff
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() 语句。

上一篇 下一篇

猜你喜欢

热点阅读