見出し画像

Laravelのクラス読み込みエラーを解決する

タイトルでLaravelと書いてありますがPHP,Composerを使う場合でも同じことが言えます。

問題提起

今回解決する問題なのですがこう言った問題です。

スクリーンショット 2020-12-05 20.22.58

[]の部分が変わったエラーに出くわしたことないですかね?例えば Target class [App\Http\Controllers\〇〇Controller] does not exist と言ったものです。エディタの機能も豊富になってきていたりartisanコマンドでファイルを生成するとこう言ったミスは防ぐことができるとは思いますがそれでも自分で1から書いていたりするとよく起きる気がします。

とりあえずよくある考えられる原因を2つほど紹介します。基本的に解決法①で解決すると思います。解決法②に関しては解決法①の条件を解決していることが前提条件です。

解決法①

名前間違えていませんか?Composer2からphpファイル名、その中のクラス名が異なっていれば無視されてしまいます。

Class Fuga\Production\Hoho located in ./fuga/Production/Hoge.php does 
not comply with psr-4 autoloading standard. Skipping.

* このログの出し方については↓のポイントをみてください

その場合エラーとしてはこう言った形になると思います。この場合クラス名はHohoになっているのですがファイル名はHoge.phpとなっていることがわかると思います。

Class Fuga\Production\fuga located in ./fuga/Production/Fuga.php does
 not comply with psr-4 autoloading standard. Skipping.

クラス名はfugaになっていますがファイル名はFuga.phpになっています。大文字、小文字も区別されるので気をつけて見てください。


またこれを治した場合であってもまだエラーが治らない時があります。以下も確認してください

・クラス名・ファイル名を治した時、そのクラスに依存している(そのクラスを使っている)クラスでのuseも直しましたか?

・use以外の場合はクラスの先頭にバックスラッシュ"\"をつけていますか?

        $this->app->bind(
           \Fuga\FugaInterface::class,
           \Fuga\Production\Fuga::class
       );

Laravelのサービスプロパイダでの例ですが先頭に\がないとクラスを読み込むことができません。


ポイント

ログについてですが 

composer dump-autoload

と打つとクラスが全て確認され、無視された場合は↑のようなログが出てきます。そこで示されたクラス、ファイルは無視されているのでもし問題がある場合はそのファイル名、クラス名が一致しているか確認してください!


解決法②

そのクラスそもそも読み込み対象に入っていますか?

例えばLaravelでappディレクトリの外にクラスを作る必要があるとしましょう。実はこの場合解決法①で解決を試みても解決しませんしなんならファイル名、クラス名が違っていてもログに書かれてある忠告すら出ません。実はそれ読み込まれてないです。Laravelと言うよりPHPで1から何かを作っているときにはよく起こるかもしれないですね。

結論から言うとcomposer.jsonにautoload設定をしてください

具体的な方法についてですがcomposer.jsonに以下のようは箇所はないですか?

    "autoload": {
       "psr-4": {
           "App\\": "app/",
           "Fuga\\":"fuga/",
           "Database\\Factories\\": "database/factories/",
           "Database\\Seeders\\": "database/seeders/"
       }
   },

Laravelの場合はバージョンによりますが上3行が書かれているものがあると思います。(上のコードはLaravel8で生成されたものです)これによってファイル名はappでnamespaceをAppにすることが可能になっていて自動的に読み込まれています!

PHPを生で書いている場合などはこの項目が追加されていないと思うので追加してください

    "autoload": {
       "psr-4": {
           
       }
   },

ではどのように追加すれば良いかですが少し↑でも示されているように追加した分を追加してください。左側がnamespace、右側がディレクトリ名に対応しています。つまり 

 "Fuga\\":"fuga/",

この場合Fugaというnamespaceで使用し、ディレクトリはfuga以下と言った感じで自動的に読み込んでくれるようになります。


注意

composer.jsonを書き換えるとすぐに反映されるわけではありません。上のポイントでも触れたのですが以下のコマンドを打って再読み込みさせてください。

composer dump-autoload

もちろんここで解決法①の条件で引っかかってしまう場合はまたファイル名・クラス名を治してください。


まとめ

どちらかで解決したでしょうか?意外かもしれませんが解決法①の不注意でどこかに間違いがあることがほとんどだと思います。これ以外に考えられる原因があれば教えていただければ幸いです!


この記事が気に入ったらサポートをしてみませんか?