Laravel 的配置文件加载源码分析

Posted 小伍

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Laravel 的配置文件加载源码分析相关的知识,希望对你有一定的参考价值。

Laravel 的配置缓存被保存在 bootstrap/cache/config.php 文件中。这个文件就是把 config 文件夹的所有文件合并成了一个大的配置文件。config.php 直接返回一个数组,数组的键名对应 config 文件夹下的文件名,数组的值对应 config 文件夹下文件返回的配置信息。

源码分析

使用到配置缓存文件的类:

class Application extends Container implements ApplicationContract, HttpKernelInterface
{
    // 获取配置缓存文件的路径
    public function getCachedConfigPath()
    {
        return $this->normalizeCachePath(\'APP_CONFIG_CACHE\', \'cache/config.php\');
    }

    // 应用配置是否已经缓存(即配置缓存文件是否存在)
    public function configurationIsCached()
    {
        return file_exists($this->getCachedConfigPath());
    }

调用到 getCachedConfigPath() 的类:

class LoadConfiguration
{
    // 应用启动
    public function bootstrap(Application $app)
    {
        $items = [];

        // 如果配置文件已缓存,则直接加载;否则遍历每个配置文件然后全部加载。
        if (file_exists($cached = $app->getCachedConfigPath())) {
            $items = require $cached;

            $loadedFromCache = true;
        }

        // 遍历配置目录中的所有配置文件,并逐一加载到仓库中
        // 使配置选项对于开发者来说在应用的各个部分中均可用
        $app->instance(\'config\', $config = new Repository($items));

        if (! isset($loadedFromCache)) {
            $this->loadConfigurationFiles($app, $config);
        }

        // 根据加载的配置值设置应用程序的环境。
        $app->detectEnvironment(function () use ($config) {
            return $config->get(\'app.env\', \'production\');
        });

        date_default_timezone_set($config->get(\'app.timezone\', \'UTC\'));

        mb_internal_encoding(\'UTF-8\');
    }
}

调用到 configurationIsCached() 的类:

class LoadEnvironmentVariables
{
    // 应用启动
    public function bootstrap(Application $app)
    {
        // 如果配置缓存文件已存在,则直接返回
        if ($app->configurationIsCached()) {
            return;
        }

        // 自定义环境配置文件
        $this->checkForSpecificEnvironmentFile($app);

        // 加载系统配置文件 .env
        try {
            $this->createDotenv($app)->safeLoad();
        } catch (InvalidFileException $e) {
            $this->writeErrorAndDie($e);
        }
    }

    // 检测是否存在 APP_ENV 中匹配的自定义环境配置文件
    protected function checkForSpecificEnvironmentFile($app)
    {
        if ($app->runningInConsole() && ($input = new ArgvInput)->hasParameterOption(\'--env\')) {
            if ($this->setEnvironmentFilePath(
                $app, $app->environmentFile().\'.\'.$input->getParameterOption(\'--env\')
            )) {
                return;
            }
        }

        $environment = Env::get(\'APP_ENV\');

        if (! $environment) {
            return;
        }

        $this->setEnvironmentFilePath(
            $app, $app->environmentFile().\'.\'.$environment
        );
    }

    // 加载自定义环境配置文件,如 .env.local
    protected function setEnvironmentFilePath($app, $file)
    {
        if (file_exists($app->environmentPath().\'/\'.$file)) {
            $app->loadEnvironmentFrom($file);

            return true;
        }

        return false;
    }

    // 创建 Dotenv 实例
    protected function createDotenv($app)
    {
        return Dotenv::create(
            $app->environmentPath(),
            $app->environmentFile(),
            Env::getFactory()
        );
    }

总结

如果配置文件缓存已经存在,则直接使用配置文件缓存。

如果配置文件缓存不存在,则先加载自定义配置文件,再加载系统配置文件。

以上是关于Laravel 的配置文件加载源码分析的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

Spring源码分析Bean加载流程概览

Spring源码分析Bean加载流程概览

laravel5.5用户认证源码分析

Android 逆向类加载器 ClassLoader ( 类加载器源码简介 | BaseDexClassLoader | DexClassLoader | PathClassLoader )(代码片段