Laravel『Class Not Found』エラーの原因と対処法

Laravel『Class Not Found』エラーの原因と対処法

Laravelで「Class ‘XXX’ not found」や「Target class [XXX] does not exist」といったエラーが出るときは、クラスの名前空間やuse宣言、ファイル配置とオートロード設定のズレが原因になっていることが多い。ルーティングやコントローラの指定ミス、configのエイリアスやサービスプロバイダの記述ミス、artisan コマンド実行時のクラス名の間違いなど、場面ごとにパターンがあるので、一つずつ潰していくと解決しやすい。

エラー内容と発生する典型的なシーン

最初に、実際に出るメッセージの例と、どういう場面で発生しやすいかを整理しておく。

Class 'App\Services\UserService' not found
Class 'Foo\Bar\Hoge' not found
Target class [UserController] does not exist.
Class 'App\Http\Controllers\Auth\LoginController' not found
Class 'CreateUsersTable' not found

典型的な発生条件は次の通り。

・ルートやコントローラで指定したクラス名が、実際の名前空間・クラス名と一致していない

・クラスファイルはあるが、namespace 宣言や use 宣言が間違っている

・ファイルを作ったのに composer dump-autoload をしておらず、オートロードに反映されていない

・config/app.php の aliases / providers に記述したクラス名が誤っている

・artisan コマンドからクラスを指定するときに、名前空間を省略/間違えている

名前空間(namespace)とuse宣言のミスマッチ

LaravelではPSR-4オートロードに従い、クラスには必ず namespace が付く。ファイル先頭の namespace と、呼び出し側の use 宣言が噛み合っていないと「Class Not Found」になる。

例えば、サービスクラスを作ったつもりで次のようになっている場合。

<?php

// ファイル: app/Services/UserService.php
namespace App\Service;   // ← Service(単数)になっている

class UserService
{
    //
}

呼び出し側でこう書くとエラーになる。

use App\Services\UserService;  // ← Services(複数)を指定している

$userService = new UserService();  // Class 'App\Services\UserService' not found

対処はどちらかに合わせるだけ。

// 正: namespace と use を揃える
namespace App\Services;

class UserService
{
    //
}

Controller・FormRequest・Job・Listener・Eventなど、artisanで作成したクラスは基本的に正しい namespace が付くが、手動作成したクラスやフォルダ移動したクラスは namespace を見直すと改善することが多い。

LaravelのPSR-4オートロードとディレクトリ構造のズレ

composer.json には、どのディレクトリがどの namespace に対応するかが PSR-4 で定義されている。

"autoload": {
    "psr-4": {
        "App\\": "app/"
    }
}

この場合、

・App\Foo\Bar\Baz クラスは app/Foo/Bar/Baz.php に置く必要がある。

例えば次のように配置してしまうと、クラスは見つからない。

# NG な構成例
app/
  Services/
    User/
      UserService.php   # 中身のnamespaceが App\Services\UserService になっている

この場合、PSR-4に従うなら namespace もディレクトリ構造に合わせる。

<?php

// ファイル: app/Services/User/UserService.php
namespace App\Services\User;

class UserService
{
    //
}

呼び出し側。

use App\Services\User\UserService;

「ファイルのパス」と「namespace+クラス名」がPSR-4のルール通りになっているかを確認するのがポイント。

composer dump-autoload を忘れている(クラス追加直後のエラー)

composer のオートロードは、クラスマップを元にクラスを解決する。新しいクラスを作成したあと、オートロード情報が更新されていないと、クラスが存在していても「Class Not Found」となることがある。

特に、composer.json の autoload セクションを変更した場合は必須。

# オートロード情報を更新
composer dump-autoload

# 開発環境では最適化付きもよく使う
composer dump-autoload -o

・クラスを追加・削除した

・autoload の設定(psr-4, classmap 等)を変更した

といった操作をしたあとにエラーが出る場合は、まず dump-autoload を試す価値がある。

RouteとControllerの指定ミス(Target class does not exist)

Laravel 8以降では、ルートでコントローラを指定するときの書き方が変わっており、ここを間違えると「Target class [XxxController] does not exist」になる。

NG例:

// Laravel 8以降で古い書き方をしているケース
Route::get('/users', 'UserController@index');  // これだけだとClass解決に失敗することがある

推奨される書き方:

use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']);

また、コントローラの namespace 自体が違うケースもある。

<?php

namespace App\Http\Controllers\Admin;

class UserController extends Controller
{
    //
}

この場合、ルートは次のように書く。

