深入理解 Laravel 中 config 配置加载原理
Laravel的配置加载其实就是加载config目录下所有文件配置。如何过使用
php artisan config:cache则会把加载的配置合并到一个配置文件中,下次请求就不会再去加载config目录。
1.加载流程
LoadEnvironmentVariables.env环境配置加载。如果缓存配置是不会加载.env的LoadConfiguration判断是否缓存配置- 是,则直接加载配置,不会加载config目录所有文件了
- 否,则加载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.小结与注意点
php artisan config:cache之后不会加载config配置,即便你修改了config目录中的配置文件也是不生效的,除非清除缓存php artisna config:clear,或者重新缓存php artisan config:cache- 因为配置缓存可以提高效率,因此推荐生产环境使用配置缓存。
- 不能在config目录内定义配置以外的东西。比如在config目录内定义类,定义常量,自定义函数。这些都是不推荐的,因为配置缓存之后,config目录任何文件都不会加载,这些类或者常量不存在,最终导致自动加载失败。解决方案是使用composer.json的自动加载配置来加载:
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
},
"files": [
# 这样那个会加载helpers.php文件了。该文件定义的是辅助函数
"bootstrap/helpers.php"
]
},
- 在
config中调用其他的config('something.item')是不会预期的加载的。因为不能保证配置something.item已经加载到了
深入理解 Laravel 中 config 配置加载原理的更多相关文章
- Django中模块的加载原理
Django中的module的加载是通过反射来完成的,借助importlib中的import_module函数来实现的动态加载.import_module的内部通过使用了递归和线程锁,字符串的切割,实 ...
- 通过源码浅析Java中的资源加载
前提 最近在做一个基础组件项目刚好需要用到JDK中的资源加载,这里说到的资源包括类文件和其他静态资源,刚好需要重新补充一下类加载器和资源加载的相关知识,整理成一篇文章. 理解类的工作原理 这一节主要分 ...
- springcloud项目配置拓展从本地config目录加载
本文受阿里开源的Nacos启发,应用启动后从Nacos服务加载配置到应用中,想着本地开发的时候加载配置能否从本地存储中加载,这样也能加快开发效率 首先我们来看下SpringCloud项目应用Nacos ...
- Mybatis源码解读-SpringBoot中配置加载和Mapper的生成
本文mybatis-spring-boot探讨在springboot工程中mybatis相关对象的注册与加载. 建议先了解mybatis在spring中的使用和springboot自动装载机制,再看此 ...
- 【Dubbo源码阅读系列】之 Dubbo XML 配置加载
今天我们来谈谈 Dubbo XML 配置相关内容.关于这部分内容我打算分为以下几个部分进行介绍: Dubbo XML Spring 自定义 XML 标签解析 Dubbo 自定义 XML 标签解析 Du ...
- Log4j2源码分析系列:(一)配置加载
前言 在实际开发项目中,日志永远是一个绕不开的话题.本系列文章试图以slf4j和log4j2日志体系为例,从源码角度分析日志工作原理. 学习日志框架,首先要熟悉各类日志框架,这里推荐两篇文章,就不再赘 ...
- 理解Laravel中的pipeline
理解Laravel中的pipeline suoga 关注 0.1 2015.09.08 00:00* 字数 1533 阅读 7151评论 8喜欢 24 pipeline在laravel的启动过程中出 ...
- Spring Cloud Nacos实现动态配置加载的源码分析
理解了上述Environment的基本原理后,如何从远程服务器上加载配置到Spring的Environment中. NacosPropertySourceLocator 顺着前面的分析思路,我们很自然 ...
- 关于flume配置加载
最近项目在用到flume,因此翻了下flume的代码, 启动脚本: nohup bin/flume-ng agent -n tsdbflume -c conf -f conf/配置文件.conf -D ...
随机推荐
- Qt+Qgis二次开发:地理实体抽象
1 概述 地理实体抽象是指点.线.面及其组合而成的,用于描述实际地物的数据结构. 其中包含几何实体和属性数据. GIS中进行几何操作,以各种实体类为基础进行操作. 在OGC中,地理实体可以由WKT表 ...
- PAT A1126 Eulerian Path (25 分)——连通图,入度
In graph theory, an Eulerian path is a path in a graph which visits every edge exactly once. Similar ...
- 【Codeforces 650 D】Zip-line
题意:给一个序列以及\(n\)个查询,每一个查询是问(假装)把第\(a_i\)个数改为\(b_i\)之后原序列的最长上升子序列的长度. 思路:线段树优化\(dp\). 肯定离线做啊. 首先我们考虑\( ...
- 【Codeforces 526D】Om Nom and Necklace
Codeforces 526 D 题意:给一个字符串,求每个前缀是否能表示成\(A+B+A+B+\dots+A\)(\(k\)个\(A+B\))的形式. 思路1:求出所有前缀的哈希值,以便求每个子串的 ...
- Android学习之基础知识九 — 数据存储(持久化技术)之使用LitePal操作数据库
上一节学习了使用SQLiteDatabase来操作SQLite数据库的方法,接下来我们开始接触第一个开源库:LitePal.LitePal是一款开源的Android数据库框架,它采用了对象关系映射(O ...
- Android学习之六种事件响应方法汇总
java源码如下: 1.MainActivity.java源码 package com.example.responsetest; import android.app.Activity; impor ...
- arcgis_js_api_3.12的project实践
esri.config.defaults.geometryService = new esri.tasks.GeometryService("http://localhost:6080/ar ...
- Oracle ORA-14102: 只能指定一个 LOGGING 或 NOLOGGING 子句
oracle 11g ,在通过命令impdp向一个数据库用户导入数据时,出现错误: ORA-14102: 只能指定一个 LOGGING 或 NOLOGGING 子句 造成此问题的原因是:当导入的表里没 ...
- 源码分享篇:使用Python进行QQ批量登录
直接上源码 1 #coding=utf-8 2 __author__ = 'Eagle' 3 import os 4 import time 5 import win32gui 6 import wi ...
- CDH hive-1.1.0-cdh5.10.0 安装
又重新安装Hive,记录一下吧: hadoop早已经装上了. cdh5的hive下载地址: http://archive.cloudera.com/cdh5/cdh/5/ 下载文件:hive-1.1. ...