前情提要
一般程式至少都會有開發、測試、生產三個環境。我一般習慣有.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檔案的載入: www.jianshu.com/p/0370072a6023
Laravel原始碼入門-啟動引導過程:my.oschina.net/zhmsong/blog/900617
通過nginx的fastcgi_param來設定環境變數:www.cnblogs.com/gantoday/p/7465097...
Laravel 啟動流程分析 (程式碼全流程):
部落格:Laravel 啟動流程分析 (程式碼全流程)
make使用文件: 服務容器《Laravel 7 中文文件》
本作品採用《CC 協議》,轉載必須註明作者和本文連結