Hion Coding - Blogs share everything
  • HOME
  • ABOUT
  • POSTS
  • CONTACT
  • TOOLS
    CÂU HỎI VÕ ĐÀI TỐI THƯỢNG CONVERT IMAGE TO WEBP
Elevating Junior Laravel Developers: Learn about Service Provider

Elevating Junior Laravel Developers: Learn about Service Provider

Hion Coding - Blogs share everything
Admin Hion Coding Blogs vochilong.work@gmail.com
3rd January 2024

PHP/Laravel

Elevating Junior Laravel Developers: Learn about Service Provider

Reference: Viblo

Index Elevating Junior Laravel Developers
 series:

  1. Elevating Junior Laravel Developers: Recipes & Best Practices
  2. Elevating Junior Laravel Developers: Learn about Service containers
  3. Elevating Junior Laravel Developers: Learn about Service Provider
  4. Elevating Junior Laravel Developers: Learn about Facade
  5. Elevating Junior Laravel Developers: Learn about Contract


In the previous article, we learned about the central component of Laravel Framework, which is the Service Container.
In general, the Service Container in Laravel is the place to manage class dependencies and perform dependency injection.

You just need to bind a Class, Interface or any keyword to the Service Container to be able to resolve them anywhere.

Laravel itself also binds many things into the Service Container so that we can call them for use when needed, in many different ways.

In this article, we will learn when, where, and how Laravel does that binding. From there, we will be able to understand and find a way to easily replace an existing Laravel service with a service we implement ourselves.


Service Provider - Declared in config/app.php

Surely you have touched this config file a lot when working with Laravel. Not only is it a place to set up project parameters such as debug mod, url, timezone, local..., in the config/app.php file, you will also see another important item, which is providers, with comment lines in below is

/*
 * Laravel Framework Service Providers...
 */

/*
 * Application Service Providers...
 */

Well, this is where registering service container bindings begins. However, instead of always using app()->bind(), app()->instance() ... as mentioned in the previous article, in the bindings declaration section in the config/app.php file Here we pass in the class names. Those classes are often named SomethingServiceProvider, such as Illuminate\Session\SessionServiceProvider, Illuminate\View\ViewServiceProvider, Illuminate\Routing\ControllerServiceProvider...

In addition, you may have noticed that in Laravel packages that you often use, such as Laravel Debugbar, Laravel Markdown, Laravel IDE Helper..., when installing, those packages require you to add their ServiceProvider class to the providers section in config/app.php. In other words, third-party packages for Laravel also often provide Service Providers to make the installation and use process easier.

So what exactly is a Service Provider?


Service Provider - From concept to practice

As mentioned above, in the created project, besides the bootstrap/app.php file that declares the binding Kernel and Exception, you will not see anywhere else that declares the binding directly. Instead, there is only one place to declare the class that will perform the binding, those classes are Service Providers.
Service Providers are all extended from an abstract class that Laravel provides, which is Illuminate\Support\ServiceProvider. If you look at the code of this class, you will see that it includes an abstract function called register, which means that the Service Provider you write will be required to declare this register method. And this is where you do the binding to the Service Container. For example, let's look at a simple Service Provider called HashServiceProvider to see what it has.

Normally, in the config/app.php file, you will see that providers are declared as Illuminate\Hashing\HashServiceProvider::class, based on that name we can find the provider file at /vendor/laravel/framework/src /Illuminate/Hashing/HashServiceProvider.php:

class HashServiceProvider extends ServiceProvider
{
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('hash', function () { return new BcryptHasher; });
    }
}

So we can see that in HashServiceProvider we have done the binding of the hash keyword, which can be considered the service name, with an instance of the BcryptHasher class via the singleton method. So:

  • get_class(app()->make('hash')) will return Illuminate\Hashing\BcryptHasher;
  • app()->make('hash') === app()->make('hash') will return true, because every time we call app()->make('hash') we will receive the same object.

Besides, you can see that in the HashServiceProvider class above, we also have a protected variable called $defer. Declaring $defer = true will help the binding process not be performed until the service is called. In other words, according to the example above, for each request, an instance of BcryptHasher will not be created from the beginning, but only when we call app()->make('hash') for the first time. The new binding takes place (and will only take place once, from future calls it will already be in the Service Container so you just need to get it out). To do this, besides the register function, in case $defer = true, we need to have another function that tells Laravel what service this provider will return, which is the provides function. Specifically, the HashServiceProvider's provides function looks like this:

public function provides()
{
    return ['hash'];
}

So we can summarize the process of Laravel handling Service Providers as follows:

  • Check whether the variable $defer is true or false. If it is false, do the binding immediately by running the register function.
  • If $defer is true, the register function will not run but instead will store information about what service that service provider will return through the results of the provides function. So the binding did not take place.
  • When we request to resolve a service from the Service Container, Laravel will check to see if it is a deferred service or not. If so, Laravel will run the register function of the corresponding provider. At this time the binding will take place. And of course, after binding is complete, that service will be removed from the list of deferred services. Finally, the resolve will be performed.

