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


80

这是我的控制器:

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

当我register使用邮递员到达路线时,出现以下错误:

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


更新:

多亏了答案,我才得以解决。我决定为此路线使用完全限定的类名,但是答案中还介绍了其他选项。

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

欢迎来到..您的控制器是否在Api文件夹中?
坎培·保罗

您需要composer dump-autoloadRegisterController缺少名称空间的或中重新生成类。
sta

@KamleshPaul是
阮越南阮晋勇

然后尝试composer dump-autoload
Kamlesh Paul

我只需要在终端中输入?
阮越南阮晋勇

Answers:


138

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

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

不使用名称空间前缀时,在路由中引用控制器时,必须使用控制器的完全合格类名称。

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属性:

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

此信息现在在《升级指南》中

Laravel 8.x Docs-升级指南-路由

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

再次强调一下,重要的是为路由组设置名称空间,它们恰好通过$namespace直接在示例中引用成员变量来实现。

更新:

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

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

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

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

这真让我发疯。$ namespace变量上方的注释说:“如果指定,此名称空间将自动应用于您的控制器路由。” 好吧,不是。您必须指出-> namespace('App \ Http \ Controllers')。他们应该真正更改源代码中的注释...
shock_gone_wild

@shock_gone_wild大约25分钟前,该注释和属性已从Provider中删除,因此在下一个补丁版本laravel/laravel中将消失
lagbox

为什么修改了?为了提高性能?
CodeGuru

该答案的视频版本(5分钟)youtu.be/MfE1tnMG6fE
Wibisono Indrawan

1
自8.0.2起laravel/laravel,@ WesleySmith可供您取消注释并根据需要使用
lagbox

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

情况1

我们可以改变api.phpweb.php像波纹管文件..
我们写电流的方法syntex

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

应该更改为

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

案例-2

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

8

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

4

laravel 8更新了RouteServiceProvider并使用字符串语法影响路由,您可以像上面一样更改它,但是建议的方法是使用操作语法而不是将路由与字符串语法一起使用:

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

应更改为:

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

2

如果您使用的是laravel 8

只需复制并粘贴我的代码

use App\Http\Controllers\UserController;

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

2

在laravel 8中,您只需在route \ 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';


1

在laravel-8中,您可以像这样使用

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

谢谢


1

如果您想继续使用原始的自动前缀控制器路由,只需在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'));
    });
}

0

Laravel 8更新写路由的方式

引用链接https://laravel.com/docs/8.x/upgrade

在laravel 8中,您需要使用像

use App\Http\Controllers\SayhelloController;
Route::get('/users/{name?}' , [SayhelloController::class,'index']);

要么

Route::get('/users', 'App\Http\Controllers\UserController@index');

如果你想用旧的方式

然后在 RouteServiceProvider.php

添加这行

 /**
     * 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'; // need to add in Laravel 8
    

public function boot()
{
    $this->configureRateLimiting();

    $this->routes(function () {
        Route::prefix('api')
            ->middleware('api')
            ->namespace($this->namespace) // need to add in Laravel 8
            ->group(base_path('routes/api.php'));

        Route::middleware('web')
            ->namespace($this->namespace) // need to add in Laravel 8
            ->group(base_path('routes/web.php'));
    });
}

然后你可以使用像

Route::get('/users/{name?}' , [SayhelloController::class,'index']);

要么

Route::get('/users', 'UserController@index');




0

我有这个错误

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

解决方案:只需检查您的类名,它应该与您的文件名完全相同。


0

如果您希望将此路线分组,则可以执行以下操作:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.