【问题标题】:Target class controller does not exist - Laravel 8目标类控制器不存在 - Laravel 8
【发布时间】:2020-12-27 16:00:51
【问题描述】:

这是我的控制器:

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class RegisterController extends Controller
{
    public function register(Request $request)
    {
        dd('aa');
    }
}

如屏幕截图所示,该类存在并且在正确的位置:

我的api.php路线:

Route::get('register', 'Api\RegisterController@register');

当我使用 Postman 访问我的 register 路由时,它给了我以下错误:

目标类 [Api\RegisterController] 不存在。


更新:

感谢答案,我能够修复它。我决定为此路线使用完全限定的类名,但答案中描述了其他选项。

Route::get('register', 'App\Http\Controllers\Api\RegisterController@register');

【问题讨论】:

  • 欢迎来到 SO .. 您的控制器在 Api 文件夹中吗.?
  • 您需要将类重新生成为composer dump-autoload 或在您的RegisterController 中缺少命名空间。
  • @KamleshPaul 是的
  • 然后试试composer dump-autoload

标签: php laravel laravel-8 laravel-routing


【解决方案1】:

在 Laravel 8 中定义路由的方式是

// Using PHP callable syntax...
use App\Http\Controllers\HomeController;
Route::get('/', [HomeController::class, 'index']);

或者

// Using string syntax...
Route::get('/', 'App\Http\Controllers\HomeController@index');

资源路由变成

// Using PHP callable syntax...
use App\Http\Controllers\HomeController;
Route::resource('/', HomeController::class);

这意味着在 laravel 8 中,默认没有自动控制器声明前缀。

如果你想坚持旧的方式,那么你需要在 app\Providers\RouteServiceProvider.php 并在 routes 方法中激活。

