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说起了,该文件源码如下:

<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);//运行模式
defined('YII_ENV') or define('YII_ENV', 'dev');//运行环境
require(__DIR__ . '/../../vendor/autoload.php');//composer的类自动加载文件
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');//yii的工具类文件(包含了yii类自动加载)
require(__DIR__ . '/../../common/config/bootstrap.php');//主要用于执行一些yii应用引导的代码
require(__DIR__ . '/../config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
  require(__DIR__ . '/../../common/config/main.php'),
  require(__DIR__ . '/../../common/config/main-local.php'),
  require(__DIR__ . '/../config/main.php'),
  require(__DIR__ . '/../config/main-local.php')
);
(new yii\web\Application($config))->run();

文件中第4、5行代码分别引入了composer的类自动加载文件和yii的工具类文件Yii.php,Yii.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文件,该文件源码:

return [
 'yii\base\Action' => 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类中,源码如下:

/**
 * 类自动加载器
 * @param type $className:要加载的类的名称
 * @return type
 * @throws UnknownClassException
 */
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?");
  }
}

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

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

更多关于Yii相关内容感兴趣的读者可查看本站专题:《Yii框架入门及常用技巧总结》、《php优秀开发框架总结》、《smarty模板入门基础教程》、《php面向对象程序设计入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

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

您可能感兴趣的文章:

  • Yii2中YiiBase自动加载类、引用文件方法分析(autoload)
  • Yii实现自动加载类地图的方法
  • yii2框架中使用下拉菜单的自动搜索yii-widget-select2实例分析
  • Yii2基于Ajax自动获取表单数据的方法
  • YII2自动登录Cookie总是失效的解决方法
  • Yii2框架实现登录、退出及自动登录功能的方法详解
(0)

