Search code examples
phplaraveldependency-injectionlaravel-5middleware

Passing objects to a laravel middleware


According to the documentation, a middleware may be parametrised with static values in the routes file:

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

What if I need to pass in a service?


My motivation for doing this is avoiding Facades because even though they are supposed to be mockable, I am running into problems already at the first try. Mockery/mockery does some crazy eval stuff and I am not wiling to debug that. In essence some class is declared twice and PHP chokes with a fatal error. It happens probably because I am following the example incorrectly, but let us leave it at that. I do not want to rely on Facades.

I do not want to learn about why Facades are awesome, because dependency declaration in constructors is enough to make me happy.


I tried following the route action, but I cant not understand what happens in Route::parseAction($action). Where are the middlewares instantiated? Is there a standard way to pass objects to middewares?


Solution

  • If you want a service passed to the middleware you need to declare it as a dependency of middleware's constructor. As an example look at the RedirectIfAuthenticated middleware that exists by default in Laravel app - it gets fetched the Guard object, which is the one you can also access via Auth facade.

    class RedirectIfAuthenticated
    {
      /**
       * The Guard implementation.
       *
       * @var Guard
       */
      protected $auth;
    
      /**
       * Create a new filter instance.
       *
       * @param  Guard $auth
       *
       * @return void
       */
      public function __construct(Guard $auth)
      {
        $this->auth = $auth;
      }
    
      //rest of the code