Hiroto's diary

プログラミングとか色々

JSONにコメントを書く時や、JSON5を書く時はJavaScriptでハイライトすると便利。

たまに役に立つかもしれないライフハックです。

コメント入りのJSONJSONでハイライトすると色々残念

設定などの説明でJSONにコメントを入れた時、普通にJSONシンタックスハイライトをさせると、残念な感じになります。

{
    // presetの設定
    "presets": [
        "@babel/preset-env"
    ],
    // compactオプションを使わない
    "compact": false
}

JSON5で書いた物をJSONでハイライトさせると、こっちは更に残念な感じに。

{
    // presetの設定
    presets: [
        '@babel/preset-env',
    ],
    // compactオプションを使わない
    compact: false,
}

JavaScriptでハイライトするといい感じに

こういう時はJavaScriptでハイライトさせると色々いい感じになります。

{
    // presetの設定
    "presets": [
        "@babel/preset-env"
    ],
    // compactオプションを使わない
    "compact": false
}

JSON5の例。

{
    // presetの設定
    presets: [
        '@babel/preset-env',
    ],
    // compactオプションを使わない
    compact: false,
}

Laravel の .env の値は config() 経由で使う

TL;DR

  • env()は コントローラー, モデル, etc.. 内で直接使わない。
  • config/*.phpenv()の値を入れてconfig()から参照する。

<?php
// config/my-app.php

return [
    // configに.envの内容を入れる。
    'my-env' => env('MY_ENV'),
];
<?php
// コントローラー内など

// config() を使用。
$my_env = config('my-app.my-env');

// これはダメなパターン。
$my_env = env('MY_ENV');

何故 env() を使ってはいけないのか

本番環境でconfig:cacheコマンドを実行した際、.envファイルを読み込まないから。

.envファイルはIlluminate\Foundation\Bootstrap\LoadEnvironmentVariablesクラスのbootstrap()で読み込まれるのですが、読み込む前にconfigのキャッシュの有無を確認し、キャッシュがあった場合は.envファイルを読み込まない仕様になっています。

当該部分のLaravelのコードを引用。

<?php
// 省略

    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());
        }
    }

// 省略

github.com

大体の場合の本番環境では、高速化の為に設定を一纏めにするconfig:cacheコマンドを実行すると思うのですが、前述の通りキャッシュがあると.envが読み込まれないので、env()を直接叩いてると開発時やテスト時には動くけど本番環境で死ぬ。といった事になります。(実際なった)

実際に試す

適当なコントローラーを用意してddを使って値をダンプするだけ。

<?php
class HogeController extends Controller
{
    public function getHoge()
    {
        dd(
            env('MY_ENV'),
            config('my-app.my-env')
        );
    }
}

まずはキャッシュ無しでアクセス。

"Foo"

"Foo"

テスト環境や開発環境と同じ様にキャッシュを作成していないのでどちらも同じ値が取得できます。

次にキャッシュさせてアクセス。artisanconfig:cacheを実行してbootstrap/cache/config.phpを作成します。

php artisan config:cache

で、先ほどと同じ様にアクセスしてみる。

null

"Foo"

.envファイルが読み出されていないのでenv()で取得した所で値が入ってる訳もなくnullを返します。


と言う訳で最初に書いた通り、env()は直接使わずにconfig().envの値を入れて使いましょう

© 2015 hiroxto