【问题标题】:Laravel 8 Multiple Routes With The Same UrlLaravel 8 具有相同 URL 的多条路由
【发布时间】:2021-08-05 15:49:48
【问题描述】:

美好的一天

我是 Laravel 的新手,我想创建一个拥有多个用户(学生、主管、HOD)的网站。我想知道是否有办法让所有用户都拥有相同的 URL。以下是我用来尝试实现此目的的方法:

web.php

// Routes For Students
Route::group(['middleware' => ['auth', 'role:student']], function() {
    Route::get('/home', 'App\Http\Controllers\StudentController@index')->name('student');
    Route::get('/proposal', 'App\Http\Controllers\StudentController@proposal')->name('proposal');
    Route::get('/thesis', 'App\Http\Controllers\StudentController@thesis')->name('thesis');
});

// Routes For Supervisors
Route::group(['middleware' => ['auth', 'role:supervisor']], function() {
    Route::get('/home', 'App\Http\Controllers\supervisorController@index')->name('supervisor');
    Route::get('/proposal', 'App\Http\Controllers\supervisorController@proposal')->name('proposal');
    Route::get('/thesis', 'App\Http\Controllers\supervisorController@thesis')->name('thesis');
});

// Routes For HOD's
Route::group(['middleware' => ['auth', 'role:hod']], function() {
    Route::get('/home', 'App\Http\Controllers\hodController@index')->name('hod');
    Route::get('/proposal', 'App\Http\Controllers\hodController@proposal')->name('proposal');
    Route::get('/thesis', 'App\Http\Controllers\hodController@thesis')->name('thesis');
});

但是我注意到您不能拥有具有相同 URL 的路由,但我希望所有类型的用户在他们各自的主页、提案和论文页面上都具有相同的 URL。这可能吗?

如果您需要更多代码或更好的解释,请告诉我。

【问题讨论】:

    标签: php laravel routes laravel-8 laratrust


    【解决方案1】:

    我建议只为所有这些路由添加一个前缀。这样你就不会得到任何重复的 uri。


    如果您真的不想这样做,我还有另一种可能,但您将无法保留路线名称。

    基本上,使用可调用控制器重新路由到正确的控制器/动作。

    php artisan make:controller -i
    
    Route::group(['middleware' => ['auth']], function () {
        Route::get('/home', 'App\Http\Controllers\MyInvokableController')->name('home');
        Route::get('/proposal', 'App\Http\Controllers\MyInvokableController')->name('proposal');
        Route::get('/thesis', 'App\Http\Controllers\MyInvokableController')->name('thesis');
    });
    
    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class MyInvokableController extends Controller
    {
        private $lookupArray = [
            'home'     => 'index',
            'proposal' => 'proposal',
            'thesis'   => 'thesis',
        ];
    
        public function __invoke(Request $request)
        {
            $role = ;// get your user's role
            $urlSegment = $request->segment(count($request->segments()) - 1); // 'home', 'proposal' or 'thesis'
    
            if ($role === 'student') {
                return app(StudentController::class)->{$this->lookupArray[$urlSegment]}($request);
            } elseif ($role === 'supervisor') {
                return app(supervisorController::class)->{$this->lookupArray[$urlSegment]}($request);
            } elseif ($role === 'hod') {
                return app(hodController::class)->{$this->lookupArray[$urlSegment]}($request);
            } else {
                throw new \Exception("Unexpected role $role.");
            }
        }
    }
    

    【讨论】:

    • 感谢您的回答。如果我必须添加一个前缀,你认为它是什么?也许是用户 ID?还是一些随机生成的数字?
    • 没什么复杂的。只需 prefix('student') 用于学生路线,prefix('supervisor') 用于主管路线,prefix('hod') 用于 hod 路线。这样你就可以拥有/student/home/supervisor/home/hod/home 的网址。我说的是您要在分组中添加的路由前缀。 Route::prefix('hod')-&gt;name('hod.')-&gt;group(['middleware' =&gt; ['auth']], function () {
    • 啊,好的。第一次发问题,很高兴能得到这么好的帮助。谢谢。
    【解决方案2】:

    如果您需要保持相同的路线,您可以按照@IGP 的回答或只检查刀片本身的用户角色。

    // welcome.blade.php
    @role('student')
        <h1>Student welcome page</h1>
    @endrole
    
    @role('supervisor')
        <h1>Supervisor welcome page</h1>
    @endrole
    
    @role('hod')
        <h1>Hod welcome page</h1>
    @endrole
    

    【讨论】:

    • 感谢您的回答。这就是我的想法,但是我想知道如果每种用户类型在各自的页面中都有很多事情发生,那么效率会有多高。对此有什么想法吗?
    • 好吧,由于@role sn-ps 中的代码如果没有分配给用户该角色将不会被执行,您可以简单地将这些内容移动到单独的刀片中(为了清楚起见)并添加@include('&lt;role&gt;-welcome-page') 加载每个角色的内容。我认为不会有任何性能问题,如果没有正确拆分,只需将很多代码放在一起。
    • 好的,如果没有任何性能问题,那么这绝对是要走的路。谢谢。
    【解决方案3】:

    我认为您最好处理控制器上的逻辑而不是角色中间件。是否有任何主管具有学生“角色”?不,那是因为 Supervisor 不是这里的角色,它是用户类型。所以在这里你想要相同的 URL,这是我更喜欢的:

    Route::group(['middleware' => ['auth']], function() {
        Route::get('/home', 'App\Http\Controllers\Controller@index')->name('home');
        Route::get('/proposal', 'App\Http\Controllers\Controller@proposal')->name('proposal');
        Route::get('/thesis', 'App\Http\Controllers\Controller@thesis')->name('thesis');
    });
    

    在幕后处理用户类型。

    public function index(Request $request) 
    {
        // handle the request, determine the user type, populate the proper view, etc.
    }
    

    现在关于角色,

    中间件也可以接收额外的参数。例如,如果您的应用程序需要在执行给定操作之前验证经过身份验证的用户是否具有给定的“角色”。 Laravel 8 Documentation - Middleware

    举个例子,您可以在您的应用程序中设置“演示者”角色,该角色具有唯一的 URL,并且允许学生和主管访问它们。

    仅仅使用中间件并不意味着它就是一个有效的解决方案。正如文档所说:

    中间件提供了一种方便的机制来检查和过滤进入应用程序的 HTTP 请求。 Laravel Documentation

    【讨论】:

    • 感谢您的回答。当您的解释超出我的想象时,我肯定需要阅读更多有关此内容的信息。谢谢。
    猜你喜欢
    • 2021-05-04
    • 2018-11-04
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    相关资源
    最近更新 更多