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

时间:2022-10-28 11:16:18

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已经加载到了

深入理解 Laravel 中 config 配置加载原理的更多相关文章

  1. Django中模块的加载原理

    Django中的module的加载是通过反射来完成的,借助importlib中的import_module函数来实现的动态加载.import_module的内部通过使用了递归和线程锁,字符串的切割,实 ...

  2. 通过源码浅析Java中的资源加载

    前提 最近在做一个基础组件项目刚好需要用到JDK中的资源加载,这里说到的资源包括类文件和其他静态资源,刚好需要重新补充一下类加载器和资源加载的相关知识,整理成一篇文章. 理解类的工作原理 这一节主要分 ...

  3. springcloud项目配置拓展从本地config目录加载

    本文受阿里开源的Nacos启发,应用启动后从Nacos服务加载配置到应用中,想着本地开发的时候加载配置能否从本地存储中加载,这样也能加快开发效率 首先我们来看下SpringCloud项目应用Nacos ...

  4. 【Dubbo源码阅读系列】之 Dubbo XML 配置加载

    今天我们来谈谈 Dubbo XML 配置相关内容.关于这部分内容我打算分为以下几个部分进行介绍: Dubbo XML Spring 自定义 XML 标签解析 Dubbo 自定义 XML 标签解析 Du ...

  5. Log4j2源码分析系列:(一)配置加载

    前言 在实际开发项目中,日志永远是一个绕不开的话题.本系列文章试图以slf4j和log4j2日志体系为例,从源码角度分析日志工作原理. 学习日志框架,首先要熟悉各类日志框架,这里推荐两篇文章,就不再赘 ...

  6. 关于flume配置加载

    最近项目在用到flume,因此翻了下flume的代码, 启动脚本: nohup bin/flume-ng agent -n tsdbflume -c conf -f conf/配置文件.conf -D ...

  7. 关于asp.net中页面事件加载的先后顺序

    一.ASP.NET 母版页和内容页中的事件 母版页和内容页都可以包含控件的事件处理程序.对于控件而言,事件是在本地处理的,即内容页中的控件在内容页中引发事件,母版页中的控件在母版页中引发事件.控件事件 ...

  8. Java实现配置加载机制

    前言 现如今几乎大多数Java应用,例如我们耳熟能详的tomcat, struts2, netty…等等数都数不过来的软件,要满足通用性,都会提供配置文件供使用者定制功能. 甚至有一些例如Netty这 ...

  9. Android开发中如何解决加载大图片时内存溢出的问题

    Android开发中如何解决加载大图片时内存溢出的问题    在Android开发过程中,我们经常会遇到加载的图片过大导致内存溢出的问题,其实类似这样的问题已经屡见不鲜了,下面将一些好的解决方案分享给 ...

随机推荐

  1. dos 操作显示 > nul 2>nul

    1>nul 屏蔽操作成功显示的信息,但是出错还是会显示(同 >nul)2>nul 屏蔽操作失败显示的信息,但是成功还是会显示>nul 2>nul 就是正确的错误的一起屏蔽 ...

  2. vi/vim实用命令

    查找 n是下一个,N是上一个 撤销和重做 u:撤销上一步的操作 ctrl+r:恢复上一步被撤销的操作 替换 :1,$ s/aaa/bbb/g

  3. iOS开发UI篇—Quartz2D使用(图片剪切)

    iOS开发UI篇—Quartz2D使用(图片剪切) 一.使用Quartz2D完成图片剪切 1.把图片显示在自定义的view中 先把图片绘制到view上.按照原始大小,把图片绘制到一个点上. 代码: - ...

  4. Glide 下载Gif文件

    之前做了一个类似朋友圈里的查看大图功能,现在也要加上保存功能. 保存图片有很多思路,可以从imageview里提取bitmap,可以用url下载到本地.imageview提取的话,gif图就会变成一张 ...

  5. UDP丢包和无序 问题的解决方法

    最近在做一个项目,在这之前,做了个验证程序. 发现客户端连续发来1000个1024字节的包,服务器端出现了丢包现象. 纠其原因,是服务端在还未完全处理掉数据,客户端已经数据发送完毕且关闭了. 我用过s ...

  6. Java初转型-Maven入门

    原系列名:Maven学习总结(一) 原博文出自于:http://www.cnblogs.com/xdp-gacl/p/3498271.html 感谢! 一.Maven的基本概念 Maven(翻译为&q ...

  7. listbox修改字体大小

    listBox1.Font = new Font(this.Font.FontFamily, 14);

  8. [Django实战] 第8篇 - 分页列表

    当用户登录成功后,首先看到的是他自己之前提交的任务列表,本篇将实现该页面. 视图(views.py)里定义如下: from django.core.paginator import Paginator ...

  9. hdu 1217

    判断通过货币的兑换能否获利,,最短路,这里是乘法,, #include<stdio.h> #include<string.h> double map[31][31],ans[3 ...

  10. checkout 多选 全选(亲测有效)

    <input type="button" id="btn1" value="全选"> <input type=" ...