【讨论】:

    【解决方案2】:

    我在安装 Laravel 8.27.0 版时遇到了同样的错误: 错误如下:

    但是当我看到我的app/Providers/RouteServiceProvider.php 文件时,我的引导方法中有命名空间。然后我只是取消注释这个 => protected $namespace = 'App\\Http\\Controllers'; 现在我的项目正在运行

    【讨论】:

      【解决方案3】:

      Laravel 8 documentation 实际上比这里的任何答案都更简洁明了地回答了这个问题:

      路由命名空间更新

      在之前的 Laravel 版本中,RouteServiceProvider 包含一个 $namespace 属性。此属性的值将自动添加到控制器路由定义和调用 action helper / URL::action 方法的前缀。在 Laravel 8.x 中,该属性默认为 null。这意味着 Laravel 不会自动为命名空间添加前缀。因此,在新的 Laravel 8.x 应用程序中,控制器路由定义应该使用标准的 PHP 可调用语法来定义:

      use App\Http\Controllers\UserController;
      
      Route::get('/users', [UserController::class, 'index']);
      

      action 相关方法的调用应使用相同的可调用语法:

      action([UserController::class, 'index']);
      
      return Redirect::action([UserController::class, 'index']);
      

      如果您更喜欢 Laravel 7.x 样式的控制器路由前缀,您可以简单地将 $namespace 属性添加到应用程序的 RouteServiceProvider 中。

      【讨论】:

        【解决方案4】:

        app/Providers文件夹中,文件RouteServiceProvider.php,将受保护的$namespace变量改为

        protected $namespace = 'App\\Http\\Controllers';
        

        这将在保存时自动注释变量。

        【讨论】:

        • “自动评论”是什么意思?发生什么了?你能详细说明一下吗?
        【解决方案5】:

        当我将 null 传递给 middleware 函数时发生在我身上:

        Route::middleware(null)->group(function () {
            Route::get('/some-path', [SomeController::class, 'search']);
        });
        

        传递 [] 没有中间件工作。或者如果不使用中间件,可能只是删除middleware 调用:D

        【讨论】:

          【解决方案6】:

          在新安装的 Laravel 8 上,在 App/Providers/RouteServices.php 文件中:

           /*
           * The path to the "home" route for your application.
           *
           * This is used by Laravel authentication to redirect users after login.
           *
           * @var string
           */
          public const HOME = '/home';
          
          /**
           * The controller namespace for the application.
           *
           * When present, controller route declarations will automatically be prefixed with this namespace.
           *
           * @var string|null
           */
           // protected $namespace = 'App\\Http\\Controllers';
          

          取消注释行

          protected $namespace = 'App\\Http\\Controllers';
          

          这应该可以帮助您以老式的方式运行 Laravel。

          如果你从低版本的 Laravel 升级到 8,那么你可能需要隐式添加行

          受保护的 $namespace = 'App\Http\Controllers';

          RouteServices.php 文件中让它以旧方式运行。

          【讨论】:

            【解决方案7】:

            如果您更喜欢对这些路线进行分组,您可以这样做:

            Route::group(['namespace' => 'App\Http\Controllers\Api'], function () {
                Route::resource('user', 'UserController');
                Route::resource('book', 'BookController');
            });
            

            【讨论】:

              【解决方案8】:

              我遇到了这个错误:

              (Illuminate\Contracts\Container\BindingResolutionException 目标类 [App\Http\Controllers\ControllerFileName] 不存在。

              解决方案:

              只需检查您的班级名称。它应该与您的文件名完全相同。

              【讨论】:

                【解决方案9】:

                对于解决方案,只需取消注释第 29 行:

                **protected $namespace = 'App\\Http\\Controllers';**
                

                在“app\Providers\RouteServiceProvider.php”文件中。

                Just uncomment line 29

                【讨论】:

                • 这个解决了我的问题 laravel 8.22.1 .. 以上评价都没有。谢谢
                【解决方案10】:

                如果您使用的是 Laravel 8,只需复制并粘贴我的代码:

                use App\Http\Controllers\UserController;
                
                Route::get('/user', [UserController::class, 'index']);
                

                【讨论】:

                  【解决方案11】:

                  只需从RouteServiceProvider 中取消注释以下行(如果不存在则添加它):

                  protected $namespace = 'App\\Http\\Controllers';
                  

                  【讨论】:

                    【解决方案12】:

                    在 Laravel 8 中你可以这样使用它:

                    Route::group(['namespace'=>'App\Http\Controllers', 'prefix'=>'admin',
                     'as'=>'admin.', 'middleware' => ['auth:sanctum', 'verified']], function()
                    {
                        Route::resource('/dashboard', 'DashboardController')->only([
                            'index'
                        ]);
                    });
                    

                    【讨论】:

                      【解决方案13】:

                      Laravel 8 更新了 RouteServiceProvider,它使用字符串语法影响路由。您可以像以前的答案一样更改它,但推荐的方法是使用操作语法,而不是使用带有字符串语法的路由:

                      Route::get('register', 'Api\RegisterController@register');
                      

                      应该改为:

                      Route::get('register', [RegisterController::class, 'register']);
                      

                      【讨论】:

                        【解决方案14】:
                        • 是的,在 Laravel 8 中确实会发生此错误。
                        • 在尝试了许多解决方案后,我得到了这个完美的解决方案。
                        • 只需按照步骤...

                        案例一

                        我们可以更改 api.phpweb.php 文件,如下所示。 我们目前写syntax的方式是

                        Route::get('login', 'LoginController@login');
                        

                        应该改为:

                        Route::get('login', [LoginController::class, 'login']);
                        

                        案例2

                        1. 首先进入文件:app &gt; Providers &gt; RouteServiceProvider.php

                        2. 在该文件中替换该行 protected $namespace = null;protected $namespace = 'App\Http\Controllers';

                        3. 然后如图所示添加-&gt;namespace($this-&gt;namespace)行...

                        【讨论】:

                        • 关于第一种情况,如果我们有一个资源控制器怎么办。也就是说,没有具体的功能可以指定?
                        • Route::resource("proxies", ProxyController::class) 因找不到类错误而失败。它使用命名空间两次\App\Http\Controllers\App\Http\Controllers\ProxyController
                        • 谢谢,这很神奇
                        【解决方案15】:

                        在 Laravel 8 中默认是移除命名空间前缀,所以你可以在 Laravel 7 中设置旧的方式:

                        RouteServiceProvider.php中,添加这个变量:

                        protected $namespace = 'App\Http\Controllers';
                        

                        并更新boot 方法:

                        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'));
                            });
                        }
                        

                        【讨论】:

                          【解决方案16】:

                          在 Laravel 8 中,您只需在 routes\web.php 中添加控制器命名空间

                          use App\Http\Controllers\InvoiceController; // InvoiceController is controller name
                          
                          Route::get('invoice',[InvoiceController::class, 'index']);
                          

                          或转到: app\Providers\RouteServiceProvider.php 路径并删除评论:

                          protected $namespace = 'App\\Http\\Controllers';
                          

                          【讨论】:

                            【解决方案17】:

                            您使用的是 Laravel 8。在全新安装的 Laravel 8 中,没有将命名空间前缀应用于您的路由加载到的路由组。

                            “在以前的 Laravel 版本中,RouteServiceProvider 包含一个 $namespace 属性。该属性的值将自动添加到控制器路由定义和调用 action helper / URL::action 方法的前缀。在 Laravel 8 中。 x,该属性默认为null。这意味着Laravel不会自动为命名空间添加前缀。” Laravel 8.x Docs - Release Notes

                            在不使用命名空间前缀时,在路由中引用控制器时,您必须为控制器使用完全限定的类名。

                            use App\Http\Controllers\UserController;
                            
                            Route::get('/users', [UserController::class, 'index']);
                            // or
                            Route::get('/users', 'App\Http\Controllers\UserController@index');
                            

                            如果您更喜欢旧方式:

                            App\Providers\RouteServiceProvider:

                            public function boot()
                            {
                                ...
                            
                                Route::prefix('api')
                                    ->middleware('api')
                                    ->namespace('App\Http\Controllers') // <---------
                                    ->group(base_path('routes/api.php'));
                            
                                ...
                            }
                            

                            对您想要为其声明命名空间的任何路由组执行此操作。

                            $namespace 属性:

                            尽管在发行说明中提到要在您的 RouteServiceProvider 上设置 $namespace 属性并在您的 RouteServiceProvider 中进行评论,但这对您的路线没有任何影响。它目前仅用于添加命名空间前缀以生成操作的 URL。所以你可以设置这个变量,但它本身不会添加这些命名空间前缀,你仍然需要确保在将命名空间添加到路由组时使用这个变量。

                            此信息现在位于升级指南中

                            Laravel 8.x Docs - Upgrade Guide - Routing

                            升级指南显示的重要部分是您正在为路由组定义命名空间。单独设置$namespace 变量有助于生成操作的 URL。

                            再一次,我不能强调这一点,重要部分是为路由组设置命名空间,他们恰好通过直接引用成员变量$namespace例子。

                            更新:

                            如果您从 laravel/laravel 的 8.0.2 版本开始安装了 Laravel 8 的新副本,您可以取消注释 RouteServiceProvider 中的 protected $namespace 成员变量以返回旧方式,因为已设置路由组将此成员变量用于组的命名空间。

                            // protected $namespace = 'App\\Http\\Controllers';
                            

                            取消注释会将命名空间前缀添加到分配给路由的控制器的唯一原因是因为路由组设置为使用此变量作为命名空间:

                            ...
                            ->namespace($this->namespace)
                            ...
                            

                            【讨论】:

                            • 这真的把我逼疯了。 $namespace 变量上方的注释说:“如果指定,此命名空间将自动应用于您的控制器路由。”好吧,事实并非如此。正如您所指出的,您必须添加 ->namespace('App\Http\Controllers') 。他们真的应该更改源代码中的注释...
                            • 为什么修改了?为了提高性能?
                            • @WesleySmith 自 laravel/laravel 的 8.0.2 起,如果您愿意,您可以取消注释并使用
                            • @lagbox 世界因为stackoverflow和像你这样的人而变得美好......
                            • 你先生/女士/人是一个传奇。我想给你 10 美元的 IOTA 小费。如果你不知道它是什么 (howtobuyiota.co.uk/what-is-iota)。如果有,请告诉我您的收货地址。
                            【解决方案18】:

                            在 Laravel 8 中,指定路线的方式发生了变化:

                            Route::resource('homes', HomeController::class)->names('home.index');
                            

                            【讨论】:

                              【解决方案19】:

                              如果您想继续使用原来的自动前缀控制器路由,您可以简单地在 RouteServiceProvider 中设置 $namespace 属性的值,并在引导方法中更新路由注册以使用 $namespace 属性:

                              class RouteServiceProvider extends ServiceProvider
                              {
                                  /**
                                   * This namespace is applied to your controller routes.
                                   *
                                   * In addition, it is set as the URL generator's root namespace.
                                   *
                                   * @var string
                                   */
                                  protected $namespace = 'App\Http\Controllers';
                              
                                  /**
                                   * Define your route model bindings, pattern filters, etc.
                                   *
                                   * @return void
                                   */
                                  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'));
                                  });
                              }
                              

                              【讨论】:

                                猜你喜欢
                                • 2021-06-16
                                • 2020-12-27
                                • 2021-04-09
                                • 2021-01-18
                                • 2021-04-27
                                • 2021-09-03
                                • 2021-01-26
                                相关资源
                                最近更新 更多