2通りの方法
方法1 サーバー環境変数APP_ENVを設定しておく。
方法2 bootstrap/app.phpで、loadEnvironmentFromメソッドで読み込む.envファイルを指定する。
どちらにしても、各環境用の.envを用意しておきましょう。
- .env (ローカル用)
- .env.dev (開発環境用)
- .env.stg (ステージング環境用)
- .env.prod (本番環境用)
また以下の例は全てapacheサーバですが、nginxでも同じことができます。
[方法1] サーバー環境変数で切り替える
各環境の.htaccessで環境変数を設定しておきます。本番環境なら
SetEnv APP_ENV prod
SetEnvIfを使用すれば各環境ごとに.htaccessを変えなくてすみます。
SetEnvIf Host "production.co.jp" APP_ENV=prod
SetEnvIf Host "staging.co.jp" APP_ENV=stg
SetEnvIf Host "development.co.jp" APP_ENV=dev
APP_ENVの値によって、読み込む.envファイルが変わります。
[方法2] loadEnvironmentFromメソッドで切り替える
bootstrap/app.phpで読み込むファイルを指定しておくと、サーバー環境変数がなくてもOKです。
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
/*
|--------------------------------------------------------------------------
| 環境によって読み込む.envファイル切り替え
|--------------------------------------------------------------------------
*/
switch ($_SERVER['SERVER_NAME'] ?? 'localhost') {
case 'development.co.jp':
$app->loadEnvironmentFrom('.env.dev');
break;
case 'staging.co.jp':
$app->loadEnvironmentFrom('.env.stg');
break;
case 'production.co.jp':
$app->loadEnvironmentFrom('.env.prod');
break;
}
artisanコマンドを使うとき
artisanコマンドを使用するときは、読み込む.envファイルを--envオプションで指定しなければなりません。
.env.stgを読み込ませるには以下のようにします。
$ php artisan migrate --seed --env=stg
指定しないと、デフォルトである.envが読み込まれます。
[補足] どのように切り替えられているのか
コアのLoadEnvironmentVariables.phpで.envファイルの読み込みが行われていますが、サーバー環境変数の有無で読み込むファイル名を変更しています。
loadEnvironmentFromメソッドは、自由に読み込むファイル名を指定できるメソッドです。bootstrap/app.phpで指定しておけば、読み込むファイル名が変更された状態でこのクラスの処理が走ります。
<?php
namespace Illuminate\Foundation\Bootstrap;
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
use Symfony\Component\Console\Input\ArgvInput;
use Illuminate\Contracts\Foundation\Application;
class LoadEnvironmentVariables
{
/**
* Bootstrap the given application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public function bootstrap(Application $app)
{
if ($app->configurationIsCached()) { // キャッシュされているとそもそも.envを読みに行かない
return;
}
// コンソールから実行されているのか、サーバー環境変数がセットされているかチェックする
$this->checkForSpecificEnvironmentFile($app);
try {
// .env か .env.{APP_ENV} か loadEnvironmentFrom()で指定したファイルを読み込む
(new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
} catch (InvalidPathException $e) {
//
}
}
/**
* Detect if a custom environment file matching the APP_ENV exists.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
protected function checkForSpecificEnvironmentFile($app)
{
// artisanコマンドの時はここで判別される
if ($app->runningInConsole() && ($input = new ArgvInput)->hasParameterOption('--env')) {
if ($this->setEnvironmentFilePath(
$app, $app->environmentFile().'.'.$input->getParameterOption('--env')
)) {
return;
}
}
if (! env('APP_ENV')) { // サーバー環境変数が設定されてなければreturn
return;
}
$this->setEnvironmentFilePath( // 読み込み先を.env.{APP_ENV}とする
$app, $app->environmentFile().'.'.env('APP_ENV')
);
}
/**
* Load a custom environment file.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param string $file
* @return bool
*/
protected function setEnvironmentFilePath($app, $file)
{
if (file_exists($app->environmentPath().'/'.$file)) {
$app->loadEnvironmentFrom($file);
return true;
}
return false;
}
}