Help us understand the problem. What is going on with this article?

[Laravel 5.5] 読み込む.envファイルを環境ごとに切り替える

More than 1 year has passed since last update.

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です。

bootstrap/app.php
/*
|--------------------------------------------------------------------------
| 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で指定しておけば、読み込むファイル名が変更された状態でこのクラスの処理が走ります。

/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/LoadEnvironmentVariables.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;
    }
}
fork
株式会社フォークは、Webサイトの企画・制作・開発・サーバホスティング・コンタクトセンターを一社に集約したワンストップソリューションを展開する制作会社です。
https://www.fork.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away