场景
- 最近在看Request Lifecycle, 在完成服务容器的实例化之后, resolve Illuminate\Contracts\Http\Kernel::class , 然后在它的handle()方法中bootstrap了一些核心的服务, 那么下面就分析
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
做了什么
分析
if ($app->configurationIsCached()) {return;}
如果配置文件缓存了 则不进行操作
$this->checkForSpecificEnvironmentFile($app);
如果定义了APP_ENV变量则将配置文件重新定义为.env'. getenv(APP_ENV')
, 如果不指定环境变量的话 则什么也做不了
(new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
读取配置文件, 配置文件默认是.env 但是在第二步可能会被改变
- Dotenv/Loader load方法
if (!$this->isComment($line) && $this->looksLikeSetter($line)) {}
配置文件中如果含有#
或者没有=
则抛掉
$this->setEnvironmentVariable($line
- $_ENV $_SERVER getenv 如果已经存在的变量 则不改变原有配置
- 如果是apache环境且环境变量已经存在 则使用配置把原有数据覆盖掉 方式是
apache_setenv($name, $value);
- 如果已经通过了上面的两个流程 则
putenv("$name=$value"); $_ENV[$name] = $value;$_SERVER[$name] = $value;
public function bootstrap(Application $app)
{
if ($app->configurationIsCached()) {
return;
}
$this->checkForSpecificEnvironmentFile($app);
try {
(new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
} catch (InvalidPathException $e) {
}
}
protected function checkForSpecificEnvironmentFile($app)
{
if ($app->runningInConsole() && ($input = new ArgvInput)->hasParameterOption('--env')) {
if ($this->setEnvironmentFilePath(
$app, $app->environmentFile().'.'.$input->getParameterOption('--env')
)) {
return;
}
}
if (! env('APP_ENV')) {
return;
}
$this->setEnvironmentFilePath(
$app, $app->environmentFile().'.'.env('APP_ENV')
);
}
总结
LoadEnvironmentVariables 依赖Dotenv/Dotenv将配置文件加载到putenv,$_ENV,$_SERVER 甚至是apache子进程中
if (! env('APP_ENV')) { return;}$this->setEnvironmentFilePath( $app, $app->environmentFile().'.'.env('APP_ENV')); 这里告诉了我们实现多环境的方法: 最简单的修改php.ini APP_ENV=dev