深刻学习Composer原理(二)

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

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

这回咱们创建一个文件,叫作spl_autoload_register.php,而后将下面的代码复制进去吧:git

<?php

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

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

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

咱们先看看它的定义和格式面试

PHP官方文档中的定义

注册给定的函数做为 __autoload 的实现sql

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

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

函数格式

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

有点长,咱们一步步看:composer

  • 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();

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

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

image

  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

相关文章
相关标签/搜索