202
125

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravel8を試したら即効でエラー「Target class [〇〇〇Controller] does not exist.」が表示された

Last updated at Posted at 2020-09-12

#はじめに
最近になってLaravel8がリリースされたと聞いて、とりあえず動かしてみようと思ったら開始早々にエラーが発生しました。
laravel8エラー.png
web.phpPostControllerを呼び出す処理を書いたのに上記エラーが発生。Laravel6ではちゃんと呼び出せたのに:joy:
そのときのweb.phpはこちら。

web.php
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', 'PostController@index');

原因調査したら、どうやらLaravel8の変更点の一つである__「RouteServiceProvider.phpファイルからデフォルトの名前空間を削除」__したのが大きく関係していると判明!Laravel7.xのプロジェクトからLaravel8.xに移行した場合は、この変更点の影響は受けない。Laravel8で作成した新規プロジェクトは変更点を考慮する必要があるそうです。

#RouteServiceProvider.phpの変化
Laravel7までは、RouteServiceProvider.phpには次のコードが含まれていました。
(ファイルはapp/Providers配下に格納されています)

RouteServiceProvider.php
protected $namespace = 'App\Http\Controllers';

Route::middleware('web')
      ->namespace($this->namespace)
      ->group(base_path('routes/web.php'));

webミドルウェアとApp\Http\Controllersの名前空間を使用して、routes/web.phpにルートをロードするよう指示しています。

web.php
// Laravelは、App\Http\Controllers\PostControllerを検索します
Route::get('/', 'PostController@index');

Laravel8では、$namespace変数が削除され、Route宣言が次のように変更されました。

RouteServiceProvider.php
Route::middleware('web')
      ->group(base_path('routes/web.php'));

App\Http\Controllersの名前空間を使用していないです。

web.php
// Laravelは、App\Http\Controllers内でコントローラーを検索しません
Route::get('/', 'PostController@index');

このあと、どう修正すればよいのか解決方法を3つご紹介します。

#解決方法

  • RouteServiceProvider.phpで名前空間を手動で追加する
  • web.phpで完全な名前空間を使用する
  • web.phpでアクション構文を使用する

##RouteServiceProvider.phpで名前空間を手動で追加する
Laravel7.x以前と同じ方法です。

RouteServiceProvider.php
protected $namespace = 'App\Http\Controllers'; //追加
public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::middleware('web')
                ->namespace($this->namespace) //追加
                ->group(base_path('routes/web.php'));

            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace) //追加
                ->group(base_path('routes/api.php'));
        });
    }

##web.phpで完全な名前空間を使用する
コントローラーの名前の前に名前空間を追加します。
例として、app/Http/Controllersフォルダ内のPostControllerを呼び出したいときは、次の通り記載します。

web.php
Route::get('/', 'App\Http\Controllers\PostController@index');

##web.phpでアクション構文を使用する

web.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
Route::get('/', [PostController::class, 'index']);

配列で使用したいクラスとメソッドを指定します。
具体的に配列内の値は
PostsController :: class -> App \ Http \ Controllers \ PostsControllerを返している
index -> PostController.phpのindexメソッドを呼び出している

#終わりに
Laravel開発で初めて遭遇したエラーでしたので勉強になりました。
ただ、Laravel8の新機能・変更点を理解してから使用してみようと思いました。理解せず使用すると痛い目に遭いますね:joy:

#参考
How to fix ‘Target class does not exist’ in Laravel 8

202
125
2

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
202
125

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?