转自: http://tech.ddvip.com/2010-11/1290157560163148.htm
Yii应用的入口脚本引用出了Yii类,Yii类的定义:
class Yii extends YiiBase
{
}
由yiic创建的应用里Yii类只是YiiBase类的“马甲”,我们也可以根据需求定制自己的Yii类。
Yii(即YiiBase)是一个“helper class”,为整个应用提供静态和全局访问入口。
Yii类的几个静态成员:
$_aliases : 存放系统的别名对应的真实路径
$_imports :
$_classes :
$_includePaths php include paths
$_app : CWebApplication对象,通过 Yii::app() 访问到
$_logger : 系统日志对象
$_app 对象由 Yii::createWebApplication() 方法创建。
类自动加载
Yii基于php5的autoload机制来提供类的自动加载功能,自动加载器为YiiBase类的静态方法autoload()。
当程序中用new创建对象或访问到类的静态成员,php将类名传递给类加载器,由类加载器完成类文件的include。
autoload机制实现了类的“按需导入”,就是系统访问到类时才include类的文件。
YiiBase类的静态成员$_coreClasses 里预先存放了Yii自身的核心类名于对应的类文件路径。其他的Yii应用中用到的类可以用Yii::import() 导入,Yii::import()将单类的与对应类文件存放于$_classes中,以*通配符表示的路径加入到php include_path中。被Yii::import()导入的类文件或目录都记入$_imports中,避免多次导入。
/* Yii::import()
* $alias: 要导入的类名或路径
* $forceInclude false:只导入不include类文件,true则导入并include类文件
*/
public static function import($alias,$forceInclude=false)
{
// 先判断$alias是否存在于YiiBase::$_imports[] 中,已存在的直接return, 避免重复import。
if(isset(self::$_imports[$alias])) // previously imported
return self::$_imports[$alias];
// $alias类已定义,记入$_imports[],直接返回
if(class_exists($alias,false) || interface_exists($alias,false))
return self::$_imports[$alias]=$alias;
// 已定义于$_coreClasses[]的类,或名字中不含.的类,记入$_imports[],直接返回
if(isset(self::$_coreClasses[$alias]) || ($pos=strrpos($alias,'.'))===false) // a simple class name
{
self::$_imports[$alias]=$alias;
if($forceInclude)
{
if(isset(self::$_coreClasses[$alias])) // a core class
require(YII_PATH.self::$_coreClasses[$alias]);
else
require($alias.'.php');
}
return $alias;
}
// 产生一个变量 $className,为$alias最后一个.后面的部分
// 这样的:'x.y.ClassNamer'
// $className不等于 '*', 并且ClassNamer类已定义的, ClassNamer' 记入 $_imports[],直接返回
if(($className=(string)substr($alias,$pos+1))!=='*' && (class_exists($className,false) || interface_exists($className,false)))
return self::$_imports[$alias]=$className;
// $alias里含有别名,并转换真实路径成功
if(($path=self::getPathOfAlias($alias))!==false)
{
// 不是以*结尾的路径(单类)
if($className!=='*')
{
self::$_imports[$alias]=$className;
if($forceInclude)
require($path.'.php');
else
// 类名与真实路径记入$_classes数组
self::$_classes[$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);
set_include_path('.'.PATH_SEPARATOR.implode(PATH_SEPARATOR,self::$_includePaths));
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)));
}