路由到 Laravel 8 中的控制器 [重复]

Posted

技术标签:

【中文标题】路由到 Laravel 8 中的控制器 [重复]【英文标题】:Route to controller in Laravel 8 [duplicate] 【发布时间】:2021-01-19 01:13:47 【问题描述】:

我正在使用 Laravel 8,当我像这样编写到 __invoke 控制器的路由时:

use App\Http\Controllers\PortfolioController;

Route::get('/portfolio', 'PortfolioController')->name('portfolio');

它显示了这个错误:

路由操作无效:[PortfolioController]。 PortfolioController 不可调用

所以它只能这样工作:

Route::get('/portfolio', [PortfolioController::class, '__invoke'])->name('portfolio');;

这对我来说没有意义,因为它应该找到__invoke,这是PortfolioController.php 中唯一的一个:

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PortfolioController extends Controller

    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    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 属性???

【问题讨论】:

【参考方案1】:

TL;DR

这样做:

use App\Http\Controllers\PortfolioController;

Route::get('/portfolio', PortfolioController::class)->name('portfolio');
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^

说明

在 Laravel 8 之前,路由的命名空间在 RouteServiceProvider.php:

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

// ...

protected function mapWebRoutes()

    Route::middleware('web')
        ->namespace($this->namespace) // <----
        ->group(base_path('routes/web.php'));

所以,当您定义路线时,就像在您的示例中一样:

Route::get('/portfolio', 'PortfolioController')->name('portfolio');
                         ^^^^^^^^^^^^^^^^^^^^^

PortfolioController 字符串以 App\Http\Controllers 命名。

在 Laravel 8 中,此行为已被修改。来自v8 release note:

在 Laravel 8.x 中,该属性默认为 null。这意味着没有 自动命名空间前缀将由 Laravel 完成。因此,在 新的 Laravel 8.x 应用程序,控制器路由定义应该是 使用标准 PHP 可调用语法定义:

use App\Http\Controllers\UserController;

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

现在,对于您提到的特定情况,__invoke() 方法,这就是您应该如何处理它们according to the docs:

为单个动作控制器注册路由时,您不需要 指定方法:

use App\Http\Controllers\ShowProfile;

Route::get('user/id', ShowProfile::class);

【讨论】:

非常感谢您的精彩解释??? 或者如果你不想在路由文件中导入所有控制器$router-&gt;group([ 'namespace' =&gt; '\App\Http\Controllers'], function ($router) $router-&gt;get('portfolio', [ 'as' =&gt; 'portfolio', 'uses' =&gt; 'PortfolioController::class', ]); );【参考方案2】:

另一种用途,可以使用完整路径


Route::get('/portfolio', 'App\Http\Controllers\PortfolioController')->name('portfolio');

或调用特定方法

Route::get('/portfolio', 'App\Http\Controllers\PortfolioController@foo')->name('portfolio')

【讨论】:

以上是关于路由到 Laravel 8 中的控制器 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

有 Laravel 8 路由和控制器问题

Laravel 8:调用路由时数组到字符串的转换:列表

为 Laravel 8 路由定义命名空间 [重复]

Laravel 中的控制台路由是啥?它是如何工作的? [关闭]

如何在控制器laravel 8中通过ajax传递路由链接和图像存储链接

在 Laravel 中对控制器进行单元测试而不测试路由的最佳方法是啥