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

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

Enter image description here

我的api.php路由:

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

当我使用邮递员命中我的register路由时,它给了我以下错误:

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

我该怎么解决呢?


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

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

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

在Laravel之前的版本中,RouteServiceProvider包含$namespace属性。此属性的值将自动添加到控制器路由定义和调用action helper / 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 -升级指南- Routing . x

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

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

更新:

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

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

只有取消注释的原因是将命名空间前缀添加到分配给路由的Controllers中,因为路由组被设置为使用此变量作为命名空间:

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

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

在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中确实发生了这个错误。
  • 在尝试了许多解决方案后,我得到了这个完美的解决方案。
  • 只要按照步骤做……

案例1

我们可以像下面这样在api.phpweb.php文件中进行更改。 当前我们编写syntax的方式是

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

应该改为:

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

案例2

  1. 首先进入文件:app > Providers > RouteServiceProvider.php

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

    Enter image description here

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

    Enter image description here

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文件中。

取消第29行

我犯了这个错误:

< p >(照亮\合同\ \ BindingResolutionException容器 目标类[App\Http\Controllers\ControllerFileName]不存在

解决方案:

检查你的类的名字。它应该与您的文件名完全相同。

如果你喜欢这些路由的分组,你可以这样做:

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中,应用程序/供应商/ 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的低版本升级到8版本,那么你可能不得不隐式地添加line

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

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

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

路由命名空间更新

在Laravel之前的版本中,RouteServiceProvider包含$namespace属性。此属性的值将自动添加到控制器路由定义和调用action helper / 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

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

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

为任何中间件传递[]都不行。或者如果不使用中间件,可能只是删除middleware调用:D

app /提供者文件夹文件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,请确保你用用户而不是用户控件来引用它。

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

而不是

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

使用

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

在我的例子中,我有同样的错误,因为我忘记在路径中大写controllers的第一个字母。

所以我改变了

use App\Http\controllers\HomeController;

:

use App\Http\Controllers\HomeController;

我试了所有的方法,都没用,直到我第二次尝试 重新启动服务器< / p >
php artisan cache:clear
php artisan optimize


php artisan route:list

是的,检查路由文件夹中的web.php是否使用了Controller类。

use App\Http\Controllers\<name of controlelr class>