yii2框架-yii2自身的自动加载(三)
来源:互联网 发布:淘宝宝贝排名查询软件 编辑:程序博客网 时间:2024/05/20 23:29
上一节说完了composer的自动加载,下面我们来说一下yii2自身的自动加载。
而Yii::$classMap = require(__DIR__ . '/classes.php')这一句定义了命名空间与实际路径的映射关系,将返回一个数组的形式,保存在一个静态的变量中,那么这个变量有什么用呢?
下面我们再来看看spl_autoload_register注册的autoload()函数,在BaseYii.php中定义如下:
$classFile = static::getAlias('@' . str_replace('\\', '/', $className) . '.php'
这句代码就是通过别名的方式来映射定义路径,比如:new \app\controllers\User,这个在$classMap肯定是找不到对应的关系的,所以这句代码会把\app\controllers\User先替换成@app/controllers/User,然后再通过static::getAlias('@app/controllers/User')解释别名,找到对应的实际文件路径,因为@app在配置文件中已经定义或者默认定义别名,getAlias()会负责解释,当然需要在@app下建立controllers的文件夹等,并将解释路径的值赋值变量$classFile,最后将这个路径包含进来。
所以总结一点:
我们可以在定义了别名的文件夹下@xxx,再建立文件夹aaa,然后定义文件bbb.php,那么在bbb.php的文件的命名空间就是xxx\aaa,这个文件的类名就是bbb。那么我们就可以在任何的地方直接用 new \xxx\aaa\bbb()的形式类创建实例。发生的过程大概就是这样子:
a)因为我们在入口文件首先注册composer的自动加载函数,放在spl的堆栈中
b)接着,我们又注册yii2自身的自动加载函数,放在spl的堆栈中,根据栈的后入先出的原则,yii2注册的函数将放在composer注册函数的前面,如果要用自动加载函数的话,首先用yii2自身注册的。
c)所以当我们 new \xxx\aaa\bbb 的时候,首先会从堆栈中调用yii2自身注册的autoload()函数,查找在yii2的本身是否存在对应的映射关系,如果找到,就直接包含文件进来,并实例化。如果找不到,再到yii2定义的别名的文件夹下面找,如果找到,就直接包含文件进来,并实例化。如果在yii注册的函数里都找不到,则接着调用spl堆栈的第二个自动函数,即composer自定义的autload()函数,按照函数定义的方式一直往下找,知道找到为止.如果确实找不到会返回错误。
在我们的入口文件,例如index.PHP,代码如下:
<?php // comment out the following two lines when deployed to production defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); require(__DIR__ . '/../vendor/autoload.php'); require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php'); $config = require(__DIR__ . '/../config/web.php'); (new yii\web\Application($config))->run();我们可以注意到require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php'),将yii2的核心的函数包含进去,下面看看Yii.php的代码:
<?php /** * Yii bootstrap file. * * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */ require(__DIR__ . '/BaseYii.php'); /** * Yii is a helper class serving common framework functionalities. * * It extends from [[\yii\BaseYii]] which provides the actual implementation. * By writing your own Yii class, you can customize some functionalities of [[\yii\BaseYii]]. * * @author Qiang Xue <qiang.xue@gmail.com> * @since 2.0 */ class Yii extends \yii\BaseYii { } spl_autoload_register(['Yii', 'autoload'], true, true); Yii::$classMap = require(__DIR__ . '/classes.php'); Yii::$container = new yii\di\Container();首先包含BaseYii.php这个基础的yii文件,然后类Yii继承包含的Yii文件,命名空间是\yii\BaseYii,同时通过spl_autoload_register注册一个自动加载函数,这个函数是本类的autoload()函数,这些函数是在\yii\BaseYii中定义,而Yii类又继承\yii\BaseYii,所以Yii类相当于定义这些属性和方法。
而Yii::$classMap = require(__DIR__ . '/classes.php')这一句定义了命名空间与实际路径的映射关系,将返回一个数组的形式,保存在一个静态的变量中,那么这个变量有什么用呢?
下面我们再来看看spl_autoload_register注册的autoload()函数,在BaseYii.php中定义如下:
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?"); } }其中参数$className代表的是命名空间的类名,这个函数首先根据类名$className从$classMap是否可以找到对应设置的映射关系,如果找到对应的映射关系,就把文件对应的路径解释出来,赋值变量$classFile,如果找不到对应的映射关系,则将这个命名空间类执行:
$classFile = static::getAlias('@' . str_replace('\\', '/', $className) . '.php'
这句代码就是通过别名的方式来映射定义路径,比如:new \app\controllers\User,这个在$classMap肯定是找不到对应的关系的,所以这句代码会把\app\controllers\User先替换成@app/controllers/User,然后再通过static::getAlias('@app/controllers/User')解释别名,找到对应的实际文件路径,因为@app在配置文件中已经定义或者默认定义别名,getAlias()会负责解释,当然需要在@app下建立controllers的文件夹等,并将解释路径的值赋值变量$classFile,最后将这个路径包含进来。
所以总结一点:
我们可以在定义了别名的文件夹下@xxx,再建立文件夹aaa,然后定义文件bbb.php,那么在bbb.php的文件的命名空间就是xxx\aaa,这个文件的类名就是bbb。那么我们就可以在任何的地方直接用 new \xxx\aaa\bbb()的形式类创建实例。发生的过程大概就是这样子:
a)因为我们在入口文件首先注册composer的自动加载函数,放在spl的堆栈中
b)接着,我们又注册yii2自身的自动加载函数,放在spl的堆栈中,根据栈的后入先出的原则,yii2注册的函数将放在composer注册函数的前面,如果要用自动加载函数的话,首先用yii2自身注册的。
c)所以当我们 new \xxx\aaa\bbb 的时候,首先会从堆栈中调用yii2自身注册的autoload()函数,查找在yii2的本身是否存在对应的映射关系,如果找到,就直接包含文件进来,并实例化。如果找不到,再到yii2定义的别名的文件夹下面找,如果找到,就直接包含文件进来,并实例化。如果在yii注册的函数里都找不到,则接着调用spl堆栈的第二个自动函数,即composer自定义的autload()函数,按照函数定义的方式一直往下找,知道找到为止.如果确实找不到会返回错误。
原文链接 :http://blog.csdn.net/u012979009/article/details/51479504
0 0
- yii2框架-yii2自身的自动加载(三)
- yii2框架-yii2自身的自动加载(三)
- yii2框架-composer的自动加载(二)
- yii2框架-composer的自动加载(二)
- yii2自动加载机制
- Yii2自动加载
- yii2的自动加载类文件
- yii2框架-理解yii2的架构(一)
- yii2框架-yii2的事件(五)
- yii2框架-yii2的rules验证(七)
- yii2框架-yii2的操作action(十)
- yii2框架-yii2的面包屑导航(十八)
- Yii2框架-理解Yii2的架构
- yii2框架的安装
- Yii2框架的搭建
- Yii2的YiiBase自动加载类、引用文件(autoload)
- yii2框架的错误处理
- Yii2框架gii的使用
- linux学习笔记--ss命令
- 线性求子序列最大平均值
- centos 安装Visual Studio Code
- 整理wmic使用,不重启变环境变量 .
- 关于java编写画图板的思考
- yii2框架-yii2自身的自动加载(三)
- TensorFlow 0.12 Estimators Models Layers学习笔记
- mysql 5.7 ERROR 1045 (28000): Access denied for user 'root'@'localhost'
- 屏幕适配基本概念
- 随机读写文件内容之RandomAccessFile类相关
- Haar Adaboost 检测自定义目标(视频车辆检测算法代码)
- PAT---B1041. 考试座位号(15)
- 用JSP输出九九乘法表
- 【ife】任务二十一:基础JavaScript练习(四)