【Laravel】 envメソッドで環境変数が取得できず、nullになるときの対処法を紹介!

Laravel

開発環境ではenv()で”.env”の値を取得できていたのに、別の環境にデプロイした途端にnullしか返ってこない!?

「どうすれば環境変数が取得できる?」とお悩みの方は、一度下記の内容を試してみてください。

値が取得できない原因は、デプロイ先の環境でartisan config:cacheを実行していたことだったのですが、このことを知らないと何が原因かわからず、ハマること間違いなしなので、どうすれば環境変数が取得できるようになるかをまとめておきたいと思います。

Laravelで.envから環境変数を取得する際に使用するヘルパー関数の”env()”ですが、artisan config:cacheを使用した状態で、コマンド等でこの関数を呼び出すと、値が取得できなくなります。

下記は.envをロードするIlluminate\Foundation\Bootstrap\LoadEnvironmentVariablesの一部ですが、“artisan config:cache”を実行済みの場合、”$app->configurationIsCached()”がtrueになるため、Dotenvによる.envの読み込み処理が実行されません。

ちなみに、$app->configurationIsCached()bootstrap/cache/config.phpが存在しているかをチェックしています。


class LoadEnvironmentVariables
{
    /**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app)
    {
        if ($app->configurationIsCached()) {
            return;
        }

        $this->checkForSpecificEnvironmentFile($app);

        try {
            (new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
        } catch (InvalidPathException $e) {
            //
        } catch (InvalidFileException $e) {
            die('The environment file is invalid: '.$e->getMessage());
        }
    }

それではartisan config:cacheを使用している場合に.envの値をどうやって取得すれば良いのかということですが、ヘルパー関数のconfig()を使用します。

config()はconfigディレクトリ配下のPHPファイルを読み込んで使用しますが、その中でenv()を使用することで、config:cacheを実行済みの場合にも.envの値を取得できるようになります。

Laravelのデフォルトのconfigファイルも同じようにenv()を取得していて、例えばconfig/database.phpでは、下記のようにしてDB_CONNECTIONを取得しています。

  • .env

DB_CONNECTION=sqlite
  • config/database.php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Database Connection Name
    |--------------------------------------------------------------------------
    |
    | Here you may specify which of the database connections below you wish
    | to use as your default connection for all database work. Of course
    | you may use many connections at once using the Database library.
    |
    */

    'default' => env('DB_CONNECTION', 'mysql'),
  • 呼び出し側

config('database.default')
// sqlite

.envの値を使用する場合は、configファイルを作成してその中でenv()を使用し、呼び出し側ではconfig()を使うようにした方が安全ですね。