Yii框架是一个比较快速的框架,其中有一点就是,使用它的Yii::import()可以先预加载autoload,然后,在真正需要的时候,再去require真正的代码。具体的实现如下:
1.预加载的方法。Yii::import(). 下面是实际的代码:
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
{
$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);
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
throw new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing directory.',
array('{alias}'=>$namespace)));
}
可以看到,上面的代码使用$forceInclude变量来控制,是立马require还是预加载。如果我们选择预加载,那么就会将这个类保存在classMap中,在真正使用到的时候,就会require进去。让我们看看autoload的代码:
public static function autoload($className)
{
// use include so that the error PHP file may appear
if(isset(self::$classMap[$className]))
include(self::$classMap[$className]);
else if(isset(self::$_coreClasses[$className]))
include(YII_PATH.self::$_coreClasses[$className]);
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');
}
可以看到,autoload的第一个逻辑就是在classMap中查找,这样就会较快速的实现预加载的功能。