这是我的控制器:

<?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命中我的寄存器路径时,它给了我以下错误:

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

我该怎么解决呢?


多亏了这些答案,我才得以修复它。我决定对这个路由使用完全限定类名,但是答案中描述了其他选项。

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

当前回答

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

在Laravel之前的版本中,RouteServiceProvider包含一个$namespace属性。此属性的值将自动添加到控制器路由定义的前缀,并调用动作助手/ URL::action方法。在Laravel 8。X,此属性默认为空。这意味着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');

如果你更喜欢旧的方式:

应用\ \ 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 -升级指南-路由

升级指南显示的重要部分是您在路由组上定义了一个名称空间。设置$命名空间变量本身只有助于生成指向操作的url。

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

更新:

如果你从Laravel / Laravel的8.0.2版本开始安装了Laravel 8的新副本,你可以取消注释RouteServiceProvider中受保护的$namespace成员变量,回到旧的方式,因为路由组被设置为为组的命名空间使用这个成员变量。

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

uncomment会将命名空间前缀添加到分配给路由的Controllers的唯一原因是路由组设置使用这个变量作为命名空间:

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

其他回答

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

路由命名空间更新

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

use App\Http\Controllers\UserController;

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

对动作相关方法的调用应该使用相同的可调用语法:

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

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

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

我在运行php artisan route:list时遇到了同样的错误。在我的情况下,我已经删除了追索权控制器,但路由仍然被定义。我必须确保在routes/web.php中注释掉了有问题的类。

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

在Laravel之前的版本中,RouteServiceProvider包含一个$namespace属性。此属性的值将自动添加到控制器路由定义的前缀,并调用动作助手/ URL::action方法。在Laravel 8。X,此属性默认为空。这意味着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');

如果你更喜欢旧的方式:

应用\ \ 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 -升级指南-路由

升级指南显示的重要部分是您在路由组上定义了一个名称空间。设置$命名空间变量本身只有助于生成指向操作的url。

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

更新:

如果你从Laravel / Laravel的8.0.2版本开始安装了Laravel 8的新副本,你可以取消注释RouteServiceProvider中受保护的$namespace成员变量,回到旧的方式,因为路由组被设置为为组的命名空间使用这个成员变量。

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

uncomment会将命名空间前缀添加到分配给路由的Controllers的唯一原因是路由组设置使用这个变量作为命名空间:

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

在Laravel 9中,不需要在RouteServiceProvider中添加命名空间。

而不是

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

use

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

如果你想继续使用原来的自动前缀控制器路由,你可以简单地在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'));
    });
}