Passer au contenu principal

Qu’est-ce qu’une façade

Une façade fournit une interface « statique » aux classes disponibles dans le conteneur de services de l’application. Laravel inclut de nombreuses façades qui donnent accès à presque toutes ses fonctionnalités. Les façades agissent comme des « proxys statiques » vers des classes concrètes du conteneur de services, offrant une syntaxe concise et expressive tout en étant plus testables et plus flexibles que les méthodes statiques classiques. Toutes les façades Laravel sont définies dans le namespace Illuminate\Support\Facades.
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Route;

Route::get('/cache', function () {
    return Cache::get('key');
});
Il n’est pas nécessaire de comprendre totalement leur fonctionnement pour les utiliser. Commencez par les utiliser et poursuivez votre apprentissage de Laravel.

Fonctionnement des façades

Dans une application Laravel, une façade est une classe qui fournit un accès à un objet du conteneur. Ce mécanisme est assuré par la classe Facade. Toutes les façades de Laravel (et vos façades personnalisées) héritent de la classe de base Illuminate\Support\Facades\Facade. La classe Facade de base utilise la méthode magique __callStatic() pour déléguer les appels sur la façade à l’objet résolu par le conteneur.
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;
use Illuminate\View\View;

class UserController extends Controller
{
    /**
     * Affiche le profil de l'utilisateur donné.
     */
    public function showProfile(string $id): View
    {
        $user = Cache::get('user:'.$id);

        return view('profile', ['user' => $user]);
    }
}
En tête du fichier, on importe la façade Cache. Elle fait office de proxy vers l’implémentation de l’interface Illuminate\Contracts\Cache\Factory. Tous les appels via cette façade sont transmis à l’instance interne du service de cache. Regardons la classe Illuminate\Support\Facades\Cache : la méthode statique get n’y existe pas.
class Cache extends Facade
{
    /**
     * Retourne le nom d'enregistrement du composant.
     */
    protected static function getFacadeAccessor(): string
    {
        return 'cache';
    }
}
La façade Cache étend Facade et définit getFacadeAccessor(). Cette méthode retourne le nom du binding dans le conteneur. Quand on appelle une méthode statique sur Cache, Laravel résout le binding cache depuis le conteneur puis exécute la méthode demandée (ici get) sur l’objet obtenu.

Quand utiliser (ou éviter) les façades

Avantages des façades

Les façades offrent une syntaxe concise et mémorisable pour utiliser Laravel sans avoir à retenir des noms de classes longs à injecter et configurer. Grâce à l’utilisation particulière des méthodes dynamiques PHP, elles sont aussi faciles à tester.

Attention au scope creep

Le principal risque est le « gonflement » de vos classes. Les façades étant simples à utiliser et sans injection, on est tenté d’en ajouter de plus en plus. Avec l’injection de dépendances, un constructeur volumineux vous alerte visuellement. Restez donc attentif à la taille de vos classes et gardez leurs responsabilités restreintes.
Si une classe devient trop grande, envisagez de la découper en plusieurs classes plus petites.

Façades vs. injection de dépendances

L’un des grands atouts de l’injection est la possibilité de substituer l’implémentation d’une classe injectée. Utile pour les tests : on injecte un mock/stub et on vérifie les appels de méthodes. Les méthodes statiques réelles ne peuvent pas être mockées en général, mais les façades s’appuient sur des méthodes dynamiques qui délèguent au conteneur. On peut donc les tester comme une instance injectée.
use Illuminate\Support\Facades\Cache;

Route::get('/cache', function () {
    return Cache::get('key');
});
Vous pouvez écrire ce test pour vérifier que Cache::get a été appelée avec les bons arguments.
use Illuminate\Support\Facades\Cache;

test('exemple simple', function () {
    Cache::shouldReceive('get')
        ->with('key')
        ->andReturn('value');

    $response = $this->get('/cache');

    $response->assertSee('value');
});

Façades vs. helpers

Outre les façades, Laravel propose des fonctions « helper » pour les tâches courantes : créer une vue, déclencher un événement, dispatcher un job, envoyer une réponse HTTP, etc. Beaucoup de helpers font la même chose que la façade correspondante.
// Via la façade
return Illuminate\Support\Facades\View::make('profile');

// Équivalent avec le helper
return view('profile');
Il n’y a pas de différence réelle entre les deux. Vous pouvez tester le helper comme la façade équivalente.
use Illuminate\Support\Facades\Cache;

