21 octobre 2021 172.839K

Formation Laravel : Services Providers et Facades

1. Les Services Providers & les Facades

Tout d’abord un Service est tout simplement du code pour effectuer une certaine tâche.

Les Services Providers (« services fournisseurs» en français), eux, permettent de charger des Class dans notre Application et de les instancier une seule fois.

Tous nos Services Providers se trouvent dans le fichier app.php situé dans le dossier /config, dans un array 'providers'.

/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/

'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,
    Illuminate\Database\DatabaseServiceProvider::class,
    Illuminate\Encryption\EncryptionServiceProvider::class,
    Illuminate\Filesystem\FilesystemServiceProvider::class,
    Illuminate\Foundation\Providers\FoundationServiceProvider::class,
    Illuminate\Hashing\HashServiceProvider::class,
    Illuminate\Mail\MailServiceProvider::class,
    Illuminate\Notifications\NotificationServiceProvider::class,
    Illuminate\Pagination\PaginationServiceProvider::class,
    Illuminate\Pipeline\PipelineServiceProvider::class,
    Illuminate\Queue\QueueServiceProvider::class,
    Illuminate\Redis\RedisServiceProvider::class,
    Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
    Illuminate\Session\SessionServiceProvider::class,
    Illuminate\Translation\TranslationServiceProvider::class,
    Illuminate\Validation\ValidationServiceProvider::class,
    Illuminate\View\ViewServiceProvider::class,

    /*
     * Package Service Providers...
     */

    /*
     * Application Service Providers...
     */
    App\Providers\AppServiceProvider::class,
    App\Providers\AuthServiceProvider::class,
    // App\Providers\BroadcastServiceProvider::class,
    App\Providers\EventServiceProvider::class,
    App\Providers\RouteServiceProvider::class,

],

Vous pouvez notamment retrouver le Service Provider concernant les Routes de notre application :
App\Providers\RouteServiceProvider

Voyons ce qui se trouve dans ce fichier :

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
    /**
        * This namespace is applied to your controller routes.
        *
        * In addition, it is set as the URL generator's root namespace.
        *
        * @var string
        */
    protected $namespace = 'App\Http\Controllers';

    /**
        * Define your route model bindings, pattern filters, etc.
        *
        * @return void
        */
    public function boot()
    {
        //

        parent::boot();
    }

    /**
        * Define the routes for the application.
        *
        * @return void
        */
    public function map()
    {
        $this->mapApiRoutes();

        $this->mapWebRoutes();

        //
    }

    /**
        * Define the "web" routes for the application.
        *
        * These routes all receive session state, CSRF protection, etc.
        *
        * @return void
        */
    protected function mapWebRoutes()
    {
        Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));
    }

    /**
        * Define the "api" routes for the application.
        *
        * These routes are typically stateless.
        *
        * @return void
        */
    protected function mapApiRoutes()
    {
        Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));
    }
}

Nous remarquons donc brièvement certains éléments :
• une variable $namespace qui est le namespace où se trouve tous nos Controllers
• une fonction boot() qui permet de lancer le code au démarrage de l’application
• une fonction map() qui définit toutes les routes de notre application en faisant appelle aux méthodes mapWebRoutes() et mapApiRoutes().
• Cette fonction mapWebRoutes() où l’on aperçoit de nouveau cette Class Route ! Mais cette fois on sait d’où elle vient, plus haut nous pouvons voir son namespace :

use Illuminate\Support\Facades\Route;

Il s’agit comme indiqué d’une Facade, en ouvrant ce fichier on découvre les Class utilisées.

<?php

namespace Illuminate\Support\Facades;

