Yii2框架类自动加载机制实例分析

本文实例讲述了Yii2框架类自动加载机制。分享给大家供大家参考,具体如下:

在yii中,程序中需要使用到的类无需事先加载其类文件,在使用的时候才自动定位类文件位置并加载之,这么高效的运行方式得益于yii的类自动加载机制。

Yii的类自动加载实际上使用的是PHP的类自动加载,所以先来看看PHP的类自动加载。在PHP中,当程序中使用的类未加载时,在报错之前会先调用魔术方法__autoload(),所以我们可以重写__autoload()方法,定义当一个类找不到的时候怎么去根据类名称找到对应的文件并加载它。其中__autoload()方法被称为类自动加载器。当我们需要多个类自动加载器的时候,我们可以使用spl_autoload_register()方法代替__autoload()注册多个类自动加载器,这样就相当于有多个__autoload()方法。spl_autoload_register()方法会把所有注册的类自动加载器存入一个队列中,你可以通过设置它的第三个参数为true来指定某个加载器放到队列的最前面以确保它最先被调用。Yii的类自动加载机制就是基于spl_autoload_register()方法的。

Yii的类自动加载机制要从它的入口文件index.PHP说起了,该文件源码如下:

rush:PHP;"> run();

文件中第4、5行代码分别引入了composer的类自动加载文件和yii的工具类文件Yii.PHP,Yii.PHP文件源码如下:

rush:PHP;"> require(__DIR__ . '/BaseYii.PHP'); class Yii extends \yii\BaseYii { } spl_autoload_register(['Yii','autoload'],true,true);//注册yii的类自动加载器 Yii::$classMap = require(__DIR__ . '/classes.PHP');//引入类名到类文件路径的映射 Yii::$container = new yii\di\Container();

这个文件定义了Yii类继承自\yii\BaseYii,代码的第6行引入了classes.PHP文件,该文件源码:

YII2_PATH . '/base/Action.PHP','yii\base\ActionEvent' => YII2_PATH . '/base/ActionEvent.PHP',....//省略n多元素 'yii\widgets\Pjax' => YII2_PATH . '/widgets/Pjax.PHP','yii\widgets\PjaxAsset' => YII2_PATH . '/widgets/PjaxAsset.PHP','yii\widgets\Spaceless' => YII2_PATH . '/widgets/Spaceless.PHP',];

通过查看其源码可以看到,这个文件返回了一个从类名称到类文件路径的映射数组。这个数组被赋值给Yii::$classMap。代码的第7行调用spl_autoload_register()方法注册一个自动加载器,这个类加载器为Yii::autoload(),这就是yii的类加载器了。同时这里通过把spl_autoload_register()方法第三个参数赋值为true,把yii的类加载器放在了加载器队列的最前面,所以当访问一个未加载的类的时候,yii的类自动加载器会最先被调用

下面我们就来看看yii的类自动加载器Yii::autoload()到底做了些什么,这个方法实际上在yii\BaseYii类中,源码如下:

文件路径 映射中找到 $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?"); } }

这个方法首先会根据需要加载的类的名称Yii::$classMap这个映射数组中查找,若存在则引入对应的类文件,不存在则进行别名解析得到完整文件路径,这里也说明若使用的类不在YII::$classMap中事先定义,则类名必须以有效的根别名打头,否则无法找到对应文件

就这样,在yii中无需在程序中事先加载一大堆可能会使用到的类文件,当使用到某个类的时候,yii的类自动加载器就会自动进行加载了,高效又便捷!

更多关于Yii相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》、《》、《》及《PHP常见数据库操作技巧汇总》

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


服务器优化必备:深入了解PHP8底层开发原理
Golang的网络编程:如何快速构建高性能的网络应用?
Golang和其他编程语言的对比:为什么它的开发效率更高?
PHP8底层开发原理揭秘:如何利用新特性创建出色的Web应用
将字符重新排列以形成回文(如果可能)在C++中
掌握PHP8底层开发原理和新特性:创建高效可扩展的应用程序
服务器性能优化必学:掌握PHP8底层开发原理
PHP8新特性和底层开发原理详解:优化应用性能的终极指南
将 C/C++ 代码转换为汇编语言
深入研究PHP8底层开发原理:创建高效可扩展的应用程序
C++程序查找法向量和迹
PHP8底层开发原理实战指南:提升服务器效能
重排数组,使得当 i 为偶数时,arr[i] >= arr[j],当 i 为奇数时,arr[i] <= arr[j],其中 j < i,使用 C++ 语言实现
Golang的垃圾回收:为什么它可以减少开发人员的负担?
C++程序:将一个数组的所有元素复制到另一个数组中
Golang:构建智能系统的基石
为什么AI开发者应该关注Golang?
在C和C++中,逗号(comma)的用法是用来分隔表达式或语句
PHP8底层开发原理解析及新特性应用实例
利用PHP8底层开发原理解析新特性:如何构建出色的Web应用