1

Yii框架号称最高效的PHP框架,执行效率高出其他框架很多。据官方介绍,Yii框架广泛的使用了一种叫做延迟加载的技术,从而达到这样的效果。

下面我们就通过实例详细的来介绍一下这个技术

类的延迟加载

首先我们在www目录新建2个类Class1Class2和一个index.php文件。

Class1Class2中我们只简单的写一个简单结构

Class1.php

class Class1{

    public function __construct(){
        echo 'class1';
    }
    
}

Class2.php

class Class2{

    public function __construct(){
        echo 'class2';
    }

}

接下来我们在index.php文件中引入这两个类

require_once('Class1.php');
require_once('Class2.php');

同时我们再定义一个变量$state,将其值设置为1。我们再对$state做一些判断操作。

$state = 1;

if($state == 1)
{
    echo 'state 等于 1';
    $class1 = new Class1();
}
else
{
    echo 'state 不等于 1';
    $class2 = new Class2();
}

我们判断$state值,如果为1,则输出一句话和实例化Class1。否则,同样输出一句话,和实例化Class2

代码正常运行。但是我们发现,我们在if中实例化Class1Class2。不管何时,都只能实例化其中的一个,而我们在引入文件的时候,却是一次性的将两个类都引入进来了。这样不可避免的造成了一些资源的浪费。

所以,我们可以先进行一些小的优化。

比如:我们在if判断中,需要实例化类的时候,再去加载相应的文件。代码如下:

$state = 1;

if($state == 1)
{
    echo 'state 等于 1';
    require_once('Class1.php');
    $class1 = new Class1();
}
else
{
    echo 'state 不等于 1';
    require_once('Class2.php');
    $class2 = new Class2();
}

优化过后的index.php文件效率肯定得到了提升,这个也就是类的延迟加载雏形。但是这样就会出现一个问题,在需要加载的文件很多时候,并不是太方便。通用性不是很强。

在Yii中,这个问题被很好的解决。

其核心武器就是spl_autoload_register()函数,该函数可以自动执行函数。
其括号中参数为需要执行的函数的函数名。比如我们定义一个函数,叫fun_loader().然后将fun_loader作为spl_autoload_register()的参数,那么在程序运行时候,就会自动的执行fun_loader函数。

我们先在index.php函数顶部加入代码

function fun_loader($value)
{
    echo '123';
}

spl_autoload_register('fun_loader');

这样程序在运行时候就会自动调用函数fun_loader,并且输出123

有了自动调用函数功能,我们就可以把刚刚的需要加载的两个类放入这个函数,达到自动加载的效果。

function fun_loader($value)
{
    require_once('Class1.php');
    require_once('Class2.php');
}

但是这样还是回归到了之前的情况,多加载了一个无用的类。

所以,fun_loader的参数起作用了,我们可以动态的将需要加载的类传递进来,实现按需加载。

我们将改造后的index.php完整的写出来,如下:

function fun_loader($value)
{
    require_once($value.'.php');
}

spl_autoload_register('fun_loader');

$state = 1;

if($state == 1)
{
    echo 'state 等于 1';
    $class1 = new Class1();
}
else
{
    echo 'state 不等于 1';
    $class2 = new Class2();
}

这样,当实例化的时候,如果发现没有找到相应的类。那么就会执行一下fun_loader函数。同时,将实例化的类名作为参数,传递给fun_loader

这样就可以实现需要时候加载需要的类。这就是Yii的延迟加载了。

Yii具体的代码在文件vendor\yiisoft\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();

星空幻颖
2.7k 声望279 粉丝