Loading services defer like this will help improve the performance of your application, as services are only loaded when they are needed. Of course, if your service is absolutely necessary and must be used, you do not need to declare $defer = true, it will only increase the processing when called for the first time.

In addition, another thing to note is that you should only declare binding in the register function, not declare event listeners, routes or other complex processing. Because you know that Laravel will traverse a series of providers to perform binding, it is possible that you will encounter a situation where you call a service when its provider has not yet been processed.

If you want to write processes that require other services, you should write it in the boot function, because this function will only be called when all service providers have been traversed, and so, of course, you will be able to access all services.


Service Provider - Application

Service Provider is the key to the process of bootstrapping a Laravel Application. Imagine your application as a Container, and when it launches, it will put the necessary services into that container, then what you need to do is retrieve the necessary services at the necessary time from the container. to process an incoming request.

Being built on a combination of such services has helped Laravel have the necessary flexibility and versatility. While working with Laravel, once you understand the concept, role, and how to use Service Provider, you can completely apply it to cases such as:

  • Bootstrapping application: When looking at the providers declaration in config/app.php, you will see that there is a section for Application Service Providers, and in there is App\Providers\AppServiceProvider. Laravel has created an ideal place for you to add your bindings or bootstrapping configs. For example, if you want to write your own validations using Validator::extend, or want to add HTML Macros, or any other logic you need to run before processing the request.. ., then the boot function in AppServiceProvider is where you should do those things.
  • Write your own services: If your application has too many things that need to be bootstrapped and you feel that writing them all in the boot function in AppServiceProvider is not good, you should think about writing many different Service Providers. In addition, when your application is expanded and has a large structure, an important question is how to organize the business logic properly. And of course, writing services and declaring them through a Service Provider is one of the ways you should try. For example, your application has many places that require working with images, and along with that will come functions and processes that handle images. Maybe then you will need an Image class that holds the logic functions, and an ImageServiceProvider, with binding and bootstrapping handling in there
  • Working with Laravel packages: As mentioned in the beginning, Laravel packages often have their own Service Providers. Now you understand what it is for, and why it needs to be declared in the config/app.php file. And vice versa, when you want to write a Laravel package for others to use, you should also remember to write a Service Provider for it. Then your service will be able to be used more easily and in a more Laravel style.
  • Replace Laravel's default service: Laravel services communicate with each other through Service Container. For example, if one of your processes needs the Authentication service, you can get it out by using app()->make('auth') and then continue with the next processing. So your process needs service auth to run, but it does not completely depend on a fixed Auth class. This also means that you can absolutely write your own service, your own provider, and replace Laravel's provider declaration in config/app.php with your own provider declaration, as long as your service class is also the same. has the necessary methods like Laravel's default service class (usually it will have to implement a certain interface). For example, a Laravel package that I often use is MultiAuth (https://github.com/Kbwebs/MultiAuth) (a package for Laravel 5.1, but with 5.2, Laravel itself already supports Multi Auth). By using the above package, I can authenticate with many different tables, such as users and admins, for example. What I need to do to use it is simply change the default service provider, from Illuminate\Auth\AuthServiceProvider to Kbwebs\MultiAuth\AuthServiceProvider, or Illuminate\Auth\Passwords\PasswordResetServiceProvider to Kbwebs\MultiAuth\PasswordResets\PasswordResetServiceProvider... and a few other small configs.


Epilogue

So I have introduced the Service Provider, its role, meaning, and how it is being used in a Laravel project. Of course, it just stops at the basic level. You can read the framework's code yourself to better understand how Laravel loads and runs the Service Provider.

Or like the providers declaration in the config/app.php file, not all services are declared there. For example, if you type app()->make('request'), app()->make('events'), or app()->make('url'), you will receive the corresponding object, However, we do not see any RequestServiceProvider, EventsServiceProvider or UrlServiceProvider in the declaration in config/app.php. Even searching the Laravel framework, you can't find anything called RequestServiceProvider or UrlServiceProvider anywhere. So where and when are those services bound, or if there is a corresponding Service Provider, how is that provider called? Try to find the answer yourself, surely when you finish researching, you will find yourself understanding more about how Laravel works.
 

Reference: Viblo

Thank you! Good luck! Hion Coding


Integrating CKEditor 5 In Laravel 10 Using Vite

9th April 2024

Integrating CKEditor 5 In Laravel 10 Using Vite

PHP/Laravel

Laravel Eloquent Tips🔥 🚀

3rd January 2024

Laravel Eloquent Tips🔥 🚀

PHP/Laravel

Elevating Junior Laravel Developers: Learn about Contract

3rd January 2024

Elevating Junior Laravel Developers: Learn about Contract

PHP/Laravel

Elevating Junior Laravel Developers: Learn about Facade

3rd January 2024

Elevating Junior Laravel Developers: Learn about Facade

PHP/Laravel

Hion Coding - Blogs share everything


© 2025 Hion Coding DMCA.com Protection Status