Laravel Services Introduction


Example

Laravel allows access to a variety of classes called Services. Some services are available out of the box, but you can create them by yourself.

A service can be used in multiple files of the application, like controllers. Let's imagine a Service OurService implementing a getNumber() method returning a random number:

class SomeController extends Controller {
    
    public function getRandomNumber()
    {
        return app(OurService::class)->getNumber();
    }
}

To create a Service, it is only needed to create a new Class:

# app/Services/OurService/OurService.php

<?php
namespace App\Services\OurService;

class OurService 
{
    public function getNumber()
    {
        return rand();
    }
}

At this time, you could already use this service in a controller, but you would need to instantiate a new object each time you would need it:

class SomeController extends Controller {
    
    public function getRandomNumber()
    {
        $service = new OurService();
        return $service->getNumber();
    }

    public function getOtherRandomNumber()
    {
        $service = new OurService();
        return $service->getNumber();
    }
}

That is why the next step is to register your service into the Service Container. When you register you Service into the Service Container, you don't need to create a new object every time you need it.

To register a Service into the Service Container, you need to create a Service Provider. This Service Provider can:

  1. Register your Service into the Service Container with the register method)
  2. Injecting other Services into your Service (dependencies) with the boot method

A Service Provider is a class extending the abstract class Illuminate\Support\ServiceProvider. It needs to implement the register() method to register a Service into the Service Container:

# app/Services/OurService/OurServiceServiceProvider.php

<?php
namespace App\Services\OurService;

use Illuminate\Support\ServiceProvider;

class OurServiceServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton('OurService', function($app) {
            return new OurService();
        });
    }
}

All the Service Providers are saved in an array in config/app.php. So we need to register our Service Provider into this array:

return [

    ...

    'providers' => [

        ...

        App\Services\OurService\OurServiceServiceProvider::class,

        ...

    ],

    ...

];

We can now access our Service in a controller. Three possibilities:

  1. Dependency Injection:
<?php
namespace App\Http\Controllers;

use App\Services\OurService\OurService;

class SomeController extends Controller
{
    public function __construct(OurService $our_service)
    {
        dd($our_service->getNumber());
    }
}
  1. Access via the app() helper:
<?php
namespace App\Http\Controllers;

use App\Services\OurService\OurService;

class SomeController extends Controller
{
    public function getRandomNumber()
    {
        return app('OurService')->getNumber();
    }
}

Laravel provides Facades, imaginary classes that you can use in all of your projects and reflect a Service. To access your service more easily, you can create a Facade:

<?php
namespace App\Http\Controllers;

use Randomisator;

class SomeController extends Controller
{
    public function getRandomNumber()
    {
        return Randomisator::getNumber();
    }

}

To create a new Facade, you need to create a new Class extending Illuminate\Support\Facades\Facade. This class needs to implement the getFacadeAccessor() method and return the name of a service registered by a Service Provider:

# app/Services/OurService/OurServiceFacade.php

<?php
namespace App\Services\OurService;

use Illuminate\Support\Facades\Facade;

class OurServiceFacade extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'OurService';
    }
}

You also need to register your Facade into config/app.php:

return [

    ...

    'aliases' => [

        ....

        'Randomisator' => App\Services\OurService\OurServiceFacade::class,
    ],

];

The Facade is now accessible anywhere in your project.

If you want to access your service from your views, you can create a helper function. Laravel ships with some helpers function out of the box, like the auth() function or the view() function. To create a helper function, create a new file:

# app/Services/OurService/helpers.php    

if (! function_exists('randomisator')) {
    /**
     * Get the available OurService instance.
     *
     * @return \App\ElMatella\FacebookLaravelSdk
     */
    function randomisator()
    {
        return app('OurService');
    }
}

You also need to register this file, but in your composer.json file:

{

    ...

    "autoload": {
        "files": [
            "app/Services/OurService/helpers.php"
        ],

        ...
    }
}

You can now use this helper in a view:

<h1>Here is a random number: {{ randomisator()->getNumber() }}</h1>