相关推荐

  • Yii2中YiiBase自动加载类、引用文件方法分析(autoload)

    本文实例分析了Yii2中YiiBase自动加载类.引用文件的方法.分享给大家供大家参考,具体如下: 在Yii2中这个函数是用来加载类的,没有直接引用文件的相关实现.但是这个也可以用来引用文件. public static function autoload($className) { /* * $classMap是一个name-value数组, * name为类的名称, * value为这个类的文件路径,其中路径可包含别名 * * 首先在$classMap中查找是否设置了类别名路径 */ if

  • YII2自动登录Cookie总是失效的解决方法

    前言 最近做Yii2自动登录功能,发现即使开启了Yii2的自动登录配置功能,浏览器关闭后,再次打开浏览器还是处于非登录状态. 网上查询资料基本没有相同情况. 查询登录源码: protected function sendIdentityCookie($identity, $duration) { $cookie = new Cookie($this->identityCookie); $cookie->value = json_encode([ $identity->getId(), $

  • yii2框架中使用下拉菜单的自动搜索yii-widget-select2实例分析

    本文实例讲述了yii2框架中使用下拉菜单的自动搜索yii-widget-select2的方法.分享给大家供大家参考,具体如下: github中源代码地址:https://github.com/kartik-v/yii2-widget-select2 利用composer.phar安装此插件: php composer.phar require kartik-v/yii2-widget-select2 "*" 引用方法: use kartik\select2\Select2; 源代码:

  • Yii实现自动加载类地图的方法

    本文实例讲述了Yii实现自动加载类地图的方法.分享给大家供大家参考.具体如下: Yii继承的一个静态属性$classMap,可以用于Yii的自动加载类地图.数组中的键是类名,数组中的值是相应类文件的路径. require_once($yii); $app = Yii::createWebApplication($config); Yii::$classMap = array( 'JPhpMailer' => Yii::getPathOfAlias('ext') . '/phpmailer/JPh

  • Yii2框架实现登录、退出及自动登录功能的方法详解

    本文实例讲述了Yii2框架实现登录.退出及自动登录功能的方法.分享给大家供大家参考,具体如下: 自动登录的原理很简单.主要就是利用cookie来实现的 在第一次登录的时候,如果登录成功并且选中了下次自动登录,那么就会把用户的认证信息保存到cookie中,cookie的有效期为1年或者几个月. 在下次登录的时候先判断cookie中是否存储了用户的信息,如果有则用cookie中存储的用户信息来登录, 配置User组件 首先在配置文件的components中设置user组件 'user' => [ '

  • Yii2基于Ajax自动获取表单数据的方法

    本文实例讲述了Yii2基于Ajax自动获取表单数据的方法.分享给大家供大家参考,具体如下: 这里有两张表,表结构如下,locations表存放的省份和邮编等信息,两张表的model和curd均使用gii生成 yii2advanced.customers表 customer_id:int(11) customer_name:varchar(100) zip_code:varchar(20) city:varchar(100) province:varchar(100) yii2advanced.l

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

    本文实例讲述了Yii2框架类自动加载机制.分享给大家供大家参考,具体如下: 在yii中,程序中需要使用到的类无需事先加载其类文件,在使用的时候才自动定位类文件位置并加载之,这么高效的运行方式得益于yii的类自动加载机制. Yii的类自动加载实际上使用的是PHP的类自动加载,所以先来看看PHP的类自动加载.在PHP中,当程序中使用的类未加载时,在报错之前会先调用魔术方法__autoload(),所以我们可以重写__autoload()方法,定义当一个类找不到的时候怎么去根据类名称找到对应的文件并加

  • PHP MVC框架中类的自动加载机制实例分析

    本文实例讲述了PHP MVC框架中类的自动加载机制.分享给大家供大家参考,具体如下: 原文 实现类的自动加载主要使用到了set_include_path和spl_autoload_register函数. set_include_path用于提前设置好可能会加载的类的路径. spl_autoload_register用于调用相关自动加载所需类的函数,实现自动载入的功能. 有一点要注意的是:自动加载在实例化类的时候执行,也就是说使用extends继承类的时候,是不会自动加载父类的. 设置目录如下:

  • PHP进阶学习之类的自动加载机制原理分析

    本文实例讲述了PHP类的自动加载机制.分享给大家供大家参考,具体如下: 前言 我们在常见的PHP的主流框架中通常写好一个类只需写好相应的命名空间或直接实例化类就可以实现类的使用.而不需要使用原生的方式把类文件一个个用require.include引入包含进来,这归功于PHP的类自动加载机制,也是本文讨论的要点. 一.概念 在PHP代码中,不需要显式地使用文件路径将类库文件包含进来,便可使用该文件中定义的类库,这种技术称作自动加载. 在使用类或者定义了命名空间的类时,只需要直接实例化使用,PHP机

  • PHP自动加载机制实例详解

    本文实例讲述了PHP自动加载机制.分享给大家供大家参考,具体如下: 在php中,我们一般使用 require, requre_once, include, include_once 这四个命令来加载其他php文件,这在一般小型的php文件中是没有任何问题的,相信每个初学者都会遇到这样的应用场景:使用一个 Db.php 来定义数据库连接,在其他文件中直接引用这个文件,达到代码复用的效果. 再让我们考虑这样一个应用场景,如果我们使用一个框架,或者一个第三方包,里面一般有成百上千个类文件,而我们通常是

  • thinkPHP5.0框架自动加载机制分析

    本文实例讲述了thinkPHP5.0框架自动加载机制.分享给大家供大家参考,具体如下: 概述 ThinkPHP5.0 真正实现了按需加载,所有类库采用自动加载机制,并且支持类库映射和composer类库的自动加载. 自动加载的实现由think\Loader类库完成,自动加载规范符合PHP的PSR-4. 自动加载 由于新版ThinkPHP完全采用了命名空间的特性,因此只需要给类库正确定义所在的命名空间,而命名空间的路径与类库文件的目录一致,那么就可以实现类的自动加载. 类库的自动加载检测顺序如下:

  • PHP类的自动加载机制实现方法分析

    本文实例讲述了PHP类的自动加载机制实现方法.分享给大家供大家参考,具体如下: Test1.class.php <?php class Test1 { public static function test() { echo "hello,world!\n"; } } Test2.class.php <?php class Test2 { public static function test() { echo "你好,世界!\n"; } } test.

  • php类自动加载失败的处理方案及实例代码

    1.打开相应的PHP代码文件. 2.添加"$class = str_replace("\\","/",$class);"代码即可. 文件在本地win系统下测试无异常,代码如下: function stu_autoload($class){ if(file_exists($class.".php")){ require ( $class.".php"); }else{ die("unable to

  • PHP面向对象自动加载机制原理与用法分析

    本文实例讲述了PHP面向对象自动加载机制原理与用法.分享给大家供大家参考,具体如下: 在学习PHP的面向对象的时候,会知道很多"语法糖",也就是魔术方法.有一个加自动加载的魔术方法,叫:__autoload(); 先看一段代码 <?php function __autoload($classname) { $filename = "./". $classname .".php"; include_once($filename); } new

  • PHP命名空间与自动加载机制的基础介绍

    前言 include 和 require 是PHP中引入文件的两个基本方法.在小规模开发中直接使用 include 和 require 没哟什么不妥,但在大型项目中会造成大量的 include 和 require 堆积.这样的代码既不优雅,执行效率也很低,而且维护起来也相当困难. 为了解决这个问题,部分框架会给出一个引入文件的配置清单,在对象初始化的时候把需要的文件引入.但这只是让代码变得更简洁了一些,引入的效果仍然是差强人意.PHP5 之后,随着 PHP 面向对象支持的完善,__autoloa

随机推荐