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. Mybatis源码解读-SpringBoot中配置加载和Mapper的生成

    本文mybatis-spring-boot探讨在springboot工程中mybatis相关对象的注册与加载. 建议先了解mybatis在spring中的使用和springboot自动装载机制,再看此 ...

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

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

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

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

  7. 理解Laravel中的pipeline

    理解Laravel中的pipeline suoga 关注  0.1 2015.09.08 00:00* 字数 1533 阅读 7151评论 8喜欢 24 pipeline在laravel的启动过程中出 ...

  8. Spring Cloud Nacos实现动态配置加载的源码分析

    理解了上述Environment的基本原理后,如何从远程服务器上加载配置到Spring的Environment中. NacosPropertySourceLocator 顺着前面的分析思路,我们很自然 ...

  9. 关于flume配置加载

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

随机推荐

  1. Cesium学习2:如何从零开始在Eclipse IDE,Java语言搭建cesium开发环境

    废话不多说,今天就先在Eclipse上搭建Cesium开发环境吧~ 零.Cesium简介 Cesiumjs 是一套javascript库,用来渲染3D地球,2D区域地图,和多种GIS要素.不需要安装任 ...

  2. git排错

    解决: 将远程仓库中除.git以外的所有文件删除,然后执行   git config --bool core.bare true  然后客户端重新push即可解决问题 还要注意远程仓库权限方面...

  3. FreeRTOS的任务非运行态

    当FreeRTOS启动任务调度器以后,任务调度器会在心跳中断函数中确定下一个要运行的任务,如果任务调度器仅仅依靠任务优先级来判断该运行哪个任务,这样会造成低优先级的任务根本没法运行,因为FreeRTO ...

  4. QT QListWidget 简单的操作

    以下是简单的 listWidget 的方法的功能 listWidget = QListWidget() #实例化一个(item base)的列表 listWidget.addItem('dd') #添 ...

  5. 解决Skyline6.5多球对比时,自动运行TerraExplorer软件的问题

    如果你的操作系统是Win7 64位,在运行Skyline6.5提供的ITE3DWindowEx控件实现多球对比时,启动程序调试运行时,却自动运行了TerraExplorer软件, 这时候你会发现for ...

  6. golang 常用包安装

    常用到的: go get -v github.com/nsf/gocode go get -v github.com/rogpeppe/godef go get -v golang.org/x/too ...

  7. zookeepeer使用zkCli.sh命令

    一.连接服务器端 [root@sxl132 zookeepeer]# ./bin/zkCli. Connecting to -- ::, [myid:] - INFO [main:Environmen ...

  8. 汇编 SETG,SETL ,SETGE, SETLE指令

    一.SETG SETZ(SETE) //取ZF标志位值 放到寄存器里 SETNZ(SETNE) == > SETG //setg cl//ZF==0 并 SF==0 并 OF==0 时 cl=1 ...

  9. Scala学习(三)练习

    Scala数组相关操作&练习 1. 1. 编写一段代码,将a设置为一个包含n个随机整数的数组,要求随机数介于0(包含)和n(不包含)之间 def main (args: Array[Strin ...

  10. 大数据处理过程核心技术ETL详细介绍

    架构挑战 1.对现有数据库管理技术的挑战. 2.经典数据库技术并没有考虑数据的多类别(variety).SQL(结构化数据查询语言),在设计的一开始是没有考虑到非结构化数据的存储问题. 3.实时性技术 ...