use App\Http\Controllers\Admin\UserController;

Route::get('/admin/users', [UserController::class, 'index']);

「Controllerのnamespace」と「Routeでの指定」が一致しているか確認する。

config/app.php の aliases / providers でのクラス指定ミス

独自クラスやパッケージのファサード・サービスプロバイダを追加したときに、config/app.php の記述を間違えると、アプリ起動時に「Class Not Found」になる。

例:独自ファサードを追加した場合。

// config/app.php

'aliases' => [
    // ...
    'MyService' => App\Facades\MyService::class,
],

ここで App\Facades\MyService が実際には App\Support\MyService にある場合、起動時にエラーになる。

Class 'App\Facades\MyService' not found

対処:実際のクラスファイルと namespace を確認し、aliases / providers の記述を修正する。

// 例: 正しい名前空間に揃える
'aliases' => [
    'MyService' => App\Support\MyService::class,
],

config を変更したあと、必要に応じて設定キャッシュを作り直す。

php artisan config:clear
php artisan config:cache

artisan コマンド実行時(migrate / db:seed / tinker など)の Class Not Found

artisan コマンドでクラス指定を伴う操作をするときにも、クラス名の指定ミスでエラーが出る。

マイグレーション実行時の例:

php artisan migrate
# Class 'CreateUsersTable' not found

主な原因:

・マイグレーションファイルのクラス名とファイル名が一致していない

・クラス名をリネームしたが、ファイル名や中身を揃えていない

マイグレーションファイルを確認。

<?php

// ファイル: database/migrations/2024_01_01_000000_create_users_table.php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration   // ← このクラス名とファイル名の一部が対応している必要
{
    public function up()
    {
        //
    }

    public function down()
    {
        //
    }
}

Seeder でも同様に、DatabaseSeeder から呼び出すクラス名を間違えるとエラーになる。

// DatabaseSeeder.php
public function run()
{
    $this->call([
        UsersTableSeeder::class,   // ← 実際のクラス名と一致させる
    ]);
}

Job・Event・Listener・Notificationなどのクラスが見つからない場合

artisan make:job などで作成したクラスをキューやイベントに登録するときも、名前空間とクラス名の指定ミスで「Class Not Found」になる。

Job の例:

php artisan make:job SendWelcomeMail

生成されるファイル。

<?php

namespace App\Jobs;

class SendWelcomeMail implements ShouldQueue
{
    //
}

呼び出す側。

use App\Jobs\SendWelcomeMail;

SendWelcomeMail::dispatch($user);

もし namespace を書き換えたり、ファイルを移動したりした場合は、use 宣言・Queue設定(config/queue.php)と整合が取れているか再確認する。Event / Listener / Notification も同じ考え方でチェックできる。

クラス名の大文字・小文字の違い(Linux環境でのみ発生することも)

WindowsやmacOSではファイルシステムが大小文字を区別しないことが多いため、ローカル開発時には動いていても、本番Linux環境で「Class Not Found」になることがある。

例:

# ファイル名
app/Services/userservice.php

# クラス定義
class UserService { ... }

# 呼び出し側
use App\Services\UserService;

Windowsのローカルでは動くが、Linux本番では「UserService.php が見つからない」とされる場合がある。

対処:

・クラス名とファイル名を完全に一致させる(UserService.php / class UserService)

・ディレクトリ名も含めて、PSR-4のルールに従って大文字小文字を統一する

トラブルシューティングの基本手順(どのレイヤでクラスが見つからないかを切り分ける)

Class Not Found に遭遇したら、次の順番で確認していくと原因にたどり着きやすい。

1) エラーメッセージに出ているクラス名 (例: App\Services\UserService) を正確にメモする
2) そのクラスの「ファイルパス」と「namespace」が実際にどうなっているかを確認する
   - app/ 配下なら PSR-4 で App\ に対応しているか
3) 呼び出し側の use 宣言が正しいか(use App\Services\UserService; など)
4) Route / Controller の指定方法がLaravelのバージョンに合っているか
   - Route::get([...]) 記法や Target class エラーに注意
5) config/app.php の aliases / providers に間違ったクラス名を書いていないか
6) artisan コマンド実行時なら、Migration / Seeder / Job のクラス名・ファイル名が一致しているか
7) composer.json のautoload設定を変更したなら、composer dump-autoload を実行したか
8) WindowsとLinuxで動作が違うなら、ファイル名とクラス名の大文字小文字をすべて揃えたか

このチェックリストを上から順に確認すれば、多くの「Class Not Found」は原因の場所を特定できる。