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

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

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

一、__autoload()

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

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

//Test1.php文件
<?php
class Test1{
static function test(){
echo "test1";
}
}
//Test2.php文件
<?php
class Test2{
static function test(){
echo "test2";
}
}

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

//Test.php文件
<?php
include "Test1.php";
include "Test2.php"; Test1::test();
Test2::test();

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

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

//Test.php文件
<?php
function __autoload($class){
if(file_exists($class.".php")){
require_once($class.".php");
}else{
die("文件不存在!");
}
} Test1::test();
Test2::test();

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

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

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

function __autoload($class){
if(file_exists("classes/".$class.".php")){
require_once("classes/".$class.".php");
}else{
die("文件不存在!");
}
}
function __autoload($class){
if(file_exists("core/".$class.".php")){
require_once("core/".$class.".php");
}else{
die("文件不存在!");
}
} Test1::test();
Test2::test();

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

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

二、spl_autoload_register()

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

function my_autoload1($class){
if(file_exists("classes/".$class.".php")){
require_once("classes/".$class.".php");
}else{
die("文件不存在!");
}
}
function my_autoload2($class){
if(file_exists("core/".$class.".php")){
require_once("core/".$class.".php");
}else{
die("文件不存在!");
}
} //现在我们就可以加载类文件啦
my_autoload1("Test1");
my_autoload2("Test2"); Test1::test();
Test2::test();

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

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

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

spl_autoload_register("my_autoload1");

我们重新实现 Test.php:

//Test.php文件
function my_autoload1($class){
if(file_exists("classes/".$class.".php")){
require_once("classes/".$class.".php");
}else{
die("文件不存在!");
}
}
function my_autoload2($class){
if(file_exists("core/".$class.".php")){
require_once("core/".$class.".php");
}else{
die("文件不存在!");
}
} //将加载函数注册到PHP中
spl_autoload_register("my_autoload1");
spl_autoload_register("my_autoload2"); Test1::test();
Test2::test();

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

__autolaod的更多相关文章

  1. 现代php编程

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

随机推荐

  1. 删除gitlab 上的文件

  2. Single Number II leetcode java

    问题描述: Given an array of integers, every element appears three times except for one. Find that single ...

  3. python记录_day23 正则表达式 re模块

    一. 正则表达式 使用python的re模块之前应该对正则表达式有一定的了解 正则表达式是对字符串操作的一种逻辑公式.我们一般使用正则表达式对字符串进行匹配和过滤. 正则的优缺点: 优点:灵活, 功能 ...

  4. python-flask-wtforms组件流程源码

    在最开始要弄明白一点,类都是由元类创建的.在定义类 class Foo:pass的时候(类也是对象),就会执行type类或者type派生类的__init__方法,当Foo()时:执行type类或者ty ...

  5. .net 基础

    之前给大家总结了java的面试几次技巧总结,同学们看了觉得还是不错,能够得到大家的认可,感觉还是挺不错的.现在又有同学来想小编索要.NET面试的总结了,好吧.谁让小编这么好呢!以下是.NET面试之框架 ...

  6. Leetcode 863. 二叉树中所有距离为 K 的结点

    863. 二叉树中所有距离为 K 的结点  显示英文描述 我的提交返回竞赛   用户通过次数39 用户尝试次数59 通过次数39 提交次数174 题目难度Medium 给定一个二叉树(具有根结点 ro ...

  7. 解决 TCP_socket 粘包问题

    所谓粘包问题主要还是C/S两端数据传输时 因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的 根本原因:粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多 ...

  8. C++手机通讯录排序

    参考:https://www.cnblogs.com/lhwblog/p/6486036.html Qt 4.8.4 vs2008 #include <QtGui/QApplication> ...

  9. 【CSV文件】CSV文件内容读取

    CSV(逗号分隔值文件格式) 逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本).纯文本 ...

  10. java this的用法

    this 含义:代表当前对象 用法: 用于返回对象的引用 示例代码 public class Test { public Test f() { return this;//获取当前对象的引用 } pu ...