/**
    * @method static \Illuminate\Routing\Route get(string $uri, \Closure|array|string|callable|null $action = null)
    * @method static \Illuminate\Routing\Route post(string $uri, \Closure|array|string|callable|null $action = null)
    * @method static \Illuminate\Routing\Route put(string $uri, \Closure|array|string|callable|null $action = null)
    * @method static \Illuminate\Routing\Route delete(string $uri, \Closure|array|string|callable|null $action = null)
    * @method static \Illuminate\Routing\Route patch(string $uri, \Closure|array|string|callable|null $action = null)
    * @method static \Illuminate\Routing\Route options(string $uri, \Closure|array|string|callable|null $action = null)
    * @method static \Illuminate\Routing\Route any(string $uri, \Closure|array|string|callable|null $action = null)
    * @method static \Illuminate\Routing\Route match(array|string $methods, string $uri, \Closure|array|string|callable|null $action = null)
    * @method static \Illuminate\Routing\RouteRegistrar prefix(string  $prefix)
    * @method static \Illuminate\Routing\RouteRegistrar where(array  $where)
    * @method static \Illuminate\Routing\PendingResourceRegistration resource(string $name, string $controller, array $options = [])
    * @method static \Illuminate\Routing\PendingResourceRegistration apiResource(string $name, string $controller, array $options = [])
    * @method static void apiResources(array $resources)
    * @method static \Illuminate\Routing\RouteRegistrar middleware(array|string|null $middleware)
    * @method static \Illuminate\Routing\Route substituteBindings(\Illuminate\Support\Facades\Route $route)
    * @method static void substituteImplicitBindings(\Illuminate\Support\Facades\Route $route)
    * @method static \Illuminate\Routing\RouteRegistrar as(string $value)
    * @method static \Illuminate\Routing\RouteRegistrar domain(string $value)
    * @method static \Illuminate\Routing\RouteRegistrar name(string $value)
    * @method static \Illuminate\Routing\RouteRegistrar namespace(string $value)
    * @method static \Illuminate\Routing\Router|\Illuminate\Routing\RouteRegistrar group(array|\Closure|string $attributes, \Closure|string $routes)
    * @method static \Illuminate\Routing\Route redirect(string $uri, string $destination, int $status = 302)
    * @method static \Illuminate\Routing\Route permanentRedirect(string $uri, string $destination)
    * @method static \Illuminate\Routing\Route view(string $uri, string $view, array $data = [])
    * @method static void bind(string $key, string|callable $binder)
    * @method static void model(string $key, string $class, \Closure|null $callback = null)
    * @method static \Illuminate\Routing\Route current()
    * @method static string|null currentRouteName()
    * @method static string|null currentRouteAction()
    *
    * @see \Illuminate\Routing\Router
    */
class Route extends Facade
{
    /**
        * Get the registered name of the component.
        *
        * @return string
        */
    protected static function getFacadeAccessor()
    {
        return 'router';
    }
}

Prenons donc la Class \Illuminate\Routing\Router. Dans cette Class on retrouve notre méthode get() que nous avions utilisée dans notre fichier web.php ainsi que plein d’autres.

Voici ci-dessous un petit extrait de cette Class Router.

class Router implements RegistrarContract, BindingRegistrar
{

    // ... // 
    
    /**
        * Register a new GET route with the router.
        *
        * @param  string  $uri
        * @param  \Closure|array|string|null  $action
        * @return \Illuminate\Routing\Route
        */
    public function get($uri, $action = null)
    {
        return $this->addRoute(['GET', 'HEAD'], $uri, $action);
    }

    /**
        * Register a new POST route with the router.
        *
        * @param  string  $uri
        * @param  \Closure|array|string|null  $action
        * @return \Illuminate\Routing\Route
        */
    public function post($uri, $action = null)
    {
        return $this->addRoute('POST', $uri, $action);
    }

    /**
        * Register a new PUT route with the router.
        *
        * @param  string  $uri
        * @param  \Closure|array|string|null  $action
        * @return \Illuminate\Routing\Route
        */
    public function put($uri, $action = null)
    {
        return $this->addRoute('PUT', $uri, $action);
    }
    
    // ... //
    
}

Ok dans la Class du Service Provider on sait d’où vient la Class Route… Mais quand est-il de notre fichier web.php ? Il n’y a pas de use Illuminate\Support\Facades\Route;

Grâce aux Alias de Class. Ils se trouvent juste en dessous du tableau 'providers' dans votre fichier app.php que nous venons de voir :

/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/

