return env('AWS_URL');
env を直接参照していた箇所が、ある日突然値を返さなくなった。最初は env が読めていないとは思わず、別の箇所を疑ってしまって少し遠回りしてしまった。
調べてみると、config:cache を有効化した途端に env() が値を返さなくなるという Laravel の仕様があったらしいので、軽く調べてみた。
php artisan config:cache
これを「config の設定値を更新するときに打つコマンド」くらいにしか理解していなかったが、実際には以下の処理を行っている。
-
config/*.phpを全部読み込む - env の値もこのときだけ読み込んで取り込む
- まとめて
bootstrap/cache/config.phpに保存する
→ 以降は env() を一切見に行かず、config キャッシュだけを参照する。
そのため、キャッシュを有効化している環境だと env() は基本的に null を返す。
Laravel 的にはenvを直接読まないことが前提らしいなので、これはもうそういうものだと扱うしかないのだけど、じゃあ「警告くらい出してくれよ!」とはおもったり……
Laravel は通常、リクエストを受けるたびに
- 複数の config ファイルを読み込む
- env をパースする
という処理を行う。これが意外と重いらしく
config:cache によってこれらを デプロイ時の 1回だけに置き換えることで
「巨大な配列をひとつ読み込むだけ」
という高速な形にしている。
なぜ Laravel は env() を直接使うことを非推奨にしているのか
1. env は設定ファイルを生成するための材料でしかない
env の値は環境によって変わるため、アプリ本体が直接読むと本番だけ挙動が変わる事故が起きやすい。
2. 読み取りタイミングが不安定
env() はキャッシュ前後で参照可否が変わるため、使用箇所が混在すると再現性の低いバグが起きる。
3. 責務の分離
env は「入力値」、config は「アプリが読むべき確定した値」で、それぞれ役割が違う。
- 環境差分をコードの外に逃がすのが env
- アプリから安全・安定して参照するための入口が config
という分担になっている
config:clear の補足
php artisan config:clear
でキャッシュを削除できるコマンドがあるけど、実際には
php artisan config:cache
を再実行するだけでキャッシュは上書き更新されるし、最新の設定を反映させたいだけならほとんどこちらだけで十分。
開発中に「いったんキャッシュを完全に消したい」ときだけ config:clear を使うことが多い。