本系列的第二篇文章,这次我们聊聊: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. tomcat及springboot实现Filter、Servlet、Listener

    tomcat实现: 核心类org.apache.catalina.startup.ContextConfig //支持注解 see:org.apache.catalina.deploy.WebXml ...

  2. Git-09-常用命令

    git常用命令 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令 下面是我整理的常用 Git 命令清单.几个专用名词的译名如下. Workspace:工作区 ...

  3. Python语言系列-02-基础数据类型

    格式化输出 #!/usr/bin/env python3 # author:Alnk(李成果) # 百分号% 格式化输出 name = input('姓名:') age = input('年龄:') ...

  4. LuoguP3167通配符匹配

    题意 本题的意思就是给出一段带有 $ ? $ 与 \(*\) 的字符串 (在下面称为\(s\)), $ ? $ 必须占据一个字符位置, \(*\) 可以占据任意位置, 求下面给出几段(在下面称为\(s ...

  5. Docker创建Nexus

    docker-compose.yml 注意为/usr/local/docker/nexus/data授权读写权限! version: '3.1' services: nexus: restart: a ...

  6. 查询liunx上磁盘占用情况

    查询挂载盘磁盘情况 df -h 查询指定目录下的文件夹内存占用情况 du -hs /*

  7. 《深入浅出vue.js》阅读笔记之(object)变化侦测

    1.什么是变化侦测? 通常,在运行时应用内部的状态会不断发生变化,此时需要不停地重新渲染页面,这时如何确定状态中发生了什么变化? 变化侦测就是用来解决这个问题的,它分为两种类型,一种是"推& ...

  8. 使用TypeConverter类

    3.2.2 使用TypeConverter类将XAML标签的Attribute与对象的Property进行映射注意本小节的例子对于初学者来说理解起来比较困难而且实用性不大,主要是为喜欢刨根问底的WPF ...

  9. 我说Java完全面向对象,老大过来就是一jio

    哈喽,大家好,我是指北君.自从开始学Java,就知道Java是一门面向对象编程的语言,所以在指北君眼中,Java就是完全面向对象的.有一天老大问到我这个事情,我脱口而出,结果老大过来就是一jio... ...

  10. Go版本管理--处理不兼容

    目录 1. 简介 2.能否引起不兼容的包 3.如何处理incompatible 1. 简介 Go module的版本选择机制,其中介绍了一个Module的版本号需要遵循v<major>.& ...