php Laravel如何将参数传递给控制器中间件

sulc1iza  于 2023-06-20  发布在  PHP
关注(0)|答案(5)|浏览(144)

我试着做一些事情,但我甚至不能想象如何去做。
要将参数传递给中间件,我这样做:

Route::put('post/{id}', ['middleware' => 'role:editor', function ($id) {
    //
}]);

Laravel文档然后获取句柄函数中的参数。。
但是laravel建议在Controller中的__结构中声明中间件的使用,而不是在路由中。
所以...

public function __construct() {
       $this->middleware('auth');
}

但是我不知道如何将参数传递给控制器。
我会感谢任何帮助。

deyfvvtc

deyfvvtc1#

您可以访问url参数到中间件,如下所示:

routes.php

Route::get('/test/{id}', ['uses' => 'Test@test']);

测试控制器

<?php
namespace App\Http\Controllers;

class Test extends Controller
{

    /**
     * Test constructor.
     */
    public function __construct()
    {
        $this->middleware('test');
    }

    public function test()
    {
        return 'sample';
    }

测试中间件

<?php namespace App\Http\Middleware;

use Closure;

class Test
{
    public function handle($request, Closure $next)
    {
        dd($request->id);

        return $next($request);
    }
}

**不要忘记更新Kernel.php以激活中间件

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'test' => \App\Http\Middleware\Test::class,
    ];
xyhw6mcr

xyhw6mcr2#

不要把中间件放在控制器中。尽可能多地将业务逻辑排除在控制器之外。
相反,创建您的中间件文件。

php artisan make:middleware MyMiddlewareDoesThings

现在,在文件中找到$handle函数。

public function handle($request, Closure $next)

只需在请求和闭包之后添加参数

public function handle($request, Closure $next, $role)

现在,$role将包含role:value的值,在您的示例中,该值为$editor

cgh8pdjw

cgh8pdjw3#

@muhammad-sumon-molla-selim的答案实际上是根据问题最好的答案,但它泄漏到解释中。
根据我的知识,我能够遵循他的指导方针,所以这里是一个完整的例子加上一个用例,其中路由的中间件或请求参数是不可能的。
我有一个抽象的CRUDControllerBase,它由许多子控制器扩展。每个子控制器需要不同的权限来执行模型上的任何操作,除了index/show。
因此,我被迫动态地将权限(字符串)从控制器传递到中间件,下面是基本结构:

// App\Http\Controllers\CRUDControllerBase.php
abstract class CRUDControllerBase extends Controller
{
    /**
     * @var string The needed permission to call store or update
     * If null, permission is granted to every users
     */
    protected ?string $permission = null;

    public function __construct()
    {
        // Here I need to pass to VerifyUserPermission the controller's permission
        $this->middleware(VerifyUserPermission::class)
             ->except(['index', 'show']);
    }
}

// App\Http\Controllers\DocumentController.php
class DocumentController extends CRUDControllerBase
{
    protected ?string $permission = 'documents';
}

// App\Http\Controllers\EventController.php
class EventController extends CRUDControllerBase
{
    protected ?string $permission = 'events';
}

下面是我如何处理这个问题的@muhammad-sumon-molla-selim的回答:

// App\Http\Middleware\VerifyUserPermission.php
// Create the VerifyUserPermission middleware, which accepts the permission string
class VerifyUserPermission
{
    public function handle(Request $request, Closure $next, ?string $permission): mixed
    {
        $user = $request->user();

        // If a permission is needed but the user doesn't have it, abort
        if ($permission && !$user->$permissionField) {
            abort(401);
        }

        return $next($request);
    }
}

// App\Http\Kernel.php
// Register the middleware
class Kernel extends HttpKernel
{
    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        // [...]
        'permission' => \App\Http\Middleware\VerifyUserPermission::class
    ];
}

// App\Http\Controllers\CRUDControllerBase.php
// Then just register the middleware into the CRUDControllerBase's constructor
abstract class CRUDControllerBase extends Controller
{
    protected ?string $permission = null;

    public function __construct()
    {
        // 'documents' permission will be needed for Documents' edition
        // 'events' permission will be needed for Events' edition
        // And so on for many others controllers
        $this->middleware("permission:$this->permission")
             ->except(['index', 'show']);
    }
}
yvgpqqbh

yvgpqqbh4#

我已经解决了这个问题,用这个:

Route::get('post/{id}', function () {
    // Your controller method here
})->middleware('myMiddleware');

在中间件中:

namespace App\Http\Middleware;
use Closure;

class MyMiddleware
{
    public function handle($request, Closure $next)
    {
        $id = $request->route('id');

        // Your middleware logic here

        return $next($request);
    }
}
w80xi6nr

w80xi6nr5#

如果你想在控制器的__结构中获取参数,你可以这样做:

class HomeController extends \BaseController
{
    public function __construct()
    {
        $this->routeParamters = Route::current()->parameters();
    }
}

相关问题