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

Target class controller does not exist - 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');
    }
}

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

我的api.php路线:

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

当我使用 Postman 访问我的 register 路线时,出现以下错误:

Target class [Api\RegisterController] does not exist.


更新:

多亏了回答,我才得以修复。我决定为这条路线使用完全限定的 class 名称,但还有其他选项,如答案中所述。

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

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

"In previous releases of Laravel, the RouteServiceProvider contained a $namespace property. This property's value would automatically be prefixed onto controller route definitions and calls to the action helper / URL::action method. In Laravel 8.x, this property is null by default. This means that no automatic namespace prefixing will be done by Laravel." Laravel 8.x Docs - Release Notes

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

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)
...

如果您想继续使用原始的 auto-prefixed 控制器路由,您只需在 RouteServiceProvider 中设置 $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'));
    });
}

在 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'));
    });
}
  • 是的,在Laravel 8中确实发生了这个错误。
  • 在尝试了很多解决方案后,我得到了这个完美的解决方案。
  • 只需按照步骤操作...

案例一

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

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

应该改为:

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

案例二

  1. 先去文件:app > Providers > RouteServiceProvider.php

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

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

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

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

应该改为:

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

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

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

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

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

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

use App\Http\Controllers\UserController;

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

在 Laravel 8 中,指定路由的方式已更改:

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

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

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

app\Providers\RouteServiceProvider.php 文件中。

Just uncomment line 29

我有这个错误:

(Illuminate\Contracts\Container\BindingResolutionException Target class [App\Http\Controllers\ControllerFileName] does not exist.

解决方案:

只需检查您的 class 姓名。它应该与您的文件名完全相同。

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

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

在 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';

在 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 并在路由方法中激活。

在新安装的 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,那么您可能必须隐式添加行

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

RouteServices.php 文件中以使其以旧方式运行。

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

路由命名空间更新

在 Laravel 的先前版本中,RouteServiceProvider 包含 $namespace 属性。 属性 的值将自动添加到控制器路由定义和对 action 帮助程序/URL::action 方法的调用中。在Laravel8.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.

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

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

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

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

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

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

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

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

同时检查你的路由 web.php 文件,如果你的 RegisterController 正确就位..

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

每次更改路由后要确保做的一件重要事情是清除缓存(使用 laravel 9):

php artisan route:clear

确保您在路径中使用正确的文件名

例如:

如果您的控制器文件名为 User.php,请确保您使用 User 而不是 用户控制器