'aliases' => [

    'App' => Illuminate\Support\Facades\App::class,
    'Arr' => Illuminate\Support\Arr::class,
    'Artisan' => Illuminate\Support\Facades\Artisan::class,
    'Auth' => Illuminate\Support\Facades\Auth::class,
    'Blade' => Illuminate\Support\Facades\Blade::class,
    'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
    'Bus' => Illuminate\Support\Facades\Bus::class,
    'Cache' => Illuminate\Support\Facades\Cache::class,
    'Config' => Illuminate\Support\Facades\Config::class,
    'Cookie' => Illuminate\Support\Facades\Cookie::class,
    'Crypt' => Illuminate\Support\Facades\Crypt::class,
    'DB' => Illuminate\Support\Facades\DB::class,
    'Eloquent' => Illuminate\Database\Eloquent\Model::class,
    'Event' => Illuminate\Support\Facades\Event::class,
    'File' => Illuminate\Support\Facades\File::class,
    'Gate' => Illuminate\Support\Facades\Gate::class,
    'Hash' => Illuminate\Support\Facades\Hash::class,
    'Lang' => Illuminate\Support\Facades\Lang::class,
    'Log' => Illuminate\Support\Facades\Log::class,
    'Mail' => Illuminate\Support\Facades\Mail::class,
    'Notification' => Illuminate\Support\Facades\Notification::class,
    'Password' => Illuminate\Support\Facades\Password::class,
    'Queue' => Illuminate\Support\Facades\Queue::class,
    'Redirect' => Illuminate\Support\Facades\Redirect::class,
    'Redis' => Illuminate\Support\Facades\Redis::class,
    'Request' => Illuminate\Support\Facades\Request::class,
    'Response' => Illuminate\Support\Facades\Response::class,
    'Route' => Illuminate\Support\Facades\Route::class,
    'Schema' => Illuminate\Support\Facades\Schema::class,
    'Session' => Illuminate\Support\Facades\Session::class,
    'Storage' => Illuminate\Support\Facades\Storage::class,
    'Str' => Illuminate\Support\Str::class,
    'URL' => Illuminate\Support\Facades\URL::class,
    'Validator' => Illuminate\Support\Facades\Validator::class,
    'View' => Illuminate\Support\Facades\View::class,
    'Input' => Illuminate\Support\Facades\Input::class,
],

Ce qui signifie que que dans web.php au lieu de taper tout ça :

Illuminate\Support\Facades\Route::get('/', 'WelcomeController@index');

Je peux simplement taper ça :

Route::get('/', 'WelcomeController@index');

Il vous est expliqué que ces alias sont enregistrés quand votre application démarre et sont chargés en lazy load, donc elle n’entrave pas la performance de votre application.

Donc 3 choses à retenir ici :

• Le Service Provider charge et instancie les Class dans mon application.
• La Façade me fournit une interface static de mes Class
• L’alias me permet de simplifier ma syntaxe lorsque j’appelle ma Class.

Il est bien de prendre conscience de comment Laravel cache les choses car avoir un code clair et épuré c’est bien mais il vous faut tout de même avoir une vision de ce qu’il se passe derrière et que vous ne voyez pas tout ça comme de la magie.

2. Ajouter un Service Provider

Maintenant nous allons voir comment greffer une nouvelle fonctionnalité à notre application Laravel. En fait ce n’est qu’un prétexte pour vous faire installer un nouveau Service Provider qui vous sera très très utile : une barre de débug !!! 😀

Et oui ! Laravel n’a pas, à l’inverse de Symfony par exemple, de barre de débug mais qu’à cela ne tienne quelqu’un s’en est chargé ! (Vous vous rappelez quand je vous disais que Laravel a une très grosse communauté ? En voici la preuve ! 🙂 ).

Pour découvrir cette superbe barre de débug je vous renvoie au Github de son créateur Barry : Barryvdh – Laravel Debugbar

Nous pouvons faire un très rapide recap de la manière d’installer cette Debugbar. Vous allez voir c’est extrêmement simple.

1 – Lancez la commande suivante dans votre terminal

composer require barryvdh/laravel-debugbar --dev

2 – Ajoutez les lignes suivantes respectivement dans vos tableaux de ‘providers’ et ‘aliases’

'providers' => [
    // ...
    Barryvdh\Debugbar\ServiceProvider::class, // 'providers'
],

'aliases' => [
    // ...
    'Debugbar' => Barryvdh\Debugbar\Facade::class, // dans 'aliases'
],

3 – Vérifiez que la valeur de PHP_DEBUG est bien à true dans votre fichier .env

(Souvenez-vous votre fichier .env se trouve à la racine de votre projet).

Et nous voici maintenant avec une Debugbar qui nous sera bien utile en développement. Vous pourrez y voir les requêtes faites à la base de données, les views utilisées, les données de session etc…

Laravel Debug bar

Besoin d'une formation personalisée ?

Avis

4,9
Rated 4.9 out of 5
Excellent88%
Splendide !12%
Sympa0%
Sans plus0%
Pas terrible0%

Pas de titre

Rated 5 out of 5
15 avril 2024

cool

paul

Pas de titre

Rated 5 out of 5
2 avril 2024
Evelyn

Pas de titre

Rated 4 out of 5
2 avril 2024

Merci beaucoup pour ce cour.

adil

Pas de titre

Rated 5 out of 5
7 mars 2024

super

hajar

Pas de titre

Rated 5 out of 5
21 juin 2023

Merci énormément je suis sur exciter à cause de ce cours

Kassi Patrick