Conditionally Loading Service Providers in Laravel 5
!Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.
Since Laravel 5 flattened a lot of the environment-specific structures, much of the configuration that was once stored in different config directories for each environment has now moved into .env
files.
But one that can't just live in .env
is the environment-dependent loading of service providers.
On a project we're working on, we want to register our error handlers in service providers, and we want to register a different error handler depending on the environment. We have two: ProductionErrorHandler
and VerboseErrorHandler
, the second of which is for development environments.
Loading service providers normally
In case you're not familiar, defining normal (non-environment-specific) Service Providers happens in /config/app.php
. There's a providers
array there that looks a bit like this:
'providers' => [
/*
* Laravel Framework Service Providers...
*/
'Illuminate\Foundation\Providers\ArtisanServiceProvider',
'Illuminate\Auth\AuthServiceProvider',
'Illuminate\Bus\BusServiceProvider',
...
]
So, if your service provider should be loaded in every environment, just toss it into that array and you're good to go.
Loading service providers conditionally
However, if you want to make it conditional, you'll need to head over to /app/Providers/AppServiceProvider.php
. This file is the general place you're going to want to be booting and registering anything that's not handled in another service provider, so this is a place you can go to conditionally register your service providers.
Here's what it looks like right now:
<?php namespace app\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* This service provider is a great spot to register your various container
* bindings with the application. As you can see, we are registering our
* "Registrar" implementation here. You can add your own bindings too!
*
* @return void
*/
public function register()
{
$this->app->bind(
'Illuminate\Contracts\Auth\Registrar',
'App\Services\Registrar'
);
}
}
So, let's do our switch.
// AppServiceProvider.php
public function register()
{
$this->app->bind(
'Illuminate\Contracts\Auth\Registrar',
'App\Services\Registrar'
);
if ($this->app->environment('production')) {
$this->app->register('App\Providers\ProductionErrorHandlerServiceProvider');
} else {
$this->app->register('App\Providers\VerboseErrorHandlerServiceProvider');
}
}
$this->app->register()
will set up the service provider just like adding it to config/app.php
will, so its register()
and boot()
methods will get called at the appropriate times.
You could also use switch
instead of if
, or you could do your work based on other environment variables, or whatever else--but this is your current best bet to conditionally load service providers. Hope this helps!
Comments? I'm @stauffermatt on Twitter
Tags: laravel • laravel 5