Los service providers son el lugar central donde se realiza el bootstrapping de toda una aplicación Laravel. Tanto tu propia aplicación como todos los servicios centrales de Laravel se inicializan a través de service providers.Por “bootstrap” entendemos registrar cosas como bindings del contenedor de servicios, listeners de eventos, middleware, rutas y demás. Los service providers son el lugar central donde configuras la aplicación.Internamente, Laravel usa muchos service providers para inicializar servicios centrales como mailer, colas o caché. Muchos son “diferidos”: no se cargan en cada solicitud, sino solo cuando se necesita realmente el servicio que ofrecen.Los service providers definidos por el usuario se registran en bootstrap/providers.php.
Si quieres profundizar en cómo Laravel procesa las solicitudes, consulta la documentación de Ciclo de vida de la solicitud.
Todos los service providers extienden Illuminate\Support\ServiceProvider. La mayoría incluyen los métodos register y boot.Genera un nuevo provider con el comando Artisan make:provider. Laravel lo registra automáticamente en bootstrap/providers.php.
Dentro de registersolo debes hacer bindings al contenedor de servicios. No registres listeners de eventos, rutas u otras funcionalidades en register. Podrías acabar usando por error servicios que aún no se hayan cargado.
<?phpnamespace App\Providers;use App\Services\Riak\Connection;use Illuminate\Contracts\Foundation\Application;use Illuminate\Support\ServiceProvider;class RiakServiceProvider extends ServiceProvider{ /** * Registra los servicios de la aplicación */ public function register(): void { $this->app->singleton(Connection::class, function (Application $app) { return new Connection(config('riak')); }); }}
Dentro de los métodos del provider, siempre puedes acceder al contenedor a través de $this->app.
Si vas a registrar muchos bindings sencillos, en vez de hacerlo manualmente puedes usar las propiedades bindings y singletons. Cuando el framework carga el provider, comprueba automáticamente estas propiedades y registra los bindings.
<?phpnamespace App\Providers;use App\Contracts\DowntimeNotifier;use App\Contracts\ServerProvider;use App\Services\DigitalOceanServerProvider;use App\Services\PingdomDowntimeNotifier;use App\Services\ServerToolsProvider;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider{ /** * Todos los bindings a registrar en el contenedor * * @var array */ public $bindings = [ ServerProvider::class => DigitalOceanServerProvider::class, ]; /** * Todos los singletons a registrar en el contenedor * * @var array */ public $singletons = [ DowntimeNotifier::class => PingdomDowntimeNotifier::class, ServerProvider::class => ServerToolsProvider::class, ];}
Si registras un view composer en un service provider, hazlo en boot. Este método se llama después de que todos los service providers estén registrados, lo que significa que puedes acceder a todos los servicios registrados por el framework.
<?phpnamespace App\Providers;use Illuminate\Support\Facades\View;use Illuminate\Support\ServiceProvider;class ComposerServiceProvider extends ServiceProvider{ /** * Inicia los servicios de la aplicación */ public function boot(): void { View::composer('view', function () { // ... }); }}
No confundas los papeles de register y boot. register es solo para registrar bindings; boot es para inicializar servicios y otras tareas de arranque.
En boot también puedes usar type-hints para inyectar dependencias. El contenedor de servicios las resuelve automáticamente.
use Illuminate\Contracts\Routing\ResponseFactory;/** * Inicia los servicios de la aplicación */public function boot(ResponseFactory $response): void{ $response->macro('serialized', function (mixed $value) { // ... });}
Todos los service providers se registran en bootstrap/providers.php. Este archivo devuelve un array con los nombres de las clases de service provider de la aplicación.
En Laravel 13, los service providers se registran en bootstrap/providers.php, no en el array providers de config/app.php. make:provider añade la entrada automáticamente.
Cuando ejecutas make:provider, Laravel añade automáticamente el provider al archivo. Si creas la clase manualmente, añádela tú mismo al array.
Vamos a crear un service provider personalizado paso a paso.
1
Generar el provider
Genera el service provider con Artisan.
php artisan make:provider PaymentServiceProvider
2
Hacer el binding en register
Escribe el binding en el método register del provider generado.
<?phpnamespace App\Providers;use App\Contracts\PaymentGateway;use App\Services\StripePaymentGateway;use Illuminate\Contracts\Foundation\Application;use Illuminate\Support\ServiceProvider;class PaymentServiceProvider extends ServiceProvider{ /** * Registra los servicios de la aplicación */ public function register(): void { $this->app->singleton(PaymentGateway::class, function (Application $app) { return new StripePaymentGateway( config('services.stripe.secret') ); }); } /** * Inicia los servicios de la aplicación */ public function boot(): void { // Escribe aquí la lógica de arranque si es necesario }}
3
Registrar en bootstrap/providers.php
Si usas make:provider, se añade automáticamente. Si no, añádelo tú mismo.
Si el provider solo registra bindings del contenedor de servicios, puedes diferir su registro hasta que realmente se necesiten. Al diferir su carga se evita leerlo del sistema de archivos en cada solicitud, mejorando el rendimiento.Para crear un provider diferido, implementa la interfaz \Illuminate\Contracts\Support\DeferrableProvider y define el método provides. provides devuelve los bindings del contenedor que registra el provider.
<?phpnamespace App\Providers;use App\Services\Riak\Connection;use Illuminate\Contracts\Foundation\Application;use Illuminate\Contracts\Support\DeferrableProvider;use Illuminate\Support\ServiceProvider;class RiakServiceProvider extends ServiceProvider implements DeferrableProvider{ /** * Registra los servicios de la aplicación */ public function register(): void { $this->app->singleton(Connection::class, function (Application $app) { return new Connection(config('riak')); }); } /** * Obtiene los servicios que ofrece el provider * * @return array<int, string> */ public function provides(): array { return [Connection::class]; }}
Los providers diferidos son adecuados para servicios que solo se usan en ciertas funcionalidades y no en toda la aplicación. Al evitar la carga de servicios innecesarios optimizas el rendimiento.