• 售前

  • 售后

热门帖子
入门百科

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

[复制链接]
丁侦球 显示全部楼层 发表于 2021-10-25 20:01:52 |阅读模式 打印 上一主题 下一主题
本文实例讲述了Yii2框架类主动加载机制。分享给各人供各人参考,详细如下:
在yii中,程序中需要使用到的类无需事先加载其类文件,在使用的时候才主动定位类文件位置并加载之,这么高效的运行方式得益于yii的类主动加载机制。
Yii的类主动加载现实上使用的是PHP的类主动加载,以是先来看看PHP的类主动加载。在PHP中,当程序中使用的类未加载时,在报错之前会先调用把戏方法
  1. __autoload()
复制代码
,以是我们可以重写__autoload()方法,界说当一个类找不到的时候怎么去根据类名称找到对应的文件并加载它。此中__autoload()方法被称为类主动加载器。当我们需要多个类主动加载器的时候,我们可以使用
  1. spl_autoload_register()
复制代码
方法代替__autoload()来注册多个类主动加载器,如许就相当于有多个__autoload()方法。spl_autoload_register()方法会把所有注册的类主动加载器存入一个队列中,你可以通过设置它的第三个参数为true来指定某个加载器放到队列的最前面以确保它最先被调用。Yii的类主动加载机制就是基于spl_autoload_register()方法的。
Yii的类主动加载机制要从它的入口文件index.php说起了,该文件源码如下:
  1. <?php
  2. defined('YII_DEBUG') or define('YII_DEBUG', true);//运行模式
  3. defined('YII_ENV') or define('YII_ENV', 'dev');//运行环境
  4. require(__DIR__ . '/../../vendor/autoload.php');//composer的类自动加载文件
  5. require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');//yii的工具类文件(包含了yii类自动加载)
  6. require(__DIR__ . '/../../common/config/bootstrap.php');//主要用于执行一些yii应用引导的代码
  7. require(__DIR__ . '/../config/bootstrap.php');
  8. $config = yii\helpers\ArrayHelper::merge(
  9.   require(__DIR__ . '/../../common/config/main.php'),
  10.   require(__DIR__ . '/../../common/config/main-local.php'),
  11.   require(__DIR__ . '/../config/main.php'),
  12.   require(__DIR__ . '/../config/main-local.php')
  13. );
  14. (new yii\web\Application($config))->run();
复制代码
文件中第4、5行代码分别引入了composer的类主动加载文件和yii的工具类文件Yii.php,Yii.php文件源码如下:
  1. require(__DIR__ . '/BaseYii.php');
  2. class Yii extends \yii\BaseYii
  3. {
  4. }
  5. spl_autoload_register(['Yii', 'autoload'], true, true);//注册yii的类自动加载器
  6. Yii::$classMap = require(__DIR__ . '/classes.php');//引入类名到类文件路径的映射
  7. Yii::$container = new yii\di\Container();
复制代码
这个文件界说了Yii类继承自\yii\BaseYii,代码的第6行引入了classes.php文件,该文件源码:
  1. return [
  2. 'yii\base\Action' => YII2_PATH . '/base/Action.php',
  3. 'yii\base\ActionEvent' => YII2_PATH . '/base/ActionEvent.php',
  4.   ....//省略n多元素
  5. 'yii\widgets\Pjax' => YII2_PATH . '/widgets/Pjax.php',
  6. 'yii\widgets\PjaxAsset' => YII2_PATH . '/widgets/PjaxAsset.php',
  7. 'yii\widgets\Spaceless' => YII2_PATH . '/widgets/Spaceless.php',
  8. ];
复制代码
通过查看其源码可以看到,这个文件返回了一个从类名称到类文件路径的映射数组。这个数组被赋值给Yii::$classMap。代码的第7行调用了
  1. spl_autoload_register()
复制代码
方法注册了一个类主动加载器,这个类加载器为
  1. Yii::autoload()
复制代码
,这就是yii的类加载器了。同时这里通过把
  1. spl_autoload_register()
复制代码
方法第三个参数赋值为true,把yii的类加载器放在了加载器队列的最前面,以是当访问一个未加载的类的时候,yii的类主动加载器会最先被调用。
下面我们就来看看yii的类主动加载器Yii::autoload()到底做了些什么,这个方法现实上在yii\BaseYii类中,源码如下:
  1. /**
  2. * 类自动加载器
  3. * @param type $className:要加载的类的名称
  4. * @return type
  5. * @throws UnknownClassException
  6. */
  7. public static function autoload($className)
  8. {
  9.   if (isset(static::$classMap[$className])) {//要加载的类在 类名=>类文件路径 映射中找到
  10.     $classFile = static::$classMap[$className];
  11.     if ($classFile[0] === '@') {//若类文件路径使用了别名,进行别名解析获得完整路径
  12.       $classFile = static::getAlias($classFile);
  13.     }
  14.   } elseif (strpos($className, '\\') !== false) {//类名需要包含'\'才符合规范
  15.     $classFile = static::getAlias('@' . str_replace('\\', '/', $className) . '.php', false);//进行别名解析(说明类名必须以有效的根别名打头)
  16.     if ($classFile === false || !is_file($classFile)) {
  17.       return;
  18.     }
  19.   } else {
  20.     return;
  21.   }
  22.   include($classFile);//引入需要加载的类文件
  23.   if (YII_DEBUG && !class_exists($className, false) && !interface_exists($className, false) && !trait_exists($className, false)) {
  24.     throw new UnknownClassException("Unable to find '$className' in file: $classFile. Namespace missing?");
  25.   }
  26. }
复制代码
这个方法起首会根据需要加载的类的名称去
  1. Yii::$classMap
复制代码
这个映射数组中查找,若存在则引入对应的类文件,不存在则举行别名剖析得到完整文件路径,这里也阐明若使用的类不在YII::$classMap中事先界说,则类名必须以有效的根别名打头,否则无法找到对应文件。
就如许,在yii中无需在程序中事先加载一大堆大概会使用到的类文件,当使用到某个类的时候,yii的类主动加载器就会主动举行加载了,高效又便捷!
更多关于Yii相关内容感兴趣的读者可查看本站专题:《Yii框架入门及常用本领总结》、《php优秀开辟框架总结》、《smarty模板入门基础教程》、《php面向对象程序计划入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操纵入门教程》及《php常见数据库操纵本领汇总》
希望本文所述对各人基于Yii框架的PHP程序计划有所帮助。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作