深入理解 Laravel 中 config 配置加载原理

深入理解 Laravel 中 config 配置加载原理

Laravel的配置加载其实就是加载config目录下所有文件配置。如何过使用php artisan config:cache则会把加载的配置合并到一个配置文件中,下次请求就不会再去加载config目录。

1.加载流程

  1. LoadEnvironmentVariables .env环境配置加载。如果缓存配置是不会加载.env
  2. LoadConfiguration 判断是否缓存配置
  3. 是,则直接加载配置,不会加载config目录所有文件了
  4. 否,则加载config目录所有PHP文件

2.什么时候加载配置?

内核启动的时候。加载以下启动类

\Illuminate\Foundation\Http\Kernel

protected $bootstrappers = [
        \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,  // 加载 .env
        \Illuminate\Foundation\Bootstrap\LoadConfiguration::class, // 加载config配置
        ...
    ];

本文重点讲解第二个config配置加载。第一个请查看 深入理解 Laravel 中.env 文件读取

3. 源码分析

LoadConfiguration类中config配置加载的具体逻辑。

其实就是判断缓存是否存在,存在则加载,不存在则递归遍历config目录所有php文件。如果运行php artisan config:cache,则会把加载结果保存在bootstrap/cache目录中;你可能还会看到services.php文件,这是一个保存所有的服务提供者的文件,具体以后会讲。

public function bootstrap(Application $app)
    {
        $items = [];

       // 首先,我们将看看是否有缓存配置文件。 如果是,我们将从该文件加载配置项,因此它非常快。 
       // 否则,我们需要遍历每个配置文件并加载它们。
        if (file_exists($cached = $app->getCachedConfigPath())) {
            // 加载缓存的配置文件
            $items = require $cached;

            $loadedFromCache = true;
        }

        // 接下来,我们将遍历配置目录中的所有配置文件,并将每个配置文件加载到Repository中。
        // 这将使开发人员可以使用所有选项,以便在此应用程序的各个部分中使用。
        $app->instance('config', $config = new Repository($items));

        // 如果没有缓存配置才会去加载config目录
        if (! isset($loadedFromCache)) {
            // 加载config目录所有PHP文件
            $this->loadConfigurationFiles($app, $config);
        }

        //最后,我们将根据加载的配置值设置应用程序的环境。 
        // 我们将传递一个回调,该回调将用于在Web环境中获取环境,其中不存在“--env”开关。
        $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');
    }

    /**
     * 从所有文件加载配置项。因此效率很低
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @param  \Illuminate\Contracts\Config\Repository  $repository
     * @return void
     * @throws \Exception
     */
    protected function loadConfigurationFiles(Application $app, RepositoryContract $repository)
    {
        // 遍历出所有PHP文件
        $files = $this->getConfigurationFiles($app);

        if (! isset($files['app'])) {
            throw new Exception('Unable to load the "app" configuration file.');
        }

        // 一个一个的加载
        foreach ($files as $key => $path) {
            $repository->set($key, require $path);
        }
    }

4.小结与注意点

  1. php artisan config:cache之后不会加载config配置,即便你修改了config目录中的配置文件也是不生效的,除非清除缓存php artisna config:clear,或者重新缓存 php artisan config:cache
  2. 因为配置缓存可以提高效率,因此推荐生产环境使用配置缓存。
  3. 不能在config目录内定义配置以外的东西。比如在config目录内定义类,定义常量,自定义函数。这些都是不推荐的,因为配置缓存之后,config目录任何文件都不会加载,这些类或者常量不存在,最终导致自动加载失败。解决方案是使用composer.json的自动加载配置来加载:
"autoload": {
        "classmap": [
            "database/seeds",
            "database/factories"
        ],
        "psr-4": {
            "App\\": "app/"
        },
        "files": [
            # 这样那个会加载helpers.php文件了。该文件定义的是辅助函数
            "bootstrap/helpers.php"
        ]
    },

  1. 在 config 中调用其他的 config('something.item') 是不会预期的加载的。因为不能保证配置something.item已经加载到了
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/112433.html原文链接:https://javaforall.net

(0)
上一篇 2021年11月7日 下午10:00
下一篇 2021年11月7日 下午11:00


相关推荐

  • SkillDeck 支持 OpenClaw 了,顺便聊聊小龙虾

    SkillDeck 支持 OpenClaw 了,顺便聊聊小龙虾

    2026年3月12日
    2
  • C# DllImport的用法

    大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法)要重新编写代码,C#有没有方法可以直接都用这些原本已经存在的功能呢?答案是肯定的,大家可以通过C#中的DllImport直接调用这些功能。DllImport所在的名字空间usingSystem.Runtime.InteropServices;MSDN中

    2022年4月8日
    49
  • css中什么是伪元素,CSS伪元素是什么?

    css中什么是伪元素,CSS伪元素是什么?什么 伪元素 之前不是说了伪类吗 怎么又跑出来一个伪元素吗 它们不是一样的吗 呵呵 其实伪类和伪元素是两个不同的概念 今天小编就为大家介绍一下伪元素 一 什么是伪元素 css 伪元素代表了某个元素的子元素 这个子元素虽然在逻辑上存在 但却并不实际存在于文档树中 二 语法伪元素的语法 selector pseudo element property value 标签 伪元素 性质 值 CSS 类也可以

    2026年3月18日
    1
  • AI文章检测工具 怎么判断是不是AI写的

    AI文章检测工具 怎么判断是不是AI写的

    2026年3月14日
    3
  • 终于有人把RISC-V讲明白了

    终于有人把RISC-V讲明白了0RISC V 和其他开放架构有何不同如果仅从 免费 或 开放 这两点来评判 RISC V 架构并不是第一个做到免费或开放的处理器架构 在开始之前 我们先通过论述几个具有代表性的开放架构 来分析 RISC V 架构的不同之处以及为什么其他开放架构没能取得足够的成功 0 1 平民英雄 OpenRISCOpen 是 OpenCores 组织提供的基于 GPL 协议的开放源代码 RISC 处理器

    2026年3月19日
    2
  • LCA问题(倍增法)

    LCA问题(倍增法)之前写过了 LCA 的两个在线算法之一 DFS ST 方法 DFS ST 本篇介绍另一种在线算法 用倍增思想来解决 LCA 问题 在学习倍增之前 先看一种倍增算法的退化版 有助于理解倍增法 在找 a 和 b 的 LCA 时 先让 a 和 b 中深度较大的那一个 向上回溯到与另一个同样深度的位置上 例如下面这个图 假设要找 F 和 E 的 LCA 先让 F 向上回溯到他的父节点 D 的

    2026年3月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号