php自动加载机制简书,PHP自动加载

文章总结了PHP的自动加载机制,包含魔法函数 __autoload()和spl autoload函数。

缘起

PHP开发过程中,需要通过include、include_once、require或require_once引入定义的类,如图:

require_once('./ClassA.php');

require_once('./ClassB.php');

require_once('./ClassC.php');

...

当需要引入的类比较少的时候,没有什么大问题,但是当需要引入的类非常多时,就会出现大量的include或require语句,这样会导致遗漏或者包含不必要的类文件。因此,类的自动加载(autoload)机制应运而生。

autoload机制主要用来自动加载类,该机制使PHP程序有可能在使用类时才自动引入类文件,而不是一开始就将所有的类文件引入。

自动加载函数__autoload()

PHP程序中,当我们要使用的类未导入时,会自动调用__autoload()函数,此函数是我们在程序中自定义的,通过这个函数可以加载需要引入的类。

为了更好的说明__autoload()函数,下面举个例子进行说明,以下是项目的目录:

+ first

+-- ClassA.php

+ second

+-- ClassB.php

- autoload.php

- index.php

首先我们来看ClassA.php:

//test/first/ClassA.php

class ClassA

{

public function fun()

{

echo "ClassA is running...\n";

}

}

ClassB和ClassA类似,只有一个简单的函数fun():

//test/second/ClassB.php

class ClassB

{

public function fun()

{

echo "ClassB is running...\n";

}

}

require、include函数

如果采用原始的require或者include方法,需要分别引入ClassA、ClassB文件,程序正常打印结果。

//test/index.php

require_once __DIR__.'./first/ClassA.php';

require_once __DIR__.'./second/ClassB.php';

$classA = new ClassA();

$classB = new ClassB();

$classA->fun();

$classB->fun();

__autoload()函数

为了使用__autoload()函数,我们需要单独新建一个文件,这里我们新建了一个autoload.php文件,然后在index.php文件里调用include或require引入该文件,此时当有未引入的类时,程序会自动调用__autoload()函数,并将类名作为参数传入。

__autoload()函数,首先需要确定类名对应的文件名,然后通过调用is_readable()函数判断该文件是否可读,如果可读则调用require_once引入相应的类文件。

//test/autoload.php

function __autoload($className)

{

if($className == 'ClassA'){

$classpath = __DIR__.'\\first\\'.$className.'.php';

}else{

$classpath = __DIR__.'\\second\\'.$className.'.php';

}

if (is_readable($classpath)) {

require_once($classpath);

}

}

此时,需要修改index.php文件,该文件删掉了ClassA和ClassB的引入,同时引入了autoload.php文件。这里只需要一行即可引入所需的类,当所需的类达到数百个时,__autoload()函数的优势就会彰显无疑。另外,__autoload()函数只有在需要相应的类时才会主动引入,假设这里不需要ClassB类,那么程序不会引入。如果是采用require或include函数时,必须在程序的开始交代清楚,否则会报错。

//test/index.php

require_once __DIR__.'./autoload.php';

$classA = new ClassA();

$classB = new ClassB();

$classA->fun();

$classB->fun();

但是,autoload()函数存在一个严重的缺点:__autoload() 是全局函数且只能定义一次,不够灵活。另外,所有类名和文件名的对应关系都在__autoload()函数中实现,这会导致该函数非常臃肿。

spl autoload

SPL是Standard PHP Library(标准PHP库)的缩写。它是PHP引入的一个扩展库,其主要功能包括autoload机制的实现及包括各种Iterator接口或类。其有以下几个函数:

spl_autoload_register:注册 _autoload() 函数

spl_autoload_unregister:注销已注册的_autoload()函数

spl_autoload_functions:返回所有已注册的_autoload()函数

spl_autoload_call:尝试所有已注册的_autoload()函数来加载类

spl_autoload :_autoload()函数的默认实现

spl_autoload_extionsions: 注册并返回 spl_autoload 函数使用的默认文件扩展名。

spl_autoload_register()函数实现了一个autoload调用堆栈,我们可以向这个堆栈注册多个__autoload()函数,当PHP找不到类名时,就会调用autoload堆栈,一个一个地去调用自定义的__autoload()函数,实现自动加载功能。

举例说明spl_autoload_register()函数的用法,以下是项目目录

+ first

+-- ClassA.php

+ second

+-- ClassB.php

- autoloadA.php

- autoloadB.php

- index.php

项目增加了autoloadA.php、autoloadB.php文件,并且修改了index.php文件。autoloadA.php文件用于加载first文件夹下的类,autoloadB.php用于加载second文件夹下的类。通过调用spl_autoload_register()函数可以注册多个__autoload()函数。

//test/autoloadA.php

function __autoloadA($className)

{

$classpath = __DIR__.'\\first\\'.$className.'.php';

if (is_readable($classpath)) {

require_once($classpath);

}

}

spl_autoload_register('__autoloadA');

//test/autoloadB.php

function __autoloadB($className)

{

$classpath = __DIR__.'\\second\\'.$className.'.php';

if (is_readable($classpath)) {

require_once($classpath);

}

}

spl_autoload_register('__autoloadB');

文件index.php修改如下,此时即可以实现注册多个__autoload()函数。此时会发现,与最开始使用require或include引入文件一样需要两行才能实现所有类的引入,貌似并没有更简单。但是假设first、second文件夹下各有100个类需要引入,则使用require或include函数引入需要200行,而使用spl_autoload_register()函数引入根本不需要改变代码。

//test/index.php

require_once __DIR__ . './autoloadA.php';

require_once __DIR__ . './autoloadB.php';

$classA = new ClassA();

$classB = new ClassB();

$classA->fun();

$classB->fun();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值