What is service provider in Laravel?

The service provider in Laravel are one of the core functionalities of Laravel. In this article I am going to discuss about Laravel’s service providers.

Service provider in Laravel

Service providers are used to configure our application. Service providers are used to register services, such as middleware, routes, database connections, and more. Service providers are not loaded on each request, but only loaded when the service is needed.

Default service providers

The default service providers in Laravel are stored in the app\Providers path.

The default service providers in Laravel are as follows.

  • AppServiceProvider
  • AuthServiceProvider
  • BroadcastServiceProvider
  • EventServiceProvider
  • RouteServiceProvider

These core service providers are listed in the providers array in config\app.php.

'providers' => ServiceProvider::defaultProviders()->merge([
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class
])->toArray(),

The default providers in the app\Providers path are PHP classes. Now we will know about the common methods of these classes.

The register and the boot Methods

Most of these classes have a register method and all of these have a boot method.

Register method is used to bind things to the service container.

Boot method is called after all other service providers have been registered.

Now we will know how to create custom service provider in Laravel

Create service providers

We can use the following artisan command to create a custom service provider named TestServiceProvider.

Create service providers using artisan command

php artisan make:provider TestServiceProvider

This will create the TestServiceProvider.php file in app/Providers directory.

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class TestServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {
        //        
    }

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        //
    }
}

Any method of the service providers can access the $app property which provides access to the service container.

Now we will change the register method of this service provider and use bind and singleton method here.

Before that we will briefly know about bind and singleton method.

The bind and the singleton method

Earlier in this article we have learned that Register method is used to bind things to the service container.

The bind method is used to bind a class or value into the container. In this case, a new instance will be created for every request.

The singleton method is also used to bind a class or value into the container, but the same instance will be returned for every request.

Modify the register method by using the binding methods

Now we will change the register method in TestServiceProvider and then the code of TestServiceProvider will be as follows.

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

use Illuminate\Support\Str;

class TestServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {  
        $this->app->bind('RandomChange', function(){
            return Str::random();
        });
	$this->app->singleton('RandomUnique', function(){
            return Str::random();
        });
    }

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        //
    }
}

Now we will create two routes in routes\web.php to understand the output from the browser.

Create routes

Here we will use make method. The make method used to resolve a class instance from the container.

<?php
use Illuminate\Support\Facades\Route;

Route::get('/providerbind', function () {
    echo "String 1: ";
    echo app()->make('RandomChange');
    echo "<br />";
    echo "String 2: ";
    echo app()->make('RandomChange');
});

Route::get('/providersingleton', function () {
    echo "String 1: ";
    echo app()->make('RandomUnique');
    echo "<br />";
    echo "String 2: ";
    echo app()->make('RandomUnique');
});

Now we will browse the URLs of these two routes and see the output.

Registering provider

Now we will register the TestServiceProvider within providers key in config/app.php.

...
'providers' => ServiceProvider::defaultProviders()->merge([
...
App\Providers\TestServiceProvider::class,
])->toArray(),
..

Browser output

Now if we browse http://<SITEURL>/providerbind, the output will be like:

String 1: YtuNEWQsX9qrWnjN
String 2: 7GPeRjWTxAfptpSx

These are random strings. Here we can see that the value of string 1 and the value of string 2 are different.

The reason for this is that for ‘RandomChange’, we used bind method in service provider’s register method and we know that for bind method a new instance will be created for every request. So here we get two different strings.

Now if we browse http://<SITEURL>/providersingleton, the output will be like:

String 1: Na2qjYazWS84PNeL
String 2: Na2qjYazWS84PNeL

These are also random strings. Here we can see that the value of string 1 and the value of string 2 are same.

The reason for this is that for ‘RandomUnique’, we used singleton method in service provider’s register method and we know that for singleton method the same instance will be returned for every request. So here we get same strings for string 1 and string 2.

After the register method in TestServiceProvider we will now modify the boot method.

I previously wrote about How to write custom if statements in Laravel in a post. There I created the custom disk directive. Here I will create another custom if directive named appdb and through this directive we can know the current db name of the system.

Modify the boot method

Now we will change the boot method in TestServiceProvider and the code of TestServiceProvider will be as follows.

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

use Illuminate\Support\Facades\Blade;

class TestServiceProvider extends ServiceProvider
{ 
    
    /**
     * Register services.
     */
    public function register(): void
    {
        // 
    }

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {        
        Blade::if('appdb', function ($value) {
            return config('database.default') === $value;
        });
    }
}

Here we have defined a custom appdb directive that will check the default db connection that is used by the framework and is set in default property of config\database.php. In our application default database is mysql.

Now we will create a route in routes\web.php to understand the output of custom directive from the browser.

Create route

Here we will create viewdb route.

<?php

use Illuminate\Support\Facades\Route;

Route::get('/viewdb', function () {
    return view('viewdb');
});

Now we will create view file.

Create view file

We will create viewdb.blade.php in resources\views\viewdb.blade.php.

@appdb('mysql')
MySQL
@elseappdb('sqlite')
SQLite
@elseappdb('pgsql')
PostgreSQL
@elseappdb('sqlsrv')
SQL Server
@else
Other
@endappdb

Browser output for custom directive

Now if we browse http://<SITEURL>/viewdb, as default database is mysql in our application the output will be: MySQL.

In this post I discussed service providers of Laravel. The URL of official documentation of service providers in Laravel is: https://laravel.com/docs/10.x/providers

1 thought on “What is service provider in Laravel?”

  1. Pingback: Webtechbased

Comments are closed.