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

举报
lxw1844912514 发表于 2022/03/27 02:24:57 2022/03/27
【摘要】 Laravel的配置加载其实就是加载config目录下所有文件配置。如何过使用php artisan config:cache则会把加载的配置合并到一个配置文件中,下次请求就不会再去加载config目录。 1.加载流程 LoadEnvironmentVariables .env环境配置加载。如果缓存...

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

1.加载流程

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

2.什么时候加载配置?

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

\Illuminate\Foundation\Http\Kernel


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

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

3. 源码分析

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

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


    
  1. public function bootstrap(Application $app)
  2. {
  3. $items = [];
  4. // 首先,我们将看看是否有缓存配置文件。 如果是,我们将从该文件加载配置项,因此它非常快。
  5. // 否则,我们需要遍历每个配置文件并加载它们。
  6. if (file_exists($cached = $app->getCachedConfigPath())) {
  7. // 加载缓存的配置文件
  8. $items = require $cached;
  9. $loadedFromCache = true;
  10. }
  11. // 接下来,我们将遍历配置目录中的所有配置文件,并将每个配置文件加载到Repository中。
  12. // 这将使开发人员可以使用所有选项,以便在此应用程序的各个部分中使用。
  13. $app->instance('config', $config = new Repository($items));
  14. // 如果没有缓存配置才会去加载config目录
  15. if (! isset($loadedFromCache)) {
  16. // 加载config目录所有PHP文件
  17. $this->loadConfigurationFiles($app, $config);
  18. }
  19. //最后,我们将根据加载的配置值设置应用程序的环境。
  20. // 我们将传递一个回调,该回调将用于在Web环境中获取环境,其中不存在“--env”开关。
  21. $app->detectEnvironment(function () use ($config) {
  22. return $config->get('app.env', 'production');
  23. });
  24. // 设置时区
  25. date_default_timezone_set($config->get('app.timezone', 'UTC'));
  26. mb_internal_encoding('UTF-8');
  27. }
  28. /**
  29. * 从所有文件加载配置项。因此效率很低
  30. *
  31. * @param \Illuminate\Contracts\Foundation\Application $app
  32. * @param \Illuminate\Contracts\Config\Repository $repository
  33. * @return void
  34. * @throws \Exception
  35. */
  36. protected function loadConfigurationFiles(Application $app, RepositoryContract $repository)
  37. {
  38. // 遍历出所有PHP文件
  39. $files = $this->getConfigurationFiles($app);
  40. if (! isset($files['app'])) {
  41. throw new Exception('Unable to load the "app" configuration file.');
  42. }
  43. // 一个一个的加载
  44. foreach ($files as $key => $path) {
  45. $repository->set($key, require $path);
  46. }
  47. }

4.小结与注意点

  1. php artisan config:cache之后不会加载config配置,即便你修改了config目录中的配置文件也是不生效的,除非清除缓存php artisna config:clear,或者重新缓存 php artisan config:cache
  2. 因为配置缓存可以提高效率,因此推荐生产环境使用配置缓存。
  3. 不能在config目录内定义配置以外的东西。比如在config目录内定义类,定义常量,自定义函数。这些都是不推荐的,因为配置缓存之后,config目录任何文件都不会加载,这些类或者常量不存在,最终导致自动加载失败。解决方案是使用composer.json的自动加载配置来加载:

    
  1. "autoload": {
  2. "classmap": [
  3. "database/seeds",
  4. "database/factories"
  5. ],
  6. "psr-4": {
  7. "App\\": "app/"
  8. },
  9. "files": [
  10. # 这样那个会加载helpers.php文件了。该文件定义的是辅助函数
  11. "bootstrap/helpers.php"
  12. ]
  13. },
  1. 在 config 中调用其他的 config('something.item') 是不会预期的加载的。因为不能保证配置something.item已经加载到了

文章来源: blog.csdn.net,作者:lxw1844912514,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/lxw1844912514/article/details/100029184

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。