源码解读 Laravel PHP artisan config:cache

再来一篇源码解读系列,其实包含本篇 config:cache 源码解读在内,这三篇的源码解读都是跟线上环境部署 Laravel 项目有关,因为我们通常会使用这三个 artisan 命令来提高项目的执行效率。所以,我们进入正题:php artisan config:cache 源码解读

源码在哪

首先,我们还是可以使用编辑器的搜索功能搜 ConfigCacheCommand,这样就可以直接打开 config:cache 命令的源代码了,位于 Illuminate\Foundation\Console\ConfigCacheCommand 中,关键的代码还是位于 fire() 方法中:

public function fire(){

   $this->call('config:clear');
   // other codes
}

首先,在执行 php artisan config:cache 之前,我们需要将之前缓存过的配置文件清除,就是通过 $this->call('config:clear'); 这一行代码来实现的。

那,config:clear 的源码在哪呢?

这个命令的源码位于 Illuminate\Foundation\Console\ConfigClearCommand 中,你依然是可以在编辑器搜 ConfigClearCommand,然后定位到这里的 fire() 方法里面:

public function fire(){
   $this->files->delete($this->laravel->getCachedConfigPath());

   $this->info('Configuration cache cleared!');
}

你看,这里的代码就非常简单,主要就是删除原来缓存的配置文件,这个缓存的配置文件通过getCachedConfigPath() 获取到,这个 getCachedConfigPath()Illuminate\Foundation\Application 中:

public function getCachedConfigPath(){
   return $this->bootstrapPath().'/cache/config.php';
}

熟悉了吧,它也是放到 bootstrap/cache/ 目录下面的,命名为 config.php

那么以上就删除完缓存的配置了,然后我们再次回到 config:cache 中。既然旧的缓存已经删除,那么我们就需要生成新的缓存文件了,所以再次聚焦 ConfigCacheCommandfire() 方法:

public function fire(){

   $config = $this->getFreshConfiguration();

   $this->files->put(
            $this->laravel->getCachedConfigPath(), '<?php return '.var_export($config, true).';'.PHP_EOL
        );
}

首先 通过 getFreshConfiguration() 获取所有新的配置信息,这部分的代码逻辑就在 ConfigCacheCommand 中:

protected function getFreshConfiguration(){
    $app = require $this->laravel->bootstrapPath().'/app.php';
    $app->make(ConsoleKernelContract::class)->bootstrap();
    return $app['config']->all();
}

这三行代码很简单,就是生成了一个 Laravel 的 Application 实例,然后通过 $app['config']->all() 获取所有的配置信息。

获取配置信息之后,就把新的配置信息写入缓存中,上面 ConfigCacheCommand fire() 方法的这一行实现:

$this->files->put(
    $this->laravel->getCachedConfigPath(), 
    '<?php return '.var_export($config, true).';'.PHP_EOL
    );

getCachedConfigPath() 已经很熟悉啦,在讨论 cache:clear 时我们就知道,其实就是获取到 bootstrap/cache/config.php 文件,然后写入配置的内容 var_export($config, true),所以最后缓存的配置文件大概的内容是这样的:
config-cache.jpg

最后

有了缓存的配置文件,下次访问 Laravel 项目的时候就是直接读取缓存的配置了,而不用再次去计算和获取新的配置,这样来说,速度依然会快那么一点点。

记得关注 codecasts 公众号,定期送书,送福利
wechat_small.jpg

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 2年前 自动加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3

清晰明了.

6年前 评论

我执行完 php artisan config:config 系统无法访问,debuger 中报错

[2019-04-28 08:53:52] local.ERROR: Debugbar exception: filemtime(): stat failed for /vagrant/www/Lara-community/vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/jquery/dist/jquery.min.js  
[2019-04-28 09:02:09] production.ERROR: Call to undefined method Closure::__set_state() {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to undefined method Closure::__set_state() at /vagrant/www/Lara-community/bootstrap/cache/config.php:30)
[stacktrace]
#0 /vagrant/www/Lara-community/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/LoadConfiguration.php(28): require()
#1 /vagrant/www/Lara-community/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(213): Illuminate\\Foundation\\Bootstrap\\LoadConfiguration->bootstrap(Object(Illuminate\\Foundation\\Application))
#2 /vagrant/www/Lara-community/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(162): Illuminate\\Foundation\\Application->bootstrapWith(Array)
#3 /vagrant/www/Lara-community/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(146): Illuminate\\Foundation\\Http\\Kernel->bootstrap()
#4 /vagrant/www/Lara-community/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#5 /vagrant/www/Lara-community/public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#6 {main}
"} 
4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!