我又掉 Laravel env 函式坑裡了

overtrue發表於2017-07-05

哈哈,最近踩坑比較多啊,不過這次真的怪自己不細心看文件了。
事情是這樣的,今天發現專案在執行定時任務的時候報錯了,faild_jobs 中塞了好多錯誤記錄,一看內容全是 "JUHE_APPKEY_FOR_XXXX is null",這是我的物流查詢 Job 裡丟擲的異常,當用 env('JUHE_APPKEY_FOR_XXXX') 讀取 app_key 為空時就會丟擲。但是 .env 裡明明配置了就是沒有。

其實之前出現過一回,但是由於沒有固定重現也就沒有重視這事兒,今天終於花時間去搞定了,花了半小時終於鎖定了重現步驟:config:cache 後就肯定讀不到了,config:clear 後就可以了,當然這裡有一個前提,呼叫 env 函式的地方是在業務程式碼裡,而非 config/* 檔案中。

然後我去翻了一下文件,發現其實在 Laravel 的 5.2 升級日誌中有這麼一段:

If you are using the config:cache command during deployment, you must make sure that you are only calling the env function from within your configuration files, and not from anywhere else in your application.

If you are calling env from within your application, it is strongly recommended you add proper configuration values to your configuration files and call env from that location instead, allowing you to convert your env calls to config calls.

其實就是下面這段程式碼的意思,相信聰明的你一眼就看懂了:

file

這是框架核心啟動檔案類 Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::boot 方法,從 20 行我們可以發現,一旦快取了配置以後,就不會再從 .env 檔案載入內容了,所以你在業務程式碼中使用 env 函式時已經無法讀取 .env 中設定的內容了,但是其它環境變數不影響哦。那為啥配置檔案的可以呢?因為配置檔案快取的時候會載入 .env 然後讀取值快取配置內容。

那怎麼辦呢?上面的官方說明已經告訴我們了:在配置檔案建立對應的配置項,比如我們第三方服務可以放到 config/services.php 中,在配置裡使用 env 讀取,然後把從 env 函式讀取的地方改成 config('services.juhe.app_key') 這樣來避免這個問題。

其實作者這樣做是有道理的,畢竟 .env 檔案是文字內容,解析它的成本還是挺高的。所以請小心不要入這個坑哦。

相關文章