Laravel源码分析---composer文件加载

    最近在使用Laravel框架,所以分析一下源码是如何设计的。
首先我们可以在Laravel项目的入口文件看见这些代码。

<?php

/**
 * Laravel - A PHP Framework For Web Artisans
 *
 * @package  Laravel
 * @author   Taylor Otwell <taylor@laravel.com>
 */

define('LARAVEL_START', microtime(true));

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/

require __DIR__.'/../vendor/autoload.php'; // (1)

/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/

$app = require_once __DIR__.'/../bootstrap/app.php';  // (2)

/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); // (3)

$response = $kernel->handle(  // (4)
    $request = Illuminate\Http\Request::capture()
);

$response->send();  //(5)

$kernel->terminate($request, $response);  // (6)

这里面我划分了6个点,分别是:
(1)类加载
(2)应用实体类初始化
(3)绑定http或者console内核
(4)请求处理
(5)结果返回客户端
(6)结束请求后的处理操作

这次分析的是类加载。

程序第一次请求,我们会进入autoload.php文件

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit859fdbc36eb6d63b36031b6c1db7e16b::getLoader();

这里面autoload_real.php是重点,这个类基本上在composer中起了入口文件的功能。它将所有的功能都汇总在一起。ComposerAutoloaderInit859fdbc36eb6d63b36031b6c1db7e16b::getLoader()这个就是autooad_real.php的类,这里为什么会用这么奇怪的名字?因为这是一个全局的类,为了不让其他程序员写出相同的名字,所以添加上一串哈希值。然后我们看看getLoader到底是在干什么的?

    public static function getLoader()
    {
    	//单例,防止多次初始化
        if (null !== self::$loader) {
            return self::$loader;
        }
		//注册自动加载函数
        spl_autoload_register(array('ComposerAutoloaderInit859fdbc36eb6d63b36031b6c1db7e16b', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
        //删除自动加载函数
        spl_autoload_unregister(array('ComposerAutoloaderInit859fdbc36eb6d63b36031b6c1db7e16b', 'loadClassLoader'));
		//检查PHP版本是否大于等于5.6,是就使用静态方法调用
        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
        if ($useStaticLoader) {
            require_once __DIR__ . '/autoload_static.php';
			//调用闭包函数,类默认引用传递
            call_user_func(\Composer\Autoload\ComposerStaticInit859fdbc36eb6d63b36031b6c1db7e16b::getInitializer($loader));
        } else {
        	//设置变量映射
            $map = require __DIR__ . '/autoload_namespaces.php';
            foreach ($map as $namespace => $path) {
                $loader->set($namespace, $path);
            }

            $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);
		//这也是PHP=5.6就直接调用静态变量
        if ($useStaticLoader) {
            $includeFiles = Composer\Autoload\ComposerStaticInit859fdbc36eb6d63b36031b6c1db7e16b::$files;
        } else {
            $includeFiles = require __DIR__ . '/autoload_files.php';
        }
        //file文件加载进来
        foreach ($includeFiles as $fileIdentifier => $file) {
            composerRequire859fdbc36eb6d63b36031b6c1db7e16b($fileIdentifier, $file);
        }

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

上面的composer加载重点其实在$loader->register(true);这个语句就是文件根据命名空间找到文件的功能。

    /**
     * Registers this instance as an autoloader.
     *
     * @param bool $prepend Whether to prepend the autoloader or not
     */
    public function register($prepend = false)
    {
    	//注册根据命名空间自动加载类文件函数
        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
    }

根据上面的注释,很清晰的知道了composer究竟在干了什么了。然而你或许会疑问那些文件究竟是怎么来的,这里我可以告诉你是在使用composer install的时候就已经生成好的了。就这样子Laravel的文件加载就完成了。

如果你还是不懂,那可能就是PHP基础问题了。可以看看我的PHP框架开发教程。只要跟着框架自己写一遍之后,你就会发现,其实这里面没什么难以理解的。最主要的还是如何定义命名空间获取目录中的文件问题。而且我的框架开发中的composer支持或许会对你有些许帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值