In other words, service providers are like a funnel through which we pour "class" fuel into a tank called the "service container" of an engine called Laravel.
If we open config/app.php we will see an array with the name "provider"
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
.
.
.
],
These are some of the service providers provided together with laravel, i.e. basic services that are placed in the service container.
service provider
are they performed?If we look at the documentation on request lifecycle , the following files are executed at the start:
public/index.php
bootstrap/app.php
app/Http/Kernel.php
and its Middlewares
Service Providers
: content of this articleWhich service provider
are they loaded?
They are those definites in the array config/app.php
:
return [
// ... other configuration values
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
// ... other framework providers from /vendor
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* PUBLIC Service Providers - the ones we mentioned above
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
],
];
As we can see, there is a list of service provider
not public in the folder /vendor
, we should neither touch nor modify them. Those that interest us are below, with BroadcastServicerProvider
disabled by default, probably because it is rarely used.
All these service providers run from top to bottom, repeating the list twice:
register()
, useful for (eventually) executing something configured before the method boot()
.boot()
of all providers. Again, one by one, top to bottom, of the array 'providers'
.I Service Providers
included in Laravel, are all those present in the folder app/Providers
:
AppServiceProvider
AuthServiceProvider
BroadcastServiceProvider
EventServiceProvider
RouteServiceProvider
They are all PHP classes, each related to its own topic: App
, Auth
, Broadcasting
, Events
e Routes
. But they all have one thing in common: method boot()
.
Inside that method, we can write any code related to any of those sections: auth
, events
, route
, etc. In other words, Service Providers are just classes to register some global functionality.
They're separate as "providers" because they run very early in the application lifecycle, so something global is convenient here before the executing script gets to Models or Controllers.
Most of the functionality is in the RouteServiceProvider, here is the code:
class RouteServiceProvider extends ServiceProvider
{
public const HOME = '/dashboard';
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
});
}
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
}
}
This is the class where the files are configured route
, with routes/web.php
e routes/api.php
included by defaultdefinita. Note that for the API there are also different configurations: Endpoint prefix /api
and middleware api
for all routes
.
We can edit the service providers
, which are not in the folder /vendor
. Customizing these files is done when you have many paths and want to separate them into specific files. You create routes/auth.php
and put the paths there, then you "enable" that file in the method boot()
di RouteServiceProvider
, just add the third sentence:
`Route::middleware('web') // or maybe you want another middleware?
->group(base_path('routes/auth.php'));
AppServiceProvider
it's empty. A typical example of adding code AppServiceProvider
, is about disabling lazy loading in Eloquent . To do this, you just need add two lines in the method boot()
:
// app/Providers/AppServiceProvider.php
use Illuminate\Database\Eloquent\Model;
public function boot()
{
Model::preventLazyLoading(! $this->app->isProduction());
}
This will throw an exception if a relationship model is not loaded.
service provider
customIn addition to the pre filesdefinites, we can easily create a new one Service Provider
, related to other topics than those predefifinished as auth
/event
/routes
.
A fairly typical example is the view configuration Blade
. We can create a directive Blade
, and then add that code into the method boot(
) of any service provider
, including the default AppServiceProvider
. Let's now create a ViewServiceProvider
separate.
We can generate it with this command:
php artisan make:provider ViewServiceProvider
Which will generate the class so predefinite:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
//
}
}
As we can see inside there are two methods:
The register() method allows us to definish links to our service container. For example, in the following code:
public function register()
{
$this->app->singleton(my_class, function($app){
return new MyClass($app);
});
}
$this->app is a global variable in laravel that a singleton class can access through the app.
Singleton is a feature. When applying this feature, we are informing the application that whatever class is passed as a parameter in the app should only have one instance in the whole application. This means that MyClass will be resolved once and will have only one instance, which can be accessed using the my_class variable.
The boot() method allows you to access all services previously registered using the register method. You can then include the entire service in your application using this method.
Going back to the previous example, let's remove the method register()
and within boot()
add the Blade directive code:
use Illuminate\Support\Facades\Blade;
public function boot()
{
Blade::directive('datetime', function ($expression) {
return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
});
}
Another example of ViewServiceProvider
it concerns View Composers
, here is the snippet from the official Laravel site :
use App\View\Composers\ProfileComposer;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ViewServiceProvider extends ServiceProvider
{
public function boot()
{
// Using class based composers...
View::composer('profile', ProfileComposer::class);
// Using closure based composers...
View::composer('dashboard', function ($view) {
//
});
}
}
To run, this new provider must be added/registered to the in provider array config/app.php
:
return [
// ... other configuration values
'providers' => [
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
// Add your provider here
App\Providers\ViewServiceProvider::class,
],
];
Ercole Palmeri
You may also be interested in:
The naval sector is a true global economic power, which has navigated towards a 150 billion market...
Last Monday, the Financial Times announced a deal with OpenAI. FT licenses its world-class journalism…
Millions of people pay for streaming services, paying monthly subscription fees. It is common opinion that you…
Coveware by Veeam will continue to provide cyber extortion incident response services. Coveware will offer forensics and remediation capabilities…