ルーティングを書いただけなのに「Target class [XxxController] does not exist.」——Laravel入門者が最初にぶつかるエラーの筆頭です。
結論から。原因はLaravel 8でコントローラの名前空間が自動付与されなくなったことです。そしてこの仕様はLaravel 8以降ずっと同じなので、9・10・11・12(さらに最新の13)でも対処法は共通。古い教材の書き方をコピペすると、2026年の今でも同じエラーが再現します。
この記事では、推奨の直し方から旧仕様に戻す別解、キャッシュ起因の対処まで、5分で解決できるようにまとめます。
この記事でわかること
・エラーの技術的な原因(RouteServiceProviderの仕様変更)
・推奨解:useインポート+クラス参照の書き方
・別解:$namespaceで旧仕様に戻す方法と注意点
・直らないときのキャッシュクリア手順
エラーの原因:名前空間の自動付与が廃止された
Laravel 7以前は、RouteServiceProvider に $namespace = 'App\Http\Controllers' というプロパティが定義されていて、ルート定義に書いたコントローラ名へ自動的にこの名前空間が前置されていました。だから文字列だけで書けたのです。
// Laravel 7以前はこれで動いた(内部でApp\Http\Controllers\が補完されていた)
Route::get('test', 'TestController@index');Laravel 8でこの自動付与がデフォルトで廃止されました($namespace が未設定に)。そのため上の書き方をすると、Laravelは名前空間なしの TestController というクラスをそのまま探しに行き、見つからずに「Target class does not exist.」となります。
廃止された理由は、IDEの補完・静的解析が効くクラス参照構文への統一が推奨されるようになったからです。つまりこのエラーは「新しい書き方に移行してね」というLaravelからのメッセージでもあります。
解決法①【推奨】use+クラス参照で書く
Laravel 8以降の標準の書き方です。手順は2つだけ。
手順1:web.phpの冒頭でコントローラをuseする
use App\Http\Controllers\TestController;
use App\Http\Controllers\ContactFormController;手順2:配列構文[クラス, メソッド名]でルートを書く
// メソッドを指定する場合
Route::get('tests/test', [TestController::class, 'index']);
Route::get('contact/index', [ContactFormController::class, 'index']);
// __invoke()だけを持つシングルアクションコントローラの場合
Route::get('tests/test', TestController::class);全体像はこうなります。
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TestController;
use App\Http\Controllers\ContactFormController;
Route::get('/', function () {
return view('welcome');
});
Route::get('tests/test', [TestController::class, 'index']);
Route::get('contact/index', [ContactFormController::class, 'index']);クラス参照で書くと、タイプミスがエディタ上で即座に赤線になり、クラス名の変更にも追従できます。文字列時代には実行するまで気づけなかったミスが、書いた瞬間にわかる。これが新仕様の最大のメリットです。
解決法②【別解】$namespaceで旧仕様に戻す
古いプロジェクトをLaravel 8以降へアップグレードする場合など、大量の文字列ルートを書き換えたくないケースでは、app/Providers/RouteServiceProvider.php に $namespace を復活させて旧来の挙動へ戻せます。
class RouteServiceProvider extends ServiceProvider
{
// この1行を追加すると文字列ルートに名前空間が自動付与される
protected $namespace = 'App\\Http\\Controllers';
// ...
}ただし注意点があります。Laravel 11以降は初期構成からRouteServiceProvider自体がなくなったため、新規プロジェクトでこの別解を使う意味はほぼありません。
あくまで「旧プロジェクトの移行コストを一時的に下げる延命策」と割り切り、新しく書くルートは解決法①に統一するのが現場の定石です。
解決法③ 書き方が正しいのに直らないときはキャッシュを疑う
現場でよくあるのが「コードは正しいのにエラーが消えない」パターン。原因はルートキャッシュやオートローダの古い情報です。次のコマンドを順に実行してください。
# ルートキャッシュを削除
php artisan route:clear
# 設定などのキャッシュもまとめて削除
php artisan optimize:clear
# クラスの自動読み込み情報を再生成
composer dump-autoloadプロのコツとして、コントローラのファイル名・クラス名・名前空間(ディレクトリ構造)の3点が一致しているかも確認しましょう。
php artisan make:controller で生成していれば起きませんが、手動でファイルをコピーして作ったときにズレがちです。初心者の失敗例として、クラス名だけ変えて名前空間を直し忘れるケースを何度も見てきました。
まとめ
- 原因はLaravel 8で名前空間の自動付与が廃止されたこと(8〜12、13でも同じ仕様)
- 基本はuse+[Controller::class, 'メソッド名']で書く
- 移行中の旧プロジェクトのみ$namespace復活の別解が使える
- 直らなければ route:clear/optimize:clear/dump-autoload
この手のエラーは「仕様変更の歴史」を知っていれば一瞬で解決できます。逆に言えば、独学で古い教材だけを頼りにしていると同じ場所で何時間も溶かしがちです(駆け出しエンジニアがやりがちな勘違いでも触れています)。
体系的に最新仕様で学び直したいならスクールの活用も近道ですし、Laravelの実務経験を積みたいなら転職エージェントでLaravel案件の多い企業を探してもらうのが確実です。
未経験からの学習順序は未経験からのロードマップを、Laravel自体の強みはLaravelはなぜ人気なのかをどうぞ。
よくある質問(FAQ)
Q. Laravel 12や13でも同じ書き方で大丈夫ですか?
大丈夫です。use+クラス参照の構文はLaravel 8で標準になって以降、12・13でも変わらず推奨の書き方です。むしろ文字列+$namespace方式のほうがレガシー扱いなので、新規コードでは使わないようにしましょう。
Q. useを書かずに1行で済ませる方法はありますか?
あります。Route::get('test', [\App\Http\Controllers\TestController::class, 'index']); のようにフル修飾名で書けばuseは不要です。ただしルートが増えると読みにくくなるので、基本は冒頭でuseするスタイルをおすすめします。
Q. リソースコントローラでも同じエラーは出ますか?
出ます。
Route::resource('posts', 'PostController') のような文字列指定が原因になるのも同じ理屈で、Route::resource('posts', PostController::class) とクラス参照に直せば解決します。
エラーの原因はルーティングの書き方ではなく「クラスを解決できないこと」だと覚えておくと応用が利きます。
あわせて読みたい関連記事
Laravelはなぜ人気?6つの理由と将来性を現役エンジニアが解説【2026】LaravelはPHPフレームワークのデファクトで、2026年も毎年進化中。人気の理由をEloquent・Artisan・エコシステムなど6つに整理し、Symfony・CakePHPとの比較表、AI開発との相性、年収を上げる掛け算戦略まで現役エンジニアが解説します。frontendlab.magicgifted.com
【2026年版】未経験から3年でフリーランスエンジニア年収1000万円を達成する完全ロードマップ未経験からフリーランスエンジニア年収1000万円は、正しい順番で動けば3年で届きます。実際に2年1ヶ月で月単価112.5万円に到達した現役エンジニアが、HTML/CSSからReact、転職、独立、単価アップまでの7ステップを2026年のAI時代仕様にアップデートし、今日やるべきことまで具体的に解説します。frontendlab.magicgifted.com




