composer实现自动加载代码备忘录(一)

2019-11-15 20:08:27 浏览数 (1)

autoload_real.php源码中第一部分:
代码语言:javascript复制
<?php

// autoload_real.php @generated by Composer

class ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        if ('ComposerAutoloadClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }

        spl_autoload_register(array('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'), true, true);
        self::$loader = $loader = new ComposerAutoloadClassLoader();
        spl_autoload_unregister(array('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'));
.
.
.

这个文件定义了一个ComposerAutoloaderInit Hash值命名的类,先看上面这段代码中的几个点。

  1. 定义了私有静态属性$loader
  2. 定义了静态方法loadClassLoader()
  3. 定义了静态方法getLoader()

这三点的作用:

  1. 静态属性$loader是因为后面在静态方法中的getLoader()中有一段
代码语言:javascript复制
<?php
.
.
.
if (null !== self::$loader) {
return self::$loader;
}

这个是最简单的单例模式,因此$loader就是为了接收对象

  1. 静态方法loadClassLoader()的作用是为了require ClassLoader.php这个文件
代码语言:javascript复制
if ('ComposerAutoloadClassLoader' === $class) {
    require __DIR__ . '/ClassLoader.php';
}

这个类的参数$class为什么与'ComposerAutoloadClassLoader'相等,是因为第三点

  1. 静态方法getLoader()中的代码
代码语言:javascript复制
 spl_autoload_register(array('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'), true, true);
 self::$loader = $loader = new ComposerAutoloadClassLoader();
 spl_autoload_unregister(array('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'));

首先通过spl_autoload_register()这个函数通过回调函数的机制在自动加载堆栈中注册了一个方法,这个方法就是

代码语言:javascript复制
ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13::loadClassLoader();

注册好了自动加载之后,紧接着

代码语言:javascript复制
self::$loader = $loader = new ComposerAutoloadClassLoader();

上面那段代码先执行new ComposerAutoloadClassLoader();因为这个类并不存在(因为我们之前并没有require过),所以就调用了堆栈中的loadClassLoader()方法,因此就执行了

代码语言:javascript复制
public static function loadClassLoader($class)
 {
    if ('ComposerAutoloadClassLoader' === $class) {
        require __DIR__ . '/ClassLoader.php';
    }
}

这个$class参数就是上面new的类名,也就是ComposerAutoloadClassLoader因此走进了if判断,进而

代码语言:javascript复制
require __DIR__ . '/ClassLoader.php';

导入进了ClassLoader.php,这一部分就梳理完了 注:

  1. 回调函数可以用数组形式实现调用,
代码语言:javascript复制
array('A','test');

当使用回调函数的时候,用数组形式传递,那么A就指的是类名,test是A类中的静态方法,方法必须是静态的

代码语言:javascript复制
array($obj,'test');

$obj是实例化的对象,test是该对象的方法

附文档和参考文献:

  1. http://hanfeng.name/blog/2015/08/17/composer-autoload/
  2. spl_autoload_register(); http://php.net/manual/zh/function.spl-autoload-register.php
  3. 回调函数: http://php.net/manual/zh/language.types.callable.php

0 人点赞