疯子好好活

探究Laravel4.2加载(一)— autoload

发布时间:2016年3月22日 / 分类:PHP / 483 次围观 / 抢沙发!

以手上的4.2为准,本篇只看自动加载部分。

入口文件在:/public/index.php,打开看看。

<?php
require __DIR__.'/../bootstrap/autoload.php';

来到 /bootstrap/autoload.php

<?php
// 记录Laravel开始加载的时间
define('LARAVEL_START', microtime(true));

// 下一步看看这个文件
require __DIR__.'/../vendor/autoload.php';

来到 /vendor/autoload.php

<?php
// 下一步看看这个文件
require_once __DIR__ . '/composer' . '/autoload_real.php';
// 预告:require了上面这个文件之后,执行了上面文件中的getLoader()方法,类名是动态生成的
return ComposerAutoloaderInit78fadea5a0911ad1d52c374950318f50::getLoader();

终于来到 /vender/composer/autoload_real.php

<?php
// 动态生成的类名
class ComposerAutoloaderInit78fadea5a0911ad1d52c374950318f50
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        // 临时的加载函数,只允许加载Composer\Autoload\ClassLoader
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }
        // 注册自己的自动加载函数,就在上面。
        // 第三个参数是true,将自己的自动加载函数注册到队列之首。
        spl_autoload_register(array('ComposerAutoloaderInit78fadea5a0911ad1d52c374950318f50', 'loadClassLoader'), true, true);
        // 借助自动加载函数 加载ClassLoader到$loader
        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
        // 把刚刚注册的自动加载函数注销掉。是的,就是这么任性,临时用了一下
        spl_autoload_unregister(array('ComposerAutoloaderInit78fadea5a0911ad1d52c374950318f50', 'loadClassLoader'));

        // 设置 include_path
        $includePaths = require __DIR__ . '/include_paths.php';
        array_push($includePaths, get_include_path());
        set_include_path(join(PATH_SEPARATOR, $includePaths));

        // 登记以PSR-0方式加载的类们
        $map = require __DIR__ . '/autoload_namespaces.php';
        foreach ($map as $namespace => $path) {
            $loader->set($namespace, $path);
        }

        // 登记以PSR-4方式加载的类们
        $map = require __DIR__ . '/autoload_psr4.php';
        foreach ($map as $namespace => $path) {
            $loader->setPsr4($namespace, $path);
        }

        // 登记直接加载的类们
        $classMap = require __DIR__ . '/autoload_classmap.php';
        if ($classMap) {
            $loader->addClassMap($classMap);
        }
        
        // 执行加载
        $loader->register(true);

        // 加载一些文件,这些文件的目的是注册一些函数
        $includeFiles = require __DIR__ . '/autoload_files.php';
        foreach ($includeFiles as $fileIdentifier => $file) {
            // 借用下面的方法去加载
            composerRequire78fadea5a0911ad1d52c374950318f50($fileIdentifier, $file);
        }

        // 到此自动加载结束,层层跳回
        return $loader;
    }
}

function composerRequire78fadea5a0911ad1d52c374950318f50($fileIdentifier, $file)
{
    // 如果加载过了就不重复加载
    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
        require $file;
    
        // 加载过之后给个标记
        $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
    }
}

标签:laravel, php