yii1框架寻找类的方法之import

来源:互联网 发布:php 抽象工厂模式 编辑:程序博客网 时间:2024/05/22 01:30

Yii加载类的工作由Yii本身完成,提供了两个方法的组合完成,import和autolod

/** * Imports a class or a directory.导入类或者目录 * * Importing a class is like including the corresponding class file.导入一个类就像导入相应的类文件 * The main difference is that importing a class is much lighter because it only 主要的区别在于导入类更快只是因为 * includes the class file when the class is referenced the first time.只有调用类的时候才会真正去把文件加载进来 * * Importing a directory is equivalent to adding a directory into the PHP include path.导入一个目录相当于添加目录到php的include path * If multiple directories are imported, the directories imported later will take 如果导入多个目录,这些目录会在需找类文件时候优选使用 * precedence in class file searching (i.e., they are added to the front of the PHP include path). * * Path aliases are used to import a class or directory. For example, * <ul> *   <li><code>application.components.GoogleMap</code>: import the <code>GoogleMap</code> class.</li>这是导入类 *   <li><code>application.components.*</code>: import the <code>components</code> directory.</li>这是导入目录 * </ul> * * The same path alias can be imported multiple times, but only the first time is effective.如果多次导入别名不会出错,但是只有第一次有效 * Importing a directory does not import any of its subdirectories.导入的目录不包含子目录 * * Starting from version 1.1.5, this method can also be used to import a class in namespace format 从八本1.1.5起这个方法就能通过命名空间格式导入类 * (available for PHP 5.3 or above only). It is similar to importing a class in path alias format, 命名空间的导入跟类类似 * except that the dot separator is replaced by the backslash separator. For example, importing 把点分隔符取代为基础分隔符(明明分隔符"\"基础分隔符"/") * <code>application\components\GoogleMap</code> is similar to importing <code>application.components.GoogleMap</code>.application\components\GoogleMap 相当于application.components.GoogleMap * The difference is that the former class is using qualified name, while the latter unqualified.区别在于前者用的是合格的名字,后者是不合格的 * * Note, importing a class in namespace format requires that the namespace corresponds to 导入的命名空间格式要求分隔符被替换成基础分隔符"."能是有效的路径 * a valid path alias once backslash characters are replaced with dot characters. * For example, the namespace <code>application\components</code> must correspond to a valid * path alias <code>application.components</code>. * * @param string $alias path alias to be imported * @param boolean $forceInclude whether to include the class file immediately. If false, the class file * will be included only when the class is being used. This parameter is used only when * the path alias refers to a class. * @return string the class name or the directory that this alias refers to * @throws CException if the alias is invalid */public static function import($alias,$forceInclude=false){//if(isset(self::$_imports[$alias]))  // previously imported , 缓存过return self::$_imports[$alias];if(class_exists($alias,false) || interface_exists($alias,false)) //缓存过return self::$_imports[$alias]=$alias;if(($pos=strrpos($alias,'\\'))!==false) // a class name in PHP 5.3 namespace format 如果包含"\"是命名空间,pos等于倒数第一的分隔符. 的位置{$namespace=str_replace('\\','.',ltrim(substr($alias,0,$pos),'\\'));//命名空间分隔符\ 换成 分隔符 .if(($path=self::getPathOfAlias($namespace))!==false) //之前是否加载过 . 分隔符的类{$classFile=$path.DIRECTORY_SEPARATOR.substr($alias,$pos+1).'.php';if($forceInclude){if(is_file($classFile))require($classFile);elsethrow 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;}elseself::$classMap[$alias]=$classFile;return $alias;}else{// try to autoload the class with an autoloader //这一步会调用系统的autoloaderif (class_exists($alias,true))return self::$_imports[$alias]=$alias;elsethrow 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 如果没有 . 分隔符,就是简单的加载类名 import("classname");{// try to autoload the class with an autoloader if $forceInclude is true 试图通过autoload导入类if($forceInclude && (Yii::autoload($alias,true) || class_exists($alias,true)))self::$_imports[$alias]=$alias;return $alias;}$className=(string)substr($alias,$pos+1);$isClass=$className!=='*';//如果最后不是*,是类   //class_exists 会调用 autoloadif($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');elsethrow 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;}elseself::$classMap[$className]=$path.'.php';//只是保存类路径,这里没有真正加载,等到autoload再加载return $className;}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);//set_include_path 会把这个目录加载到系统寻找类的根目录,php寻找类首选从这些目录下寻找,auoload中也不需要去寻找这些目录if(self::$enableIncludePath && set_include_path('.'.PATH_SEPARATOR.implode(PATH_SEPARATOR,self::$_includePaths))===false)self::$enableIncludePath=false;return self::$_imports[$alias]=$path;}}elsethrow new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',array('{alias}'=>$alias)));}


0 0
原创粉丝点击