深入理解composer自动加载原理

简介: 深入理解composer自动加载原理

Composer 作为 PHP 的包管理工具,为 PHPer 们提供了丰富的类库,本文来一步步剖析 Composer 的原理

从 __autoload魔术方法 到  spl_autoload_register函数

建立vendor目录,下面建立 autoload.phpTestClass.phpspl_autoload_register.php

利用__autoload实现自动加载

  • autoload.php
<?php
/**
 * Created by 憧憬.
 */
$testClass = new TestClass();
$testClass->print();
function __autoload($className)
{
    require $className . '.php';
}
  • TestClass.php
<?php
/**
 * Created by 憧憬.
 */
class TestClass
{
    public function print()
    {
        echo 'Test Class!!';
    }
}

在编写过程中,我并没有引入 TestClass.php, 但是可以利用 __autoload 这个魔术方法来进行自动引入,该方法就是在类未加载时自动触发,但是这个是之前的实现,未来可能废弃,在 php7.2 后使用 spl_autoload_register 我们来看一下

自动加载的未来: spl_autoload_register

PHPSPL库作为扩展库,其中包含很多类库,已经于5.3.0版本后默认保持开启,成为PHP的一组强大的核心扩展库。

实现自动加载

  • spl_autoload_register.php
<?php
/**
 * Created by 憧憬.
 */
spl_autoload_register(function ($className) {
    require $className . '.php';
});
$testClass = new TestClass();
$testClass->print();

是不是和__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
/**
 * Created by 憧憬.
 */
spl_autoload_register(function ($className) {
    require_once 'TestClass' . '.php';
});
spl_autoload_register('CaseAutoLoad');
function CaseAutoLoad( $className ){
    echo "second==>\n";
    require_once 'CaseClass.php';
}
$testClass = new TestClass();
$testClass->print();
echo "还没实例化 CaseClass \n";
// 在这之前都没有执行第二个 spl_autoload_register函数 也就是利用闭包实现了懒加载
$s = new CaseClass();
$s->show();

这个函数最大的作用就是维护这个队列并且可以延迟加载我们需要的文件

查看composer的源码并实现psr4命名空间自动加载

composer init或者直接install之后,自动生成了一个vendor目录,这时您需要在文件中手动的require这个vendor目录下的autoload.php文件,便可以自动加载第三包了,其实这个文件又载入了vendor/composer/autoload_real.php

  • 进入vendor/composer/autoload_real.php
  • getLoader()方法中马上就能发现spl_autoload_register()方法
  • 并在最后看到 $loader->register(true); $loader就是 ClassLoader.php
  • 进入ClassLoader.php文件中,找到register()方法 没错,里面还是一个spl_autoload_register()方法,这样来看,这货就是Composer的灵魂啊!!

我们来看一下,因为考虑到php版本的问题,所以有多种加载方式,比如我们耳熟能详的 命名空间自动加载

vendor 下面建立目录 Model/UserModel.phpautoload_psr4.php

  • Model/UserModel.php
<?php
/**
 * Created by 憧憬.
 */
namespace Model;
class UserModel
{
    public function show()
    {
        echo 'user model!';
    }
}
  • autoload_psr4.php
<?php
/**
 * Created by 憧憬.
 */
spl_autoload_register(function ($class) {
    $file   = __DIR__ . '/' . str_replace('\\', '/', $class) . '.php';
    if (file_exists($file)) {
        require $file;
    }
});
use Model\UserModel;
$t = new UserModel();
$t->show();

这样也就实现了自动加载

autoload_real.php中,我们发现了熟悉的spl_autoload_register函数。但这个文件最大的作用是去加载ClassLoader.php这个文件和一些目录文件,也在同级目录下。在autoload_real.php中,大家可以发现在调用ClassLoader的register()函数前,还加载了几个目录相关的文件

  • autoload_static.php,静态加载方式,顶级类加载命名空间
  • autoload_psr4.php,遵守PSR4规范的包目录映射数组文件
  • autoload_namespaces.php,命名空间映射,PSR0规范
  • autoload_classmap.php,类图映射,命名空间直接映射路径

