0

Is there any way to pass complex parameter (for example array of objects) to middleware in laravel? I know that I can pass strings via some kind of DSL but I need to pass some more complicated data to one of middlewares. Is this achievable? And if so, how?

There is example what I want to achieve

class Middleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, array $modifiers = null)
    {
        foreach($modifiers as $name => $closure) {
            $request->$name = $closure($request->name)
        }
        return $next($request);
    }
}

And I want to pass

[
    'param' => function($param) { return $param * 2; }
]

As $modifiers parameter to Middleware, and that array will be different for different routes so passing by global context is no go.

kadet
  • 94
  • 1
  • 7
  • Could you provide an exemple of what you are trying to achieve? – Wistar Dec 04 '16 at 03:15
  • Where will this variable come from? Please share some code and workflow. – Jan Willem Dec 04 '16 at 09:05
  • @Wistar I've added example code – kadet Dec 04 '16 at 13:26
  • Yes, you can pass whatever you want through middle-ware which can be assign on a variable. Beside, if you tell your actual problem exactly what you want to do, then someone may easily help you out with some other/better way. – Imran Dec 04 '16 at 13:36
  • @Al-ImranAhmed If so, how? I have actually few problems, and all can be solved by passing some complex structure into middleware. This particular is about resolving url parameter from relation. I couldn't find how to pass variable (I found soultions for strings only) for middleware - and this is what I'am asking for. TIA – kadet Dec 04 '16 at 14:00
  • Where is the param coming from? Is it posted from a form? – Wistar Dec 04 '16 at 17:18
  • @Wistar No. Just plain variable defined in routes file. – kadet Dec 04 '16 at 17:26
  • @Kacper'Kadet'Donat That's the problem. I do not see why you would have to do that – Wistar Dec 04 '16 at 23:33

2 Answers2

1

Although I am still not sure from where you would set this parameter, in case you want to pass it through from your routes file, you could try something with either

Grouping:

Route::group(['middleware' => 'somemiddleware'], function() {
  Route::group(['modifiers' => [
    function() { return '1'; }, 
    function() { return '2'; }
  ]], function() {
    Route::get('/foo', function() {
      echo 'bar..';
    });
    // some other routes here
  });

.. or, individually for each route:

Route::group(['middleware' => 'somemiddleware'], function() {    
  Route::get('/foo', ['modifiers' => [
      function() { return '1'; },
      function() { return '2'; }
  ], 'uses' => function() {
      echo 'foo..';
  }]);
});

Now, using this workaround, the array of modifiers will be passed on the route's action, which can also be accessed in the middleware context:

class Middleware
{
  public function handle($request, Closure $next)
  {
    foreach($this->getModifiers($request) as $name => $closure) {
        $request->$name = $closure($request->name);
    }
    return $next($request);
  }
  protected function getModifiers($request) {
    $routeAction = $request->route()->getAction();

    return isset($routeAction['modifiers']) ? $routeAction['modifiers'] : array();
  }
}

I'm not sure if this workaround applies to your current situation, but it could put you in the right direction.

Jan Willem
  • 1,280
  • 1
  • 9
  • 9
0

I suggest that you evaluate your parameters inside the middleware

class Middleware
{

    public function handle($request, Closure $next)
    {
        $modifiers = $this->getModifiers();
        foreach($modifiers as $name => $closure) {
            $request->$name = $closure($request->name)
        }
        return $next($request);
    }

   protected function getModifiers(){

       //Logic you need to get to your param

       return $param;
   }
}
Wistar
  • 3,770
  • 4
  • 45
  • 70
  • 1
    Well, this is not what I'm looking for. I know that i can access global vars (Config vars are just fancy globals) from any context - including middleware - but this is not solution to problem, only strange workaround. Why not? I can pass parameters to for example throttle middleware, or can middleware and it's perfectly fine. I want to do the same thing with my middleware but instead of passing string like `60` to throttle i want to pass array like `[ 1, 2, function() { ... } ]` to middleware. Global var is not solution to any problem. – kadet Dec 05 '16 at 13:22
  • @Kacper'Kadet'Donat Instead of passing a variable, have you thought of adding a protected function to your middleware which would do the logic to determine the number of throttles? – Wistar Dec 05 '16 at 15:01
  • Well, how? And this is still not solution to my problem - passing complex parameter to middleware. If it's not possible - then ok, I'll found some better or worse workaround, like yours. Oh and if this is really not possible then please update your answer with that information, because for now it's not an answer for question 'How to pass parameter other than string to middleware?', and i'll accept and up vote it as some kind of valid workaround :) – kadet Dec 05 '16 at 17:59
  • @Kacper'Kadet'Donat Answer updated with the information you provided. – Wistar Dec 05 '16 at 19:02