I'm trying to figure out how to pass parameters to a middleware in slim 2. I have a specific use case where I need to customize the behavior of a middleware based on certain parameters.
Here's an example of the middleware code:
$app->post('/test',function () use ($app) { })->setMiddleware([new TestMiddleware(), 'call']);
I cannot add parameters in the object as no constructor can be used in the middleware. I tried to add the parameters in the request inside the router but the middleware is called first.
If you take a look at the documentation of slime v2 Middleware for routes
You'll find some helpful examples, like this one:
Now, for the piece of code you've provided, it makes use of the class
TestMiddlewareand the functioncallSo if we take the example provided above as guidance your code should look like this:
TestMiddleware.php
Index.php
This will be displayed in the browser
Last, if you want to use your
callfunction like this:you'll need to use the
statickeyword, otherwise you've to instantiate the class and pass it to the route:Edit:
Okay, I spent some time modifying the code to meet the requirements and I've found multiple solutions to do it, however the most optimal and best in my opinion is this one:
I'll give you a brief explanation.
Here,
CustomMiddlewareinherits properties and methods from the class MiddlewareThe constructor is used to retrieve parameters
$stateand$msg.You may ask why we're not getting the parameters through the
call()function? Well, If you take a look at the source code you will find out thatcall()is an abstract function that doesn't accept parameters because it belongs to theMiddlewareclass, meaningCustomMiddlewareis just implementing itI had trouble setting the middleware parameters, so I had to use an invoke function.
This is how normaly you will set a middleware in Slim:
1st option
2nd option
3rd
Now, the way I did it is by invoking the instance of the object
CustomMiddlewareas a function using$middleware(), which activates the invoke method. Within the invoke method you can trigger the execution of another function, in this case thecallfunction, avoiding like this calling it manuallyWhat I wanted to avoid:
What I expected:
The Invoke function:
The
callfunction will be modified at your convenience, so there's not much to say.The parameters are set here, with
$msgand$statebeing the two variables, we pass the parameters to the instance of the object CustomMiddleware and the__constructwill take care of it, last we have$middleware(), that will trigger the__invokeand thecallfunction.Again, you may ask why I'm using an anonymous function.
Well, let's say we set the route like this:
If we pass the instance of the object as a argument to the route you will get an error in the browser:
Meaning that the instance
$middlewarepassed to the route shouldn't be an object but a functionLast, we define the route.
We specify as second argument, the middleware defined earlier
Doing this, you should have a working Middleware
Hope it helps
Cheers