ChatGPT解决这个技术问题 Extra ChatGPT

目标类控制器不存在 - 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');
    }
}

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

https://i.stack.imgur.com/H4CtY.png

我的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

l
lagbox

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

“在以前的 Laravel 版本中,RouteServiceProvider 包含一个 $namespace 属性。该属性的值将自动作为控制器路由定义的前缀,并调用 action helper / 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');

如果您更喜欢旧方式:

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

升级指南显示的 important 部分是您在路由组上定义命名空间。 only 自行设置 $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)。如果你这样做,请告诉我你的收货地址。
P
Peter Mortensen

是的,在 Laravel 8 中确实会发生此错误。

在尝试了许多解决方案后,我得到了这个完美的解决方案。

只需按照步骤...

情况1

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

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

那应该改为:

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

案例2

首先转到文件:app > Providers > RouteServiceProvider.php 在该文件中替换行 protected $namespace = null;带有受保护的 $namespace = 'App\Http\Controllers';然后添加行 ->namespace($this->namespace) 如图所示...


对于第一种情况,如果我们有一个资源控制器会怎样。也就是说,没有具体的功能可以指定?
Route::resource("proxies", ProxyController::class) 因找不到类错误而失败。它使用命名空间两次 \App\Http\Controllers\App\Http\Controllers\ProxyController
谢谢,这就像魔术一样
P
Peter Mortensen

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

O
OMi Shah

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

m
miken32

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


P
Peter Mortensen

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

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

应改为:

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

P
Peter Mortensen

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

use App\Http\Controllers\UserController;

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

C
Chuck Le Butt

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

路由命名空间更新

在之前的 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']);

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

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

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

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


m
miken32

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

https://i.stack.imgur.com/4CaZ2.png

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


J
Jie

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

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

app\Providers\RouteServiceProvider.php 文件中。

Just uncomment line 29


这个解决了我的问题 laravel 8.22.1 .. 以上评价都没有。谢谢
u
user635568

如果您的 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');
});

I
Ivan Fretes

如果您想继续使用原始的自动前缀控制器路由,您可以简单地在 RouteServiceProvider 中设置 $namespace 属性的值,并在 boot 方法中更新路由注册以使用 $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'));
    });
}

P
Peter Mortensen

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

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

P
Peter Mortensen

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

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

S
Shahzad Barkati

在新安装的 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 文件中以使其以旧方式运行。


P
Peter Mortensen

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

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

p
phoenix

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

php artisan route:clear

N
Nzubechukwu

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

例如:

如果您的控制器文件名为 User.php,请使用 User 而不是 UserController 来引用它


A
Ahmed Eid

在 Laravel 9 中无需在 RouteServiceProvider 中添加命名空间

代替

Route::resource('tickets', 'TicketController');

利用

Route::resource('tickets', TicketController::class);

n
navid

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

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

P
Peter Mortensen

我有这个错误:

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

解决方案:

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


P
Peter Mortensen

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

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

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


P
Peter Mortensen

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

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

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


“自动评论”是什么意思?怎么了?你能详细说明吗?

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