目标类控制器不存在 - Laravel 8

Ngu*_*ũng 201 php laravel laravel-8

这是我的控制器:

<?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');
    }
}
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

我的api.php路线:

Route::get('register', 'Api\RegisterController@register');
Run Code Online (Sandbox Code Playgroud)

当我register使用 Postman 到达我的路线时,它给了我以下错误:

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


更新:

多亏了答案,我才能修复它。我决定为此路由使用完全限定的类名,但还有其他选项,如答案中所述。

Route::get('register', 'App\Http\Controllers\Api\RegisterController@register');
Run Code Online (Sandbox Code Playgroud)

lag*_*box 400

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

“在以前的 Laravel 版本中,RouteServiceProvider包含一个$namespace属性。这个属性的值将自动添加到控制器路由定义和调用action帮助器/URL::action方法的前缀。在 Laravel 8.x 中,这个属性是null默认的。这意味着没有自动命名空间前缀将由 Laravel 完成。” Laravel 8.x 文档 - 发行说明

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

use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']);
// or
Route::get('/users', 'App\Http\Controllers\UserController@index');
Run Code Online (Sandbox Code Playgroud)

如果您更喜欢旧方式:

App\Providers\RouteServiceProvider

public function boot()
{
    ...

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

    ...
}
Run Code Online (Sandbox Code Playgroud)

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

$namespace属性:

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

此信息现在在升级指南中

Laravel 8.x 文档 - 升级指南 - 路由

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

同样,我再怎么强调都不为过,重要的部分是为路由组设置命名空间,它们恰好通过$namespace在示例中直接引用成员变量来完成。

更新:

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

// protected $namespace = 'App\\Http\\Controllers';
Run Code Online (Sandbox Code Playgroud)

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

...
->namespace($this->namespace)
...
Run Code Online (Sandbox Code Playgroud)

  • 这真的让我发疯。$namespace 变量上方的注释表示:“如果指定,此命名空间将自动应用于您的控制器路由。” 嗯,事实并非如此。正如您所指出的,您必须添加 -&gt;namespace('App\Http\Controllers') 。他们真的应该更改源代码中的注释...... (3认同)
  • @lagbox 世界是一个美好的地方,因为有 stackoverflow 和像你这样的人...... (3认同)
  • 为什么要进行修改?为了提高性能? (2认同)

Roh*_*iya 49

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

情况1

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

Route::get('login', 'LoginController@login');
Run Code Online (Sandbox Code Playgroud)

那应该改为:

Route::get('login', [LoginController::class, 'login']);
Run Code Online (Sandbox Code Playgroud)

案例 - 2

  1. 首先进入文件: app > Providers > RouteServiceProvider.php
  2. 在该文件中替换线
    protected $namespace = null;protected $namespace = 'App\Http\Controllers'; 在此处输入图片说明
  3. 然后添加线->namespace($this->namespace),如图所示..
    在此处输入图片说明


Har*_*ron 28

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

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

或者

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

资源路由变为

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

这意味着在 Laravel 8 中,默认情况下没有任何自动控制器声明前缀。

如果你想坚持旧的方式,那么你需要 app\Providers\RouteServiceProvider.php在routes方法中添加一个命名空间属性并激活。


Jig*_*sar 16

laravel-8 中默认删除命名空间前缀,因此您可以在 laravel-7 中设置旧方式,例如:

RouteServiceProvider.php添加此变量

protected $namespace = 'App\Http\Controllers';
Run Code Online (Sandbox Code Playgroud)

和更新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'));
        });
}
Run Code Online (Sandbox Code Playgroud)


Hed*_*ary 16

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

我得到的错误。

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

现在我的项目正在运行。


Mob*_*sen 11

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

use App\Http\Controllers\InvoiceController; // InvoiceController is controller name

Route::get('invoice',[InvoiceController::class, 'index']);
Run Code Online (Sandbox Code Playgroud)

或转到: app\Providers\RouteServiceProvider.php路径并删除注释:

protected $namespace = 'App\\Http\\Controllers';
Run Code Online (Sandbox Code Playgroud)


小智 9

laravel 8 更新了 RouteServiceProvider 并且它会影响带有字符串语法的路由,您可以像上面一样更改它,但推荐的方法是使用操作语法而不是使用带有字符串语法的路由:

Route::get('register', 'Api\RegisterController@register');
Run Code Online (Sandbox Code Playgroud)

应改为:

Route::get('register', [RegisterController::class, 'register']);
Run Code Online (Sandbox Code Playgroud)


Tim*_*oad 9

在路由文件夹的 web.php(或 api.php)中,使用/添加缺少的 Controller 类。

use App\Http\Controllers\<name of controller class>
Run Code Online (Sandbox Code Playgroud)


小智 8

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

protected $namespace = 'App\\Http\\Controllers';
Run Code Online (Sandbox Code Playgroud)

在文件中app\Providers\RouteServiceProvider.php

只需取消第 29 行的注释即可


Chu*_*utt 8

Laravel 8 文档实际上比这里的任何答案都更简洁、更清楚地回答了这个问题:

路由命名空间更新

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

use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']);
Run Code Online (Sandbox Code Playgroud)

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

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

return Redirect::action([UserController::class, 'index']);
Run Code Online (Sandbox Code Playgroud)

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


小智 7

如果你的 RegisterController 正确就位,还要检查你的路由web.php文件。

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\RegisterController;


Route::get('/register',[RegisterController::class,'index'])->name('register');
Route::post('/register',[RegisterController::class,'store']);

Route::get('/', function () {
    return view('test.index');
});
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您使用的是 Laravel 8

只需复制并粘贴我的代码

use App\Http\Controllers\UserController;

Route::get('/user', [UserController::class, 'index']);
Run Code Online (Sandbox Code Playgroud)