深入学习Composer原理(二)

本系列的第二篇文章,这次我们聊聊:spl_autoload_register()函数

PHP的SPL库作为扩展库,已经于5.3.0版本后默认保持开启,成为PHP的一组强大的核心扩展库。大家有时间可以多研究研究SPL里面的方法功能。而且,SPL中包含很多类库哟,在设计模式的系列文章中,我们也会再次见到他们的身影!

这回我们建立一个文件,叫做spl_autoload_register.php,然后将下面的代码复制进去吧:


<?php

spl_autoload_register(function( $className ){
require $className . '.php';
});

$m = new TestClass();
$m->show();

是不是和__autoload()很像,当然作用也很像。我们直接运行这个文件试试,会发现TestClass.php也正常的加载了进来。那么为啥不直接用__autoload()函数,而使用sql_autoload_register()这么诡异的函数,而且还有个神奇的闭包参数!!!

我们先看看它的定义和格式

PHP官方文档中的定义

注册给定的函数作为 __autoload 的实现

没错,那个匿名函数就是一个__autoload()函数,我们可以理解为给当前这个PHP文件中注册一个__autoload()函数,而使用匿名函数的原因呢?当然就是为了闭包特性,最主要的就是能够带来延迟加载(懒加载 )的实现!

另外,spl_autoload_register()函数不止是仅仅去注册一个__autoload(),它实现并维护了一个__autoload()队列。原来在一个文件中只能有一个__autoload()方法,但现在,你拥有的是一个队列。

函数格式

spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] ) : bool

有点长,我们一步步看:

  • callable $autoload_function:闭包函数,不多解释了,上面已经说了,不了解闭包函数的作用可以百度百度

  • bool $throw:当$autoload_function无法成功注册时,是否抛出异常

  • bool $prepend:如果是true,将会添加一个__autoload()函数到队列的顶部

  • 这个函数有返回值,成功或失败

改造代码

嗯,到这里好像有点复杂了,我们需要改造改造代码这样才能让大家看得更清晰,先准备另一个需要加载的类文件,就叫CaseClass.php好了

<?php

class CaseClass
{
public function show()
{
echo "Good!\n";
}
}

然后修改spl_autoload_register.php文件

<?php

// 使用匿名函数方式
spl_autoload_register(function( $className ){
echo "first==>\n";
require_once 'TestClass.php';
});

// 需要注册的外部__autoload()实现
spl_autoload_register('CaseAutoLoad');

function CaseAutoLoad( $className ){
echo "second==>\n";
require_once 'CaseClass.php';
}

$m = new TestClass();
$m->show();

echo "--------\n";

$s = new CaseClass();
$s->show();

什么都别说了,直接运行吧,如果有报错请检查下哪里写错了,反正我这里没错~~

正常情况下应该输出这样的内容

  1. "first==>"是我们原来的spl_autoload_register()函数输出的内容,这里我们没有使用$className来动态加载,而是只加载TestClass.php这一个文件

  2. 接下来我们便输出了TestClass里面的show()方法的内容。需要注意的是:这里可还没有加载CaseClass.php这个文件哦,也就是现在我们已经实现了懒加载了哦

  3. 接下来,我们想要实例化CaseClass对象,于是spl_autoload_register()维护的队列发挥作用了。先走第一条,利用require_once()对于之前已经加载过的TestClass.php不会再次加载了。但是这一个文件中并没有找到我们需要的CaseClass对象,于是我们进入了队列第二条,来到了CaseAutoLoad()方法中,CaseClass.php终于在这个方法中被require_once()进来了

到这里,你已经知道了这个函数最大的作用就是维护的这个队列并且可以延迟加载我们需要的文件。是不是感觉有点要走上人生巅峰了?不不不,你心里或许还在疑惑,这玩意跟Composer有啥关系?

请在您需要测试的目录初始化一个Composer

  • 进入vendor/composer/autoload_real.php中

  • 在getLoader()方法中马上就能发现spl_autoload_register()方法

  • 然后在最底下有个$loader->register(true);方法-- 简单的阅读代码我们发现其实这个$loader就是ClassLoader类

  • 进入ClassLoader.php文件中,找到register()方法- 没错,里面还是一个spl_autoload_register()方法,这样来看,这货就是Composer的灵魂啊!!

OK,走到这里,其实在面试的时候就可以跟面试官司吹牛了,Composer的原理?spl_autoload_register()方法嘛。说不定确实有不少人就被你唬住了,但是,对于Composer来说,我们还有一个非常重要的方面不能忽略,可以将它看作是Composer的血肉,让自动加载能够有形,成为一个有灵魂有躯体的完整的人,这就是PSR规范中的PSR0和PSR4规范,下篇我们就聊聊这俩货!

完整源码:https://github.com/zhangyue0503/php-blog-code-resource/

(0)

相关推荐

  • laravel 多模块模式下进行开发

    用 composer 命令下载并安装扩展包包 composer require nwidart/laravel-modules 生成配置文件 php artisan vendor:publish –p ...

  • 快速安装laravel框架的IDE提示工具

    快速安装laravel框架的IDE提示工具 使用以下命令将此包与composer一起使用: composer require –dev barryvdh/laravel-ide-helper 更新co ...

  • 深入学习Composer原理(一)

    Composer作为PHP的包管理工具,为PHPer们提供了丰富的类库,并且让PHP重焕新生,避免被时代淘汰的悲剧.可以说,Composer和PHP7是现在PHP开发者的标配,如果你还没用过Compo ...

  • 深入学习Composer原理(三)

    本系列第三篇文章,一起了解下PSR规范中的PSR4和PSR0规范 首先恭喜大家,包括我自己,坚持到了现在.这篇文章之后,Composer的基础原理就清晰明了咯.也就是说,Composer所利用的正是s ...

  • 深入学习Composer原理(四)

    本系列第四篇文章,也是最后一篇 首先,我们先看看Composer的源码从哪里看起.当然,请您先准备好源码. composer init或者直接install之后,自动生成了一个vendor目录,这时您 ...

  • 魏书生:好学生学习的十二个习惯!(老师转给学生)

    最新的研究发现,智商并不是决定孩子成绩的主要因素,关键还要看学习习惯! 对于家长来讲,一定要先给孩子抓好习惯,再谈成绩. 小磊哥今天给大家分享的是,当代著名教育改革家魏书生,总结出来的好学生的十二个学 ...

  • 学习中医药(二十)中药的禁忌

    为了确保疗效.安全用药.避免毒副作用的产生,必须注意用药禁忌.中药的用药禁忌主要包括配伍禁忌.证候禁忌.妊娠禁忌和服药的饮食禁忌四个方面. 一.配伍禁忌 所谓配伍禁忌,就是指某些药物合用会产生剧烈的毒 ...

  • “物联网开发实战”学习笔记-(二)手机控制智能电灯

    如果搭建好硬件平台后,这一次我们的任务主要是调试好智能电灯,并且连接到腾讯云的物联网平台. 腾讯云物联网平台 腾讯物联网平台的优势: 腾讯云链接: link. 到物联网平台的原因这是因为物联网平台提供 ...

  • 魏书生:好学生学习的十二个习惯

    魏书生:好学生学习的十二个习惯

  • 《学习之道》:不了解学习的原理,就是在无效重复!

    《学习之道》:不了解学习的原理,就是在无效重复!

  • 漫谈英语词汇学习技巧之二

    在<漫谈英语词汇学习技巧之一>中主要介绍了单词的构成,包括形音义三部分,以及在背诵单词过程中,听自己声音的重要性.也就是背诵单词,一定是动手.动口.用耳.用心的过程. 那今天就想要进一步介 ...