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已經加載到了
