LoginSignup
7
3

More than 3 years have passed since last update.

Class env does not exist に悩まされたときに読む書

Last updated at Posted at 2019-08-15

何が起こったか

image.png

ある日突然、Laravelのすべてのセッション開始時に
Class env does not exist というエラーを吐いて全機能が停止した。

すごいのは、WEBだけでなくコンソールも動かない。
それどころかcomposerもまともに動かない。

直接の原因は、
サービスコンテナに env として登録されているはずのインスタンスが
見つからない、というエラー。

いったい何をやらかしたのだろうか?

類型

Class config does not exist とか、
Class view does not exist とか。

結論

原因1 composerでやらかしましたよね?

ある日突然このような事態になることはほぼありません。
絶対に何かやらかしているはず。
ほら、今インストールしたモジュール、とりあえずそれを除去するか、
個別に対策するか、
composer dump-autoloadで解決することもあるようです。

参考 [小ネタ]LaravelにTelescopeを追加したら、PHP Unitでエラーが出たときの対応

原因2 .envが壊れている

.envファイルを削除して状況が変わるか試しましょう。

原因3 ->enviroment() が早すぎる

アプリケーション内でこのメソッドを使っているところを探して、下記のように修正してください。

BEFORE
if ($this->shouldReport($exception) && app()->environment('prod')) {
AFTER
if ($this->shouldReport($exception) && app()->bound('env') && app()->environment('prod')) {

原因4 まったく関係ない

一番最初に聞きたかったこと。
それは、直接の原因は、サービスコンテナやenvとは全く関係ないことがある、ということ。

Class env does not exist本来のエラーを隠している、全然関係ないエラー。

なのでとりあえず本来のエラーに登場していただきましょう。
こうします。

app\Exceptions\Handler.php
    // このメソッドを追加
    public function render($request, Exception $exception)
    {
        // メソッドがすでにあるなら↓この1行を追加
        dd($exception);
        return parent::render($request, $exception);
    }

image.png

あーー! AWS SDKのインストールに失敗していたのか!!

#今回のケースでは config/aws.php でクラスの参照に失敗していたのが本来のエラーでした。

解説

なぜこんなエラーが出るかというと
「サービスプロバイダーの初期化」などという極めて初期段階では
まだサービスコンテナのインスタンスが用意されていません。

でもエラーハンドラはもっと初期で活動開始するので、
その後起きたエラーは標準のエラーハンドラがキャプチャします。

で、そのエラーハンドラが何をしているかというと

vendor\laravel\framework\src\Illuminate\Foundation\Bootstrap\HandleExceptions.php
        // あー、env使ってるわ
        if (! $app->environment('testing')) {
            ini_set('display_errors', 'Off');
        }
vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php
        // そうだよね、view使うよね
        view()->replaceNamespace('errors', [
            resource_path('views/errors'),
            __DIR__.'/views',
        ]);

なので、こういった箇所で env が無いとか、 view がないといったエラーが発生し、
本来のエラーが捨て置かれてしまうようです。

同様に、エラーハンドラ内で ->enviroment()app('xxx') といった感じに
サービスコンテナ系を触っていると、同じ現象が起こります。

エラーハンドラ内で ->enviroment() するときには、app()->bound('env') も併用して、
envが初期化されているか確認、エラーが起こらないようにしましょう。

感想

これだけのことに、2時間以上はまってしまい、穴埋め係根性で勢いのままに執筆させていただきました。

エラーの原因と対策は一概にコレ!とはなかなか言えませんが、その解決の一助になっていただければ幸いです。

こんな記事も書いています

Laravelのちょっとマニアックな視点から、誰も書かない記事を書いています(笑
合わせてご覧いただけると幸いです(^^)

ヘルパ関数とファサード

サービスコンテナ講座

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3