前情提要
一般程序至少都会有开发、测试、生产三个环境。我一般习惯有.env、.env.test、.env.production 三个文件
如果每次被动的去相应的环境修改env配置的话,是一件很麻烦的事情
nginx配置
# example.conf
# 见 fastcgi_param 参数
location ~ \.php$ {
fastcgi_pass php72:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param APP_ENV production;
}
lumen下的使用
# bootstrap/app.php
require_once __DIR__.'/../vendor/autoload.php';
# 配置env文件
$environment = env('APP_ENV', false);
$environment_file = !env('APP_ENV', false) ? '.env' : ".env.$environment";
(new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
dirname(__DIR__), $environment_file
))->bootstrap();
laravel下的使用
laravel下使用无需进行配置, 具体原因见如下分析
原理分析
其实 lumen 和 laravel 加载 env 的配置都差不多,主要可见 Dotenv\Dotenv
类, 从而读取配置信息
在lumen
中依赖的启动方式在主要在app.php
中
(new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
dirname(__DIR__)
))->bootstrap();
我们可以看到 加载 env file 和 env path,是直接进行初始化的
public function __construct($path, $name = null)
{
$this->filePath = $path;
$this->fileName = $name;
}
我们再来看下laravel的
# 启动器
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
# 这里实现一个单例: 重要之处
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
完成后返回一个app, 在public/index.php
它会先从容器中解析出类实例
Illuminate\Contracts\Http\Kernel::class
对应
App\Http\Kernel::class
解析后
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
# 执行handle方法
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
handle方法是怎么来的呢,见App\Http\Kernel::class
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel{
...
}
我们发现在 Kernel 没有handle这个方法,所以这里执行的handle是父方法的handle : Illuminate\Foundation\Http\Kernel
# step1
$response = $this->sendRequestThroughRouter($request);
# step2
$this->bootstrap();
# step3
$this->app->bootstrapWith($this->bootstrappers());
# 注:
$this->bootstrappers = [
'Illuminate\Foundation\Bootstrap\DetectEnvironment',
'Illuminate\Foundation\Bootstrap\LoadConfiguration',
'Illuminate\Foundation\Bootstrap\ConfigureLogging',
'Illuminate\Foundation\Bootstrap\HandleExceptions',
'Illuminate\Foundation\Bootstrap\RegisterFacades',
'Illuminate\Foundation\Bootstrap\RegisterProviders',
'Illuminate\Foundation\Bootstrap\BootProviders'
];
所以得到了我们的DetectEnvironment
从而具体的解析方法见
protected function checkForSpecificEnvironmentFile($app)
{
if (! env('APP_ENV')) {
return;
}
# $app->environmentFile() : .env
# env('APP_ENV') = 'production'
$file = $app->environmentFile().'.'.env('APP_ENV');
if (file_exists($app->environmentPath().'/'.$file)) {
$app->loadEnvironmentFrom($file);
}
}
但我们在nginx中配置了 app_env的值的时候,它会自动进行拼接得到这个env file, 最后的结果为 .env.production
命令行下的使用
# 执行artisan命令
APP_ENV=production && php artisan test
参考文章:
laravel中env文件的加载: https://www.jianshu.com/p/0370072a6023
Laravel源码入门-启动引导过程:https://my.oschina.net/zhmsong/blog/900617
通过nginx的fastcgi_param来设置环境变量:https://www.cnblogs.com/gantoday/p/7465097.html
Laravel 启动流程分析 (代码全流程):
https://learnku.com/articles/19878
make使用文档: https://learnku.com/docs/laravel/7.x/container/7454#the-make-method
本文由 邓尘锋 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Mar 22, 2021 at 04:48 pm