Laravel 的配置文件加載源碼分析

Laravel 的配置緩存被保存在 bootstrap/cache/config.php 文件中。這個文件就是把 config 文件夾的全部文件合併成了一個大的配置文件。config.php 直接返回一個數組,數組的鍵名對應 config 文件夾下的文件名,數組的值對應 config 文件夾下文件返回的配置信息。php

源碼分析

使用到配置緩存文件的類:bootstrap

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()
        );
    }

總結

若是配置文件緩存已經存在,則直接使用配置文件緩存。app

若是配置文件緩存不存在,則先加載自定義配置文件,再加載系統配置文件。源碼分析

相關文章
相關標籤/搜索