美文网首页
yii浅析(二)

yii浅析(二)

作者: 柏树_Jeff | 来源:发表于2016-01-19 00:44 被阅读170次
    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() 语句。

    相关文章

      网友评论

          本文标题:yii浅析(二)

          本文链接:https://www.haomeiwen.com/subject/foykkttx.html