Service Providers
Les providers sont le lieu où votre application décide comment configurer et exposer les services. Ils ont deux rôles distincts : enregistrer des services dans le container, et exécuter du code au démarrage.
Pourquoi un provider ?
River peut créer automatiquement la plupart des services via l'autowiring (voir Container IoC). Alors pourquoi un provider ?
Cas 1 — Exposer un service dans tous les templates. River sait créer un objet Csrf, mais il ne sait pas que vous voulez l'appeler $csrf dans vos vues. C'est votre application qui décide comment exposer les services aux templates via $view->share().
// Sans provider : vous devriez passer $csrf dans chaque render() manuellement
// Avec un provider : $csrf est disponible dans tous les templates automatiquement
class Csrf_provider extends Service_provider {
public function register(): void {}
public function boot(): void {
$view = $this->container->get(View::class);
$csrf = $this->container->get(Csrf::class);
$view->share('csrf', $csrf);
}
}
$csrf dans toutes les apps, mais ça serait opinionated — toutes les apps n'ont pas besoin du CSRF dans les vues, ou pourraient vouloir un autre nom. Le provider laisse le contrôle à l'application.
Cas 2 — Configurer un service qui nécessite des paramètres. L'autowiring ne peut pas deviner une clé API ou une URL externe. Un provider est l'endroit pour construire ces services.
class Mailer_provider extends Service_provider {
public function register(): void {
$this->container->singleton(Mailer::class, function($c) {
return new Mailer(
host: $_ENV['SMTP_HOST'],
port: (int) $_ENV['SMTP_PORT'],
);
});
}
}
register() vs boot()
Un provider a deux méthodes avec des rôles bien distincts :
| Méthode | Quand | Usage |
|---|---|---|
register() |
Avant que tous les providers soient chargés | Lier des services dans le container (bind, singleton) |
boot() |
Après que tous les providers sont chargés | Utiliser des services déjà enregistrés (ex: $view->share()) |
$this->container->get() dans register(). Les autres providers ne sont pas encore chargés à ce stade. Réservez get() pour boot().
Créer un Provider
Les providers étendent River\Providers\Service_provider et se placent dans app/Providers/.
namespace App\Providers;
use River\Providers\Service_provider;
use River\Session;
use River\View;
class Flash_provider extends Service_provider {
public function register(): void {
// Rien ici — Session et View sont déjà autowired par River
}
public function boot(): void {
$session = $this->container->get(Session::class);
$data = $session->get('flash_toast');
if ($data) {
$session->remove('flash_toast');
$this->container->get(View::class)->share('flash_toast', $data);
}
}
}
Enregistrement
Ajoutez votre provider dans bootstrap/providers.php :
use River\Providers\Vite_provider;
use App\Providers\Csrf_provider;
use App\Providers\Flash_provider;
return [
Vite_provider::class,
Csrf_provider::class,
Flash_provider::class,
];