laravelのenv()について

Laravelのdatabase.phpなどを見ていると下記のような記述をよく見かけます。

    'default' => [
        'host' => env('REDIS_HOST', 'localhost'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],

この env() がなんなのか気になったので調べてみました。

laravelのコアを読みに行くとSupportディレクトリの下のhelpers.phpの中に、下記のような記述があります。(今回は5.5で調べました)

Illuminate/Support/helpers.php

if (! function_exists('env')) {
    /**
     * Gets the value of an environment variable.
     *
     * @param  string  $key
     * @param  mixed   $default
     * @return mixed
     */
    function env($key, $default = null)
    {
        $value = getenv($key);

        if ($value === false) {
            return value($default);
        }

laravelのhelperの中で定義されていたのですね...

ちなみに、laravel5.0だと Foundation/helpers.php の中に定義されています。

ついでに、このhelpers.phpってどこで読んでるんだ?っと思って調べてみたところ、同じSupportディレクトリのcomposer.jsonで読み込まれていました。

Illuminate/Support/composer.json

    "autoload": {
        "psr-4": {
            "Illuminate\\Support\\": ""
        },
        "files": [
            "helpers.php"
        ]
    },

composer.jsonのautoloadでは、事前に読み込んでおきたいファイルなどを定義し、読み込むことができます。 詳しくはこちらの記事がおすすめです。

qiita.com

余談

laravelでは、Redisのdbは0で定義されています(redis側がデフォルトで0を使うからこちらも0にしているのかな?)。

そのため、下記のようにRedisのDBもenvに変数として定義してみました!

    'default' => [
        'host' => env('REDIS_HOST', 'localhost'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => env('REDIS_DB', 0),
    ],

うまく行く!と思ったが、ところがどっこいそうは問屋がおろしませんでした。アプリ落ちちゃった...

原因を調べたところ、0がenv関数のkeyとして渡った場合、""が帰ってくるからです...""じゃredisのdbを指定できませんね...

コントローラ

dd(env('REDIS_DB', 1));

envの中身

REDIS_DB=0

ddの結果

""

もう少し追ってみる

helperの中に下記のように記述して追って見ます。

    function env($key, $default = null)
    {
        if($key == 'REDIS_DB') {
            dd($key, getenv($key));
        }

ddの結果

"REDIS_DB"
""

こっから先は下記のリポジトリを追っていけばいいと思うのですがここで気力が尽きたのでまた今度...

GitHub - vlucas/phpdotenv: Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.

教訓

とりあえず、0はenvの変数にいれないでおこう...