0

0

PHP中类自动加载的方式

不言

不言

发布时间:2018-05-02 15:20:59

|

1564人浏览过

|

来源于php中文网

原创

这篇文章主要介绍了关于PHP中类自动加载的方式,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

  最近在学习composer,发现从接触PHP到现在已经遇到了三种关于PHP中类的自动加载方式,这其中包括PHP自带的类的自动加载方式、PHP的第三方的依赖管理工具composer的加载方式以及PHP的Yaf框架下的自动加载方式。本篇博客主要是针对PHP5自带的加载方式进行详细介绍,composer和Yaf下类的自动加载将在接下来的时间里分两篇和大家一起学习。

      1.手动加载方式

  像C和C++等语言,在PHP中需要使用另一个文件中的相关的类、方法时,可以使用include、include_once、require或者require_once将所用的文件包含进工程里面。其中,四者的区别如下。

  • include将套用一个文件,如果文件不存在,则给出一个提示,跳过继续执行;

  • include_once也是套用一个文件,但是只会套用一次,如果文件不存在,则继续执行;

  • require表示套用一个文件,如果文件不存在,则中断程序的执行;

  • require_once也是套用一个文件,且只会套用一次,如果文件不存在,则中断程序的执行;

  以上四种方式是需要什么文件的时候,手动在程序当中包含进文件。这在项目的规模比较小的时候,是可以的;但是随着项目规模的扩大,要通过手动的方式加载每个文件所需要的类简直是一场噩梦。

  为了省事,在加载的时候可以通过set_include_path()设置加载的路径,同样也可以通过get_include_path()获取加载的路径。关于set_include_path()和get_include_path(),我也是刚刚接触,这里只对set_include_path()作简要的介绍,以后遇到问题再加以补充。

  首先,set_include_path()是在脚本中动态的对php.ini中的include_path进行动态的修改,而这个include_path就是对include和require(下文中如果不进行特别的说明,include代表include和include_once,require代表着require和require_once)的路径进行设置,或者说是预定义。假如,我们在一个main.php文件中需要使用projname/home/lib/mylib/test文件夹下的a.php、b.php、c.php......,如果没有设置包含的路径的话,那么写成如下的形式:

< ? php

        include("projname/home/lib/mylib/test/a.php");
        include("projname/home/lib/mylib/test/b.php");
        include("projname/home/lib/mylib/test/c.php");
	  ......

  这样,每个include都需要包含绝对路径,显得很麻烦。如果在需要被包含的文件之前加上set_include_path(“projname/home/lib/mylib/test”),那么就可以写成如下所示的形式:

< ? php

    set_include_path("projname/home/lib/mylib/test");
    include("a.php");
    include("b.php");
    include("c.php");
    ......

  相比于第一种费时费力的写法,第二种明显省去了很多的时间,但是仍然是要将每个文件包含进来,只是简化了包含的路径而已。当然,上面所说的情况是所需要的文件都存在于一个文件夹中,如果文件存在于不同的文件夹中,那么可以添加多条的set_include_path()语句,此时如果include或者require中的文件包含的文件名在多个目录下出现,那么只会包含最先出现在set_include_path目录中的文件;如果所有的set_include_path指定的文件夹中都没有对应的文件,而文件名恰好出现在当前的文件夹中,则直接包含当前目录下的对应的文件。

  get_include_path()函数只适用于获取当前的包含路径。 

  2._autoload和spl_autoload_register()自动加载方式

  为了将双手从类的加载方式中解放出来,在PHP5及以后的版本中提供了一个自动加载的机制---autoload。Autoload可以使类在确实被需要的情况下才会被加载进来,也就是所谓的lazy loading,而不是一开始就include或者require所有的类文件。其中PHP提供的自动加载机制又分为两种---__autoload()以及spl_autoload_register()。

  1). __autoload机制

  在PHP5中运行程序的过程中,如果发现某一个类并没有被包含进来,那么就会运行__autoload自动加载机制,将所需要的类加载进来。其写法如下:

< ? php

	public function  __autoload($classname) {
		$fileName = $classname."php";
		if (file_exist($fileName)) {
			require_once("$fileName");
		} else {
			echo $fileName." doesn't exist!"
		}
	}

  根据这个程序写法,我们可以得到如下的结论:保证自动加载机制的的原则就是要使得类名和文件名具有一种对应关系,类名+后缀构成了这个类所在的文件的名字。如果这个文件确实存在,那么就根据$fileName将该类加载进来。如果文件不存在,则提示用户,文件不存在。总的来说自动加载机制包括三个步骤:

  • 根据类名确定文件名,也就是确定一种类名和文件名之间的统一对应规则;

    立即学习PHP免费学习笔记(深入)”;

  • 根据文件名在磁盘上找到相应的对应文件(例子中是最简单的情况,就是类与调用他们的PHP文件都在同一个目录下);如果不在同一个目录下,那么可以使用set_include_path()指定要加载的路径;

  • 将磁盘文件加载到文件系统中,这一步只是用一般的include和require包含相应的类文件;

    新秀B2C商城系统
    新秀B2C商城系统

    新秀B2C商城系统是一款简洁易用PHP商城系统。可免费下载使用,可用于商业用途,没有时效限制,除版权标识外,所有代码都允许修改。后台功能简介:1、商城设置:基本信息,配送方式,配送范围,支付方式,财务管理;2、商品管理:商品列表,添加商品,商品分类,商品品牌,商品属性;3、订单管理:订单列表,缺货登记;4、用户互动:用户管理,留言管理,评论管理,网站公告,在线客服,用户协议;5、文章管理:文章列表

    下载

  __autoload()实现类的自动加载的原则就是:类名和文件名之间具有一种统一的对应关系,这是在一个系统中实现__autoload的关键所在。但是一个系统可能是有不同的人员所开发,如果在开发之前没有约定统一的标准,则可能存在不同的对应规则,导致需要在__autoload()中实现多种加载规则,那么可能导致__autoload()函数非常的臃肿。为了解决这个这个问题,PHP还提供了一个自动加载机制---spl_autoload_register().

  2). spl_autoload_register()机制

  SPL是Standard PHP Library(标准PHP库)的缩写,是PHP5引入的一个扩展库。SPL autoload是通过将函数指针autoload_func指向自动装载函数实现的。SPL具有两个不同的自动装载函数,分别是spl_autoload和spl_autoload_call,通过将autoload_fun指向这两个不同的加载函数地址可以实现不同的自动加载机制。

  • spl_autoload

  spl_autoload是SPL实现的默认的自动加载函数,是一个可以接受两个参数的函数。其中第一个函数为$class_name,表示要加载的类名;第二个参数是$file_extension为可选参数,表示类文件的扩展名。$file_extension中可以指定多个扩展名,扩展名之间用分号隔开即可,不指定扩展名,则使用默认的扩展名.inc或者.php。spl_autoload首先将$class_name变为小写,然后在所有的include_path中搜索$ class_name.inc或者$class_name.php文件。如果找到对应的文件,就加载对应的类。其实可以手动的使用spl_autoload("xxxx",".php")来实现xxxx类的加载。这其实和require/include差不多,但是,spl_autoload相对来说灵活一点,因为可以指定多个扩展名。

  前面说到,spl_autoload_register中包含的函数指针autoload_func用于指定要使用的加载函数。那么,我们必须将对应的函数地址赋值给autoload_func,spl_autoload_register()正实现了给函数指针autoload_func赋值的功能。如果spl_autoload_register()函数中不含有任何的参数,则默认是将spl_autoload()赋值给autoload_func.

  • spl_autoload_call 

  SPL模块的内部其实还存在着一个autoload_functions,其本质上是一个哈希表,或者为了直观的理解,我们将其想像成一个容器,里面的各个元素都是指向加载函数的指针。spl_autoload_call的实现机制其实也比较简单,按照一定的顺序遍历这个容器,执行里面的函数指针指向的加载函数,每执行一个指针之后都会检查所需要的类是否已经完成加载。如果完成了加载,则退出。否则继续接着向下执行。如果执行完所有的加载函数之后,所需要的类仍然没有完成加载,则spl_autoload_call()直接退出。这也就是说即使使用了autoload机制,也不一定能够完成类的加载,其关键在于看你如何创建你的自动加载函数。

  既然,存在一个autoload_functions,那么如何将创建的自动加载函数添加到其中呢?spl_autoload一样,同样使用spl_autoload_register()将加载函数注册到autoload_functions中。当然可以通过spl_autoload_unregister()函数将已经注册的函数从autoload_functions从哈希表中删除。

  这里需要说明的一点是spl_autoload_register实现自动加载的顺序。spl_autoload的自动加载顺序为:首先判断autoload_func是否为空,如果autoload_func为空,则查看是否定义了__autoload函数,如果没有定义,则返回,并报错;如果定义了__autoload()函数,则返回加载的结果。如果autoload_func不为空,直接执行autoload_func指针指向的函数,不会检查__autoload是否定义。也就是说优先使用spl_autoload_register()注册过的函数。

  根据以上介绍,如果autoload_func为非空是就不能自动执行__autoload()函数了。如果想在使用spl_autoload_register()函数的情况下,依然可以使用__autoload()函数,则可以将__autoload函数通过spl_autoload_register()添加到哈希表中,即,spl_autoload_register(__autoload())。下面的代码示例分别说明了如何注册普通的方法和类的静态公有方法。

  普通函数的注册方法。

  类中静态的加载函数的注册方法。

相关推荐:

PHP中类静态调用和范围解析操作符的区别

PHP中类自动加载实例解析

PHP中类的操作

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

57

2026.01.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

57

2026.01.23

yy漫画官方登录入口地址合集
yy漫画官方登录入口地址合集

本专题整合了yy漫画入口相关合集,阅读专题下面的文章了解更多详细内容。

237

2026.01.23

漫蛙最新入口地址汇总2026
漫蛙最新入口地址汇总2026

本专题整合了漫蛙最新入口地址大全,阅读专题下面的文章了解更多详细内容。

393

2026.01.23

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

17

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

103

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

73

2026.01.22

php会话教程合集
php会话教程合集

本专题整合了php会话教程相关合集,阅读专题下面的文章了解更多详细内容。

81

2026.01.22

宝塔PHP8.4相关教程汇总
宝塔PHP8.4相关教程汇总

本专题整合了宝塔PHP8.4相关教程,阅读专题下面的文章了解更多详细内容。

70

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 9.4万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号