转载自:https://blog.csdn.net/baidu_30000217/article/details/52743139

php实现类文件自动载入有两种办法:

  1. 魔术方法:__autoload();
  2. SPL标准库提供的spl_autoload_register();

一、__autoload()

__autoload()是php中的一个魔术方法,在代码中当调用不存在的类时会自动调用该方法。

假如现在有以下两个类文件:

  1. //Test1.php文件
  2. <?php
  3. class Test1{
  4. static function test(){
  5. echo "test1";
  6. }
  7. }
  8. //Test2.php文件
  9. <?php
  10. class Test2{
  11. static function test(){
  12. echo "test2";
  13. }
  14. }

现在Test.php文件中要用到 Test1.php 和 Test2.php 中的类:

  1. //Test.php文件
  2. <?php
  3. include "Test1.php";
  4. include "Test2.php";
  5. Test1::test();
  6. Test2::test();

用 include 或require 的问题是当我要调用的类很多的时候,include 或 require也会很多,造成代码的冗杂,而且每次执行到 Test.php 文件的时候都要加载这么多文件,有些文件还不一定用到,那就浪费了很多内存,降低效率。再者是当你某个类文件被删掉了,你还得去修改 Test.php 文件。

由于这些原因,我们用 __autoload() 去代替 include

  1. //Test.php文件
  2. <?php
  3. function __autoload($class){
  4. if(file_exists($class.".php")){
  5. require_once($class.".php");
  6. }else{
  7. die("文件不存在!");
  8. }
  9. }
  10. Test1::test();
  11. Test2::test();

__autoload() 魔术方法的作用是当你调用不存在的类时会被自动调用,在 Test.php文件中我们调用 类Test1 和 类Test2,由于我们没有显式的引用类文件,那么系统就会自动调用 __autoload() 方法。

但是,到现在为止 __autoload() 方法基本上被废弃了!为啥呢?因为:

1、最大的缺陷就是一个文件中不允许有多个 __autoload()方法,想象一下,你的项目引用了别人的一个项目,你的项目中有一个 __autoload,别人的项目也有一个__autoload,这样两个__autoload就冲突了。解决的办法就是修改__autoload成为一个,这无疑是非常繁琐的。
2、假如你的项目中的类根据不同的用处放在不同的文件夹中 classes 和 core,然后Test.php文件中要分别调用里面对应的类,怎么搞?这样?

  1. function __autoload($class){
  2. if(file_exists("classes/".$class.".php")){
  3. require_once("classes/".$class.".php");
  4. }else{
  5. die("文件不存在!");
  6. }
  7. }
  8. function __autoload($class){
  9. if(file_exists("core/".$class.".php")){
  10. require_once("core/".$class.".php");
  11. }else{
  12. die("文件不存在!");
  13. }
  14. }
  15. Test1::test();
  16. Test2::test();

这样做的话会出现致命错误,因为 __autoload()重复定义!(其实第1点的原因也是一样)

为了解决这个问题,于是就有 spl_autoload_register()

二、spl_autoload_register()

好,到了这一步,我们先不说 spl_autoload_register(),既然不用__autoload(),那么我们就自己定义负责类加载的函数:

  1. function my_autoload1($class){
  2. if(file_exists("classes/".$class.".php")){
  3. require_once("classes/".$class.".php");
  4. }else{
  5. die("文件不存在!");
  6. }
  7. }
  8. function my_autoload2($class){
  9. if(file_exists("core/".$class.".php")){
  10. require_once("core/".$class.".php");
  11. }else{
  12. die("文件不存在!");
  13. }
  14. }
  15. //现在我们就可以加载类文件啦
  16. my_autoload1("Test1");
  17. my_autoload2("Test2");
  18. Test1::test();
  19. Test2::test();

但是如上代码所示,直接调用我们的自定义类文件加载函数跟 include 有啥区别吗?这时 spl_autoload_register 就派上用场了。

显然,创造一个负责类文件加载函数不是为了让我们直接调用它,而是让PHP在需要类定义的时候为我们调用它。我们称这种功能为“自动加载”。

要开启“自动加载”功能,需要将加载函数注册到PHP中:

  1. spl_autoload_register("my_autoload1");

我们重新实现 Test.php:

  1. //Test.php文件
  2. function my_autoload1($class){
  3. if(file_exists("classes/".$class.".php")){
  4. require_once("classes/".$class.".php");
  5. }else{
  6. die("文件不存在!");
  7. }
  8. }
  9. function my_autoload2($class){
  10. if(file_exists("core/".$class.".php")){
  11. require_once("core/".$class.".php");
  12. }else{
  13. die("文件不存在!");
  14. }
  15. }
  16. //将加载函数注册到PHP中
  17. spl_autoload_register("my_autoload1");
  18. spl_autoload_register("my_autoload2");
  19. Test1::test();
  20. Test2::test();

这样就是实现了PHP的类文件自动载入功能。

__autolaod的更多相关文章

  1. 现代php编程

    自动加载__autolaod和spl_autoload_register() 自动加载就是指如果找不到某个类如何处理的方式,具体可参见此文,可以说spl_autoload_register是更加高级, ...

随机推荐

  1. 最长回文字串——manacher算法

    时间复杂度:O(n) 参考:https://segmentfault.com/a/1190000003914228 1.问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字 ...

  2. MVC实战之排球计分(三)—— 模型类的设计与实现

    此软件使用的数据库连接方式code first 由EF框架产生数据库. code first需要对模型类设计和实现.模型类是现实实体在计算机中的表示.它贯穿于整个架构, 负担着在各层次及模块间传递数据 ...

  3. Matlab-5:牛顿迭代法工具箱

    function [f,L]=Newton(f,a) %this is newton teration whic is used for solving implicit One-dimensiona ...

  4. CRM 价格批导2<上一个太多冗余>

    INCLUDE:LCRM_MKTPL_COND_IFF39 *--------------------------------------------------------------------- ...

  5. 26. Remove Duplicates from Sorted Array C++ 删除排序数组中的重复项

    https://leetcode.com/problems/remove-duplicates-from-sorted-array/ 双指针,注意初始时左右指针指向首元素! class Solutio ...

  6. 关闭provider进程或者consumer进程后,会发生什么?

    下图是 provider,consumer 和注册中心之间的拓扑图: provider,consumer 以及管理控制台都是 zookeeper 的客户端,所以都和 zk 建立了tcp连接. 以接口 ...

  7. git报错fatal: I don't handle protocol '​https'处理

    一.背景说明 今天使用在Cygwin中git clone时报fatal: I don't handle protocol '​https',如下: 以为是Cygwin实现的git有点问题没太在意,换去 ...

  8. [转]关于ReentrantLock中线程读某个变量是否需要加锁

    我在使用ReentrantLock类对变量进行多线程累加时,调用了lock()和unlock()方法,但读取该变量时我未加锁,结果是能正确执行,代码如下: public class Main { pr ...

  9. python 数字格式化

    第二种办法比较常用:   %02d print '%02d' % 11

  10. asp企业网站源码部分

    ASP的网页文件的格式是.asp,现在常用于各种动态网站中.PHP是一种 HTML 内嵌式的语言,PHP与微软的ASP颇有几分相似,都是一种在服务器端执行的嵌入HTML文档的脚本语言,语言的风格有类似 ...