我想做一些事情,但我甚至不知道怎么做。
将参数传递给中间件,我这样做:
Route::put('post/{id}', ['middleware' => 'role:editor', function ($id) {
//
}]);
来自laravel文档。然后在句柄函数中获取参数…
但是laravel建议在控制器的__construct中声明中间件的使用,而不是在路由中。
所以…
public function __construct() {
$this->middleware('auth');
}
但是我不知道如何传递参数给控制器。
您可以在中间件中访问url参数,如下所示:
routes.php
Route::get('/test/{id}', ['uses' => 'Test@test']);
测试控制器<?php
namespace AppHttpControllers;
class Test extends Controller
{
/**
* Test constructor.
*/
public function __construct()
{
$this->middleware('test');
}
public function test()
{
return 'sample';
}
测试中间件<?php namespace AppHttpMiddleware;
use Closure;
class Test
{
public function handle($request, Closure $next)
{
dd($request->id);
return $next($request);
}
}
**不要忘记更新Kernel.php来激活中间件
protected $routeMiddleware = [
'auth' => AppHttpMiddlewareAuthenticate::class,
'auth.basic' => IlluminateAuthMiddlewareAuthenticateWithBasicAuth::class,
'guest' => AppHttpMiddlewareRedirectIfAuthenticated::class,
'test' => AppHttpMiddlewareTest::class,
];
不要将中间件放在控制器中。尽量将业务逻辑置于控制器之外。
让你的中间件文件。
php artisan make:middleware MyMiddlewareDoesThings
现在在您的文件中,找到$handle
函数。
public function handle($request, Closure $next)
在请求和闭包之后添加参数
public function handle($request, Closure $next, $role)
现在$role
将包含role:value
的值,从您的示例中将是$editor
@ muhammadad -sumon-molla-selim的答案实际上是问题中最好的答案,但它泄露了解释
凭借我的知识,我能够遵循他的指导方针,所以这里是一个完整的例子加上一个用例,其中路由的中间件或请求参数是不可能的。
我有一个抽象的CRUDControllerBase,它被许多子控制器扩展。每个子控制器需要一个不同的权限来执行模型上的任何操作,除了index/show。
因此,我被迫动态地将权限(字符串)从控制器传递到中间件,这是基本结构:// AppHttpControllersCRUDControllerBase.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']);
}
}
// AppHttpControllersDocumentController.php
class DocumentController extends CRUDControllerBase
{
protected ?string $permission = 'documents';
}
// AppHttpControllersEventController.php
class EventController extends CRUDControllerBase
{
protected ?string $permission = 'events';
}
我在@muhammad-sumon-molla-selim的回答下解决了这个问题:
// AppHttpMiddlewareVerifyUserPermission.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);
}
}
// AppHttpKernel.php
// Register the middleware
class Kernel extends HttpKernel
{
protected $routeMiddleware = [
'auth' => AppHttpMiddlewareAuthenticate::class,
'auth.basic' => IlluminateAuthMiddlewareAuthenticateWithBasicAuth::class,
// [...]
'permission' => AppHttpMiddlewareVerifyUserPermission::class
];
}
// AppHttpControllersCRUDControllerBase.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']);
}
}
我已经解决了这个问题,用这个:
Route::get('post/{id}', function () {
// Your controller method here
})->middleware('myMiddleware');
在中间件中:
namespace AppHttpMiddleware;
use Closure;
class MyMiddleware
{
public function handle($request, Closure $next)
{
$id = $request->route('id');
// Your middleware logic here
return $next($request);
}
}
如果你想在控制器的__construct中获取参数,你可以这样做:
class HomeController extends BaseController
{
public function __construct()
{
$this->routeParamters = Route::current()->parameters();
}
}