test('test du helper cache', function () {
    Cache::shouldReceive('get')
        ->with('key')
        ->andReturn('value');

    $response = $this->get('/cache');

    $response->assertSee('value');
});

Façades en temps réel

Les façades en temps réel permettent de traiter n’importe quelle classe de l’application comme une façade. Voyons d’abord un code sans façade en temps réel. Supposons que le modèle Podcast ait une méthode publish. Publier un podcast nécessite d’injecter une instance Publisher.
<?php

namespace App\Models;

use App\Contracts\Publisher;
use Illuminate\Database\Eloquent\Model;

class Podcast extends Model
{
    /**
     * Publie le podcast.
     */
    public function publish(Publisher $publisher): void
    {
        $this->update(['publishing' => now()]);

        $publisher->publish($this);
    }
}
Avec une façade en temps réel, on n’a plus besoin de passer explicitement Publisher tout en gardant la testabilité. On préfixe le namespace de la classe importée par Facades.
<?php

namespace App\Models;

use Facades\App\Contracts\Publisher;
use Illuminate\Database\Eloquent\Model;

class Podcast extends Model
{
    /**
     * Publie le podcast.
     */
    public function publish(): void
    {
        $this->update(['publishing' => now()]);

        Publisher::publish($this);
    }
}
À l’usage, l’interface ou la classe située après Facades est résolue par le conteneur pour obtenir l’implémentation du publisher.
<?php

use App\Models\Podcast;
use Facades\App\Contracts\Publisher;
use Illuminate\Foundation\Testing\RefreshDatabase;

pest()->use(RefreshDatabase::class);

test('podcast can be published', function () {
    $podcast = Podcast::factory()->create();

    Publisher::shouldReceive('publish')->once()->with($podcast);

    $podcast->publish();
});
Les façades en temps réel sont utiles pour simplifier le mocking pendant les tests, sans devoir passer d’argument.

Tests des façades

Pour tester une façade, utilisez shouldReceive qui retourne une instance mock Mockery. Comme la façade est résolue via le conteneur, elle est bien plus testable qu’une classe statique classique.
use Illuminate\Support\Facades\Cache;

test('affiche le profil utilisateur', function () {
    Cache::shouldReceive('get')
        ->once()
        ->with('user:1')
        ->andReturn(['name' => 'Taylor']);

    $response = $this->get('/users/1');

    $response->assertSee('Taylor');
});
Méthodes de mock fréquentes :
MéthodeDescription
shouldReceive('method')S’attend à ce que la méthode soit appelée
once()Une seule fois
times(n)n fois
with(args)Avec des arguments donnés
andReturn(value)Retourne la valeur spécifiée
andReturnNull()Retourne null

Principales façades

Correspondance entre façades courantes, leur classe concrète et le nom du binding du conteneur.
FaçadeClasseBinding
AppIlluminate\Foundation\Applicationapp
AuthIlluminate\Auth\AuthManagerauth
CacheIlluminate\Cache\CacheManagercache
ConfigIlluminate\Config\Repositoryconfig
CookieIlluminate\Cookie\CookieJarcookie
CryptIlluminate\Encryption\Encrypterencrypter
DBIlluminate\Database\DatabaseManagerdb
EventIlluminate\Events\Dispatcherevents
FileIlluminate\Filesystem\Filesystemfiles
GateIlluminate\Contracts\Auth\Access\Gate
HashIlluminate\Contracts\Hashing\Hasherhash
HttpIlluminate\Http\Client\Factory
LogIlluminate\Log\LogManagerlog
MailIlluminate\Mail\Mailermailer
NotificationIlluminate\Notifications\ChannelManager
QueueIlluminate\Queue\QueueManagerqueue
RateLimiterIlluminate\Cache\RateLimiter
RedirectIlluminate\Routing\Redirectorredirect
RequestIlluminate\Http\Requestrequest
RouteIlluminate\Routing\Routerrouter
SchemaIlluminate\Database\Schema\Builder
SessionIlluminate\Session\SessionManagersession
StorageIlluminate\Filesystem\FilesystemManagerfilesystem
URLIlluminate\Routing\UrlGeneratorurl
ValidatorIlluminate\Validation\Factoryvalidator
ViewIlluminate\View\Factoryview

Prochaines étapes

Contrats

Découvrez le concept de contrats, complément des façades, et quand les utiliser.
Dernière modification le 13 juillet 2026