美文网首页Laravel备忘录我爱编程
composer实现自动加载代码备忘录(一)

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

作者: 提莫小小队长 | 来源:发表于2018-05-24 10:48 被阅读14次

    autoload_real.php源码中第一部分:

    <?php
    
    // autoload_real.php @generated by Composer
    
    class ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13
    {
        private static $loader;
    
        public static function loadClassLoader($class)
        {
            if ('Composer\Autoload\ClassLoader' === $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 \Composer\Autoload\ClassLoader();
            spl_autoload_unregister(array('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'));
    .
    .
    .
    

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

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

    这三点的作用:

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

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

    1. 静态方法loadClassLoader()的作用是为了require ClassLoader.php这个文件
    if ('Composer\Autoload\ClassLoader' === $class) {
        require __DIR__ . '/ClassLoader.php';
    }
    

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

    1. 静态方法getLoader()中的代码
     spl_autoload_register(array('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'), true, true);
     self::$loader = $loader = new \Composer\Autoload\ClassLoader();
     spl_autoload_unregister(array('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'));
    

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

    ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13::loadClassLoader();
    

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

    self::$loader = $loader = new \Composer\Autoload\ClassLoader();
    

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

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

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

    require __DIR__ . '/ClassLoader.php';
    

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

    1. 回调函数可以用数组形式实现调用,
    array('A','test');
    

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

    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

    相关文章

      网友评论

        本文标题:composer实现自动加载代码备忘录(一)

        本文链接:https://www.haomeiwen.com/subject/ubvjjftx.html