PHP自动加载

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

缘起

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

当需要引入的类比较少的时候,没有什么大问题,但是当需要引入的类非常多时,就会出现大量的include或require语句,这样会导致遗漏或者包含不必要的类文件。因此,类的自动加载(autoload)机制应运而生。
autoload机制主要用来自动加载类,该机制使PHP程序有可能在使用类时才自动引入类文件,而不是一开始就将所有的类文件引入。

自动加载函数__autoload()

PHP程序中,当我们要使用的类未导入时,会自动调用__autoload()函数,此函数是我们在程序中自定义的,通过这个函数可以加载需要引入的类。
为了更好的说明__autoload()函数,下面举个例子进行说明,以下是项目的目录:

+ first
+--   ClassA.php
+ second
+--   ClassB.php
-  autoload.php
-  index.php

首先我们来看ClassA.php:

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

require、include函数

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

fun();
$classB->fun();

__autoload()函数

为了使用__autoload()函数,我们需要单独新建一个文件,这里我们新建了一个autoload.php文件,然后在index.php文件里调用include或require引入该文件,此时当有未引入的类时,程序会自动调用__autoload()函数,并将类名作为参数传入。
__autoload()函数,首先需要确定类名对应的文件名,然后通过调用is_readable()函数判断该文件是否可读,如果可读则调用require_once引入相应的类文件。

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

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()函数。

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

fun();
$classB->fun();

你可能感兴趣的:(PHP自动加载)