这些就对应不同的规范,使用不同的自动加载,我们可以安装一些包看一下这些源码会发生哪些改变,我安装了一个 qrcode 的包, autoload_psr4.php的内容变成了这样:

接下来,composer这个命令干了什么您应该也就了解了。当您进行composer require时,首先修改了composer.json文件,然后下载包,完成后根据包里的composer.json文件中所对应的规范来修改对应的autoload_xxx.php文件。完成了文件命名空间相关内容的映射。当register()进行加载的时候,自然就得心应手了。

参考自: https://zhuanlan.zhihu.com/p/96505061

目录
相关文章
|
6月前
|
PHP 开发者
深入理解PHP的命名空间和自动加载机制
在PHP开发中,合理使用命名空间和自动加载机制可以有效管理代码,提升项目的可维护性和可扩展性。本文将详细解析PHP命名空间的概念、实现原理及其与自动加载机制的协同工作方式,旨在为开发者提供清晰的指导和实践建议,帮助构建更加模块化和高效的PHP应用程序。
|
3月前
|
PHP 开发者
深入理解PHP的命名空间与自动加载机制
【7月更文挑战第60天】 在现代PHP开发中,命名空间和自动加载机制是模块化和代码复用的关键。本文将详细探讨PHP命名空间的概念、实现及其与自动加载机制的协同工作方式。我们将通过示例代码和实践建议,揭示如何有效利用这些特性来优化项目结构,提升代码维护性和可扩展性。
|
6月前
|
PHP 开发者
深入理解PHP的命名空间和自动加载机制
【5月更文挑战第31天】 在PHP中,命名空间和自动加载机制是两个重要的特性,它们可以帮助我们更好地组织代码和管理依赖。本文将详细介绍PHP的命名空间和自动加载机制的原理和使用,以及如何在实际项目中应用这两个特性来提高代码的可维护性和可读性。
|
6月前
|
PHP
深入理解PHP中的命名空间和自动加载机制
【5月更文挑战第30天】在PHP中,命名空间和自动加载机制是两个重要的概念。命名空间解决了代码中的名称冲突问题,而自动加载机制则可以按需加载类,提高代码执行效率。本文将深入探讨PHP中的命名空间和自动加载机制的原理和应用,帮助读者更好地理解和使用这两个特性。
|
6月前
|
PHP
深入理解composer自动加载原理
深入理解composer自动加载原理
43 0
|
Linux PHP 开发者
Composer 镜像原理 (1) —— 初识 Composer
Composer 是一个 PHP 的依赖管理工具,它可以帮助开发者轻松地管理和维护 PHP 项目中的依赖关系。你是否好奇过它的镜像仓库是怎么实现的?本文为你揭晓。
137 0
|
PHP
PHP自动加载与composer自动加载
在面向对象的程序中,大部分的情况都是需要使用命名空间的。我们先了解命名空间的知识,在后续也会结合命名空间实现自动加载 在我们使用计算机的过程,如果想在同一个路径目录下新建两个同名的文件,将会得到错误提示,当前目录下已经存在该文件名的文件。 在php程序中也是如此,我们没办法在同一个空间下声明两个一样类名的文件,否则会得到报错提示 Cannot declare class A, because the name is already in use
100 2
PHP自动加载与composer自动加载
|
流计算 计算机视觉 索引
使用ffmpeg将视频转成HLS(m3u8)格式
HLS (HTTP Live Streaming)是苹果推出的视频流协议,HLS格式的视频包含一个m3u8文本文件,以及众多的.ts的视频片段,而m3u8文本文件的作用就是将这些ts片段索引起来。 因为HLS协议是将视频切分成很多小的ts片段,这些小片段很适合放到cdn上,有很多视频文章都使用了hls格式传输视频。今天我在这里教大家如何用ffmpeg将mp4格式的视频转为HLS(m3u8)格式。
671 0
Yii2.0是否支持Composer?底层原理是什么?
Yii2.0是否支持Composer?底层原理是什么?
110 0
|
应用服务中间件 PHP nginx
mac环境composer新建php的symfony项目并用nginx配置
mac环境composer新建php的symfony项目并用nginx配置
196 0
mac环境composer新建php的symfony项目并用nginx配置