Illuminate\Support\Manager est une classe abstraite présente depuis Laravel 4.0. Elle fournit les fondations permettant de construire simplement un système capable de basculer entre plusieurs « drivers », comme le cache, la session ou le mail.Un « driver » est un backend qui présente la même interface mais dont l’implémentation interne diffère. Par exemple, pour la session, on trouve les drivers file, cookie, database ou redis, sélectionnés via la clé driver du fichier de configuration.
Toutes les classes appelées Managern’héritent pas de Illuminate\Support\Manager.
Classe
Hérite-t-elle de Manager ?
Illuminate\Session\SessionManager
✅ Oui
Illuminate\Cache\CacheManager
❌ Non (implémentation dédiée)
Illuminate\Queue\QueueManager
❌ Non (implémentation dédiée)
Laravel\Socialite\SocialiteManager
✅ Oui
Les classes qui n’en héritent pas suivent tout de même la même logique fondamentale d’extension via extend(). Comprendre le pattern Manager aide donc à comprendre le fonctionnement de tout le framework.
L’appel à driver() résout un driver selon les étapes suivantes.Dans le code source, le nom de la méthode est construit à partir du nom du driver via Str::studly().
// Extrait de Illuminate\Support\Manager::createDriver()protected function createDriver($driver){ if (isset($this->customCreators[$driver])) { return $this->callCustomCreator($driver); } $method = 'create'.Str::studly($driver).'Driver'; if (method_exists($this, $method)) { return $this->$method(); } throw new InvalidArgumentException("Driver [$driver] not supported.");}
Autrement dit, le driver file appelle createFileDriver() et le driver my-custom appelle createMyCustomDriver().
Vous pouvez enregistrer votre propre driver en passant un nom et une closure à extend(). La closure reçoit l’instance du conteneur en argument.
use Illuminate\Support\Facades\Session;Session::extend('redis-cluster', function ($app) { return new RedisClusterSessionHandler( $app->make('redis'), $app['config']['session'], );});
extend() lie la closure à $this, ce qui permet d’accéder aux propriétés et méthodes du Manager depuis la closure.
La classe Manager implémente __call. Les appels de méthodes qui n’existent pas sur le Manager lui-même sont automatiquement délégués au driver par défaut.
public function __call($method, $parameters){ return $this->driver()->$method(...$parameters);}
C’est ce qui permet d’écrire SessionManager::get('key') en utilisant directement le Manager, tout en confiant le traitement effectif au driver.
Prenons un service de notifications pour créer une classe personnalisée héritant de Manager.
1
Créer une classe qui hérite de Manager
namespace App\Notifications;use Illuminate\Support\Manager;class NotificationManager extends Manager{ public function getDefaultDriver(): string { return $this->config->get('notifications.driver', 'slack'); } protected function createSlackDriver(): SlackNotifier { return new SlackNotifier( $this->config->get('notifications.slack'), ); } protected function createEmailDriver(): EmailNotifier { return new EmailNotifier( $this->config->get('notifications.email'), ); } protected function createLogDriver(): LogNotifier { return new LogNotifier( $this->container->make('log'), ); }}
2
Enregistrer via un service provider
namespace App\Providers;use App\Notifications\NotificationManager;use Illuminate\Support\ServiceProvider;class NotificationServiceProvider extends ServiceProvider{ public function register(): void { $this->app->singleton(NotificationManager::class, function ($app) { return new NotificationManager($app); }); }}
3
Ajouter un driver personnalisé
// Dans AppServiceProvider::boot() par exemple$manager = app(NotificationManager::class);$manager->extend('teams', function ($app) { return new TeamsNotifier( $app['config']['notifications.teams'], );});
4
Utilisation
$manager = app(NotificationManager::class);// Utiliser le driver par défaut$manager->send('message');// Spécifier un driver précis$manager->driver('email')->send('message');// Un driver résolu est mis en cache$manager->driver('slack'); // renvoie la même instance
Illuminate\Support\MultipleInstanceManager est une classe ajoutée dans Laravel 10. Là où Manager gère les « types » de drivers, MultipleInstanceManager gère plusieurs « instances » nommées.
Pour hériter de MultipleInstanceManager, il faut implémenter trois méthodes.
// Extrait du code sourceabstract public function getDefaultInstance();abstract public function setDefaultInstance($name);abstract public function getInstanceConfig($name);
getInstanceConfig() renvoie le tableau de configuration associé au nom. Ce tableau doit obligatoirement contenir la clé driver (ou la clé spécifiée par $driverKey).
Prenons l’exemple d’un package prenant en charge simultanément plusieurs passerelles SMS.
namespace App\Sms;use Illuminate\Support\MultipleInstanceManager;class SmsManager extends MultipleInstanceManager{ // Nom de l'instance par défaut public function getDefaultInstance(): string { return $this->config->get('sms.default', 'primary'); } public function setDefaultInstance($name): void { $this->config->set('sms.default', $name); } // Renvoie la configuration associée au nom d'instance public function getInstanceConfig($name): array { return $this->config->get("sms.gateways.{$name}"); } // Construction du driver twilio (la config est passée en argument) protected function createTwilioDriver(array $config): TwilioSmsGateway { return new TwilioSmsGateway( $config['account_sid'], $config['auth_token'], ); } // Construction du driver vonage protected function createVonageDriver(array $config): VonageSmsGateway { return new VonageSmsGateway( $config['api_key'], $config['api_secret'], ); }}
$sms = app(SmsManager::class);// Utiliser l'instance par défaut (primary = twilio)$sms->send('+33612345678', 'Code de confirmation : 123456');// Cibler une instance par nom$sms->instance('backup')->send('+33612345678', 'Code de confirmation : 123456');// Utiliser l'instance dédiée au marketing$sms->instance('marketing')->send('+33612345678', 'Annonce de campagne');
MultipleInstanceManager permet, comme Manager, d’ajouter des drivers personnalisés via extend(). Il implémente aussi __call, si bien que les méthodes absentes de l’instance elle-même sont déléguées à l’instance par défaut.
Manipulation du cache dans MultipleInstanceManager
// Supprimer une instance spécifique$manager->forgetInstance('backup');// Supprimer l'instance par défaut$manager->forgetInstance();// Supprimer plusieurs instances d'un coup$manager->forgetInstance(['primary', 'backup']);// Supprimer une instance et purger son cache$manager->purge('backup');