一、类的自动加载
1.入口文件index.php核心文件Yii.php实现自动加载(文件在于yii\vendor\yiisoft\yii2.php)
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
该文件:
class Yii extends \yii\BaseYii
{
}
spl_autoload_register(['Yii', 'autoload'], true, true);
//读取映射表类
Yii::$classMap = require(__DIR__ . '/classes.php');
Yii::$container = new yii\di\Container();
自动加载分为两种,一为从映射表读取路径,二为拼接路径从本地读取
2.spl_autoload_register()函数会注册一个autoload方法,第一个参数是欲注册的自动装载函数,第二参数为注册失败时是否抛出异常,第三个参数TRUE则将函数添加至队列首,FALSE则在队列尾。spl_autoload_register()注册的方法是BaseYii::autoload()。
spl_autoload_register(['Yii', 'autoload'], true, true);
3.Yii::$classMap = require(__DIR__ . '/classes.php'); 映射表调用类名,文件在于yii\vendor\yiisoft\yii2=》classes.php
return [
'yii\base\Action' => YII2_PATH . '/base/Action.php',
'yii\base\ActionEvent' => YII2_PATH . '/base/ActionEvent.php',
'yii\base\ActionFilter' => YII2_PATH . '/base/ActionFilter.php',
'yii\base\Application' => YII2_PATH . '/base/Application.php',
'yii\base\ArrayAccessTrait' => YII2_PATH . '/base/ArrayAccessTrait.php',
'yii\base\Arrayable' => YII2_PATH . '/base/Arrayable.php',
'yii\base\ArrayableTrait' => YII2_PATH . '/base/ArrayableTrait.php',
'yii\base\Behavior' => YII2_PATH . '/base/Behavior.php',
'yii\base\BootstrapInterface' => YII2_PATH . '/base/BootstrapInterface.php',
'yii\base\Component' => YII2_PATH . '/base/Component.php',
'yii\base\Configurable' => YII2_PATH . '/base/Configurable.php',
'yii\base\Controller' => YII2_PATH . '/base/Controller.php',
...
];
例子:\YII:$classMap['app\models\Test'] = 'D:\文件存储路径\www\models\Test.php';
4.实现YII中的自动加载
是需要调用该组件时才调用,以此实现提高效率的结果。
YII程序流程:---》index.php ---> app ---》components(组件,如SESSION/REQUEST等)
---》controller(控制器)
BaseYii:autoload()函数:
public static function autoload($className)
{
if (isset(static::$classMap[$className])) {
$classFile = static::$classMap[$className];
if ($classFile[0] === '@') {
$classFile = static::getAlias($classFile);
}
} elseif (strpos($className, '\\') !== false) {
$classFile = static::getAlias('@' . str_replace('\\', '/', $className) . '.php', false);
if ($classFile === false || !is_file($classFile)) {
return;
}
} else {
return;
}
include($classFile);
if (YII_DEBUG && !class_exists($className, false) && !interface_exists($className, false) && !trait_exists($className, false)) {
throw new UnknownClassException("Unable to find '$className' in file: $classFile. Namespace missing?");
}
}
(1)、判断类文件是否已存在$classMap[$className]中,@是指别名,为TRUE则包含相应映射表中的类文件。
(2)、否则为FALSE,则拼接类文件路径进行拼接
(3)、引用该类文件
实际上第一步为检测该类文件是否存在框架自身的映射表中,否则映射表中不存在,第二三步则拼接路径后include该类文件