我正在使用Laravel 8,当我将路由写入__invoke
控制器时,如下所示:
use AppHttpControllersPortfolioController;
Route::get('/portfolio', 'PortfolioController')->name('portfolio');
显示此错误:
无效的路由操作:[PortfolioController]。
PortfolioController
不可调用
所以它只能这样工作:
Route::get('/portfolio', [PortfolioController::class, '__invoke'])->name('portfolio');;
这对我来说没有意义,因为它应该找到__invoke
,这是PortfolioController.php
:中唯一的一个
namespace AppHttpControllers;
use IlluminateHttpRequest;
class PortfolioController extends Controller
{
/**
* Handle the incoming request.
*
* @param IlluminateHttpRequest $request
* @return IlluminateHttpResponse
*/
public function __invoke(Request $request)
{
$portfolio = [
['title' => 'Project #1'],
['title' => 'Project #2'],
['title' => 'Project #3'],
['title' => 'Project #4'],
];
return view('portfolio',compact('portfolio'));
}
}
Laravel 8是否忽略了__invoke
属性???
TL;DR
这样做:
use AppHttpControllersPortfolioController;
Route::get('/portfolio', PortfolioController::class)->name('portfolio');
^^^^^^^^^^^^^^^^^^^^^^^^^^
说明
在Laravel 8之前,路线在RouteServiceProvider.php
:中命名
protected $namespace = 'AppHttpControllers';
// ...
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace) // <----
->group(base_path('routes/web.php'));
}
所以,当你定义路线时,比如你的例子:
Route::get('/portfolio', 'PortfolioController')->name('portfolio');
^^^^^^^^^^^^^^^^^^^^^
PortfolioController
字符串的名称空间为AppHttpControllers
。
然而,自Laravel 8以来,这种行为已被修改。来自v8发布说明:
在Laravel 8.x中,此属性默认为
null
。这意味着不自动名称空间前缀将由Laravel完成。因此,在新的Laravel 8.x应用程序,控制器路由定义应该是使用标准PHP可调用语法定义:use AppHttpControllersUserController; Route::get('/users', [UserController::class, 'index']);
现在,对于您提到的特定情况,__invoke()
方法,这是您应该根据文档处理它们的方式:
为单动作控制器注册路由时,不需要指定方法:
use AppHttpControllersShowProfile; Route::get('user/{id}', ShowProfile::class);
另一种用途,可以使用全路径
Route::get('/portfolio', 'AppHttpControllersPortfolioController')->name('portfolio');
或者调用特定的方法
Route::get('/portfolio', 'AppHttpControllersPortfolioController@foo')->name('portfolio')