本系列的第二篇文章,这次我们聊聊: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规范,下篇我们就聊聊这俩货!

完整源码:GitHub

===============

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

深入学习Composer原理(二)的更多相关文章

  1. 深入学习Composer原理(四)

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

  2. 深入学习Composer原理(一)

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

  3. 深入学习Composer原理(三)

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

  4. ZooKeeper学习笔记(二)——内部原理

    zookeeper学习笔记(二)--内部原理 1. zookeeper的节点的类型 总的来说可以分为持久型和短暂型,主要区别如下: 持久:客户端与服务器端断开连接的以后,创建的节点不会被删除: 持久化 ...

  5. 学习javascript数据结构(二)——链表

    前言 人生总是直向前行走,从不留下什么. 原文地址:学习javascript数据结构(二)--链表 博主博客地址:Damonare的个人博客 正文 链表简介 上一篇博客-学习javascript数据结 ...

  6. JavaWeb学习总结(三)——Tomcat服务器学习和使用(二) 包含https 非对称秘钥 NB

    JavaWeb学习总结(三)--Tomcat服务器学习和使用(二) 一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命 ...

  7. Lua学习系列(二)

    资源整理: 风云老师博客: http://blog.codingnow.com/eo/luaoeeeaeau/ 知乎: https://www.zhihu.com/question/20736660 ...

  8. Deep Q-Network 学习笔记(二)—— Q-Learning与神经网络结合使用(有代码实现)

    参考资料: https://morvanzhou.github.io/ 非常感谢莫烦老师的教程 http://mnemstudio.org/path-finding-q-learning-tutori ...

  9. 深入浅出深度学习:原理剖析与python实践_黄安埠(著) pdf

    深入浅出深度学习:原理剖析与python实践 目录: 第1 部分 概要 1 1 绪论 2 1.1 人工智能.机器学习与深度学习的关系 3 1.1.1 人工智能——机器推理 4 1.1.2 机器学习—— ...

随机推荐

  1. linux虚拟机环境快速搭建redis5.x版本的主从集群总结

    文/朱季谦 我在阿里云服务器上曾参与过公司redis集群的搭建,但时间久了,都快忘记当时的搭建过程了,故而决定在虚拟机centOS 7的环境,自行搭建一套redis5.x版本的集群,该版本集群的搭建比 ...

  2. Spring学习02(DI依赖注入)

    5.依赖注入(Dependency Injection,DI) 5.1 概念 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 . 注入 : 指Bean对象所依赖的资源 , 由容器 ...

  3. SQL语法 - SELECT 语句

    SELECT 语句用于从数据库中选取数据. SQL SELECT 语句 SELECT 语句用于从数据库中选取数据. 结果被存储在一个结果表中,称为结果集. SQL SELECT 语法 SELECT c ...

  4. 【XSS-labs】level 6-10

    Level 6 查看源码:对URL中的传参进行了HTML实体化转义,搜索框中的值对 src\onxxxxx\data\href进行了限制. 采用大小写绕过,在搜索框输入payload,注意闭合inpu ...

  5. Java MyEclipse:The type java.lang.CharSequence cannot be resolved. It is indirectly referen

    从svn上下载项目后配置weblogic后启动报错: myeclipse  The type java.lang.CharSequence cannot be resolved. It is indi ...

  6. NOIP 模拟 $27\; \rm 牛半仙的妹子序列$

    题解 \(by\;zj\varphi\) 明显一道极长上升子序列的题. 直接线段树维护单调栈,最后单调栈求出可以贡献的序列,答案相加就行. Code #include<bits/stdc++.h ...

  7. Git进行clone的时候,报错:remote: HTTP Basic: Access denied fatal: Authentication failed for ...

    先执行: git config --system --unset credential.helper 原因:用户名或者密码错: 会提示让重新输入用户名和密码,输入正确的用户名和密码即可! 这样以后发现 ...

  8. element ui loading加载开启与关闭

    参考:https://blog.csdn.net/qq_41877107/article/details/87690555 Vue项目引入element-ui,之后,将以下代码写入 mounted() ...

  9. sparksql的三种join实现

    join 是sql语句中的常用操作,良好的表结构能够将数据分散在不同的表中,使其符合某种范式,减少表冗余,更新容错等.而建立表和表之间关系的最佳方式就是Join操作. sparksql作为大数据领域的 ...

  10. C++、Java、Python、Linux、Go、前端、算法,慕课资料分享

    C++.Java.Python.Linux.Go.前端.算法,慕课资料分享 微信公众号:大道同行JAVA 如有问题或建议,请后台留言,我会尽力解决你的问题. 前言 又见面了.废话不多说,最近多了一些在 ...