Prologo
Primi Passi
Architettura
Le Basi
- Routing
- Middleware
- Protezione da CSRF
- Controller
- Richieste
- Risposte
- Views
- Blade
- Vite
- URL
- Sessioni
- Validazione
- Errori
- Logging
Approfondimenti
- Artisan
- Broadcasting
- Cache
- Collezioni
- Concorrenza
- Contesto
- Contratti
- Eventi
- File System
- Helpers
- Client HTTP
- Localizzazione
- Notifiche
- Sviluppo di Package
- Processi
- Code
- Rate-limiting
- Stringhe
- Scheduling di Task
Sicurezza
Database
Eloquent ORM
Testing
Package
Service Provider
Introduzione
I service provider sono il punto centrale per l’avvio di tutte le applicazioni Laravel. Sia la tua applicazione, che tutti i servizi principali di Laravel, vengono avviati tramite i service provider.
Ma cosa intendiamo per "avviati"? In generale, intendiamo registrare elementi, inclusa la registrazione dei service container binding, degli event listener, dei middleware e persino delle rotte. I service provider sono il luogo principale dove avvii e configuri la tua applicazione.
Laravel utilizza decine di service provider internamente per avviare i suoi servizi principali, come il mailer, la queue, la cache e altri. Molti di questi provider sono "deferred", il che significa che non vengono caricati ad ogni richiesta, ma solo quando i servizi che forniscono sono effettivamente necessari.
Tutti i service provider definiti dall’utente sono registrati nel file bootstrap/providers.php
. Nella documentazione di seguito imparerai come scrivere i tuoi service provider e registrarli nella tua applicazione Laravel.
Se vuoi saperne di più su come Laravel gestisce le richieste e funziona internamente, consulta la nostra documentazione sul lifecycle delle richieste.
Scrivere i Service Providers
Tutti i service providers estendono la classe Illuminate\Support\ServiceProvider
. La maggior parte dei service providers contiene un metodo register
e un metodo boot
. All’interno del metodo register
, dovresti solo collegare elementi nel service container. Non dovresti mai tentare di registrare listener di eventi, rotte o altre funzionalità nel metodo register
.
La CLI di Artisan può generare un nuovo provider tramite il comando make:provider
. Laravel registrerà automaticamente il nuovo provider nel file bootstrap/providers.php
della tua applicazione:
php artisan make:provider RiakServiceProvider
Il Metodo Register
Come accennato in precedenza, all’interno del metodo register
dovresti solo definire i binding nel service container. Non dovresti mai tentare di registrare listener di eventi, rotte o qualsiasi altra funzionalità all’interno del metodo register
. Altrimenti, potresti accidentalmente utilizzare un servizio fornito da un service provider che non è ancora stato caricato.
Diamo un’occhiata a un service provider di base. Innanzitutto, all’interno di un qualsiasi metodo del tuo service provider hai sempre accesso alla proprietà $app
. Ti serve per usare il service container:
<?php
namespace App\Providers;
use App\Services\Riak\Connection;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\ServiceProvider;
class RiakServiceProvider extends ServiceProvider
{
/**
* Registra i servizi dell'applicazione.
*/
public function register(): void
{
$this->app->singleton(Connection::class, function (Application $app) {
return new Connection(config('riak'));
});
}
}
Questo service provider definisce solo un metodo register
e utilizza quel metodo per definire un’implementazione di App\Services\Riak\Connection
nel service container. Se non hai ancora familiarità con il service container di Laravel, consulta la sua documentazione.
Le proprietà bindings
e singletons
Se il tuo service provider registra molti binding semplici, potresti preferire le proprietà bindings
e singletons
invece di registrare manualmente ogni binding del container. Quando il service provider viene caricato dal framework, verificherà automaticamente queste proprietà e registrerà i relativi binding:
<?php
namespace 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
{
/**
* Tutti i binding del container che devono essere registrati.
*
* @var array
*/
public $bindings = [
ServerProvider::class => DigitalOceanServerProvider::class,
];
/**
* Tutti i singleton del container che devono essere registrati.
*
* @var array
*/
public $singletons = [
DowntimeNotifier::class => PingdomDowntimeNotifier::class,
ServerProvider::class => ServerToolsProvider::class,
];
}
Il Metodo Boot
E se avessimo bisogno di registrare altro? Ad esempio, se avessimo bisogno di registrare un view composer nel nostro service provider? Qui passiamo al metodo boot
. Questo metodo viene chiamato dopo che tutti gli altri service provider sono stati registrati, il che significa che hai accesso a tutti gli altri servizi registrati dal framework:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
View::composer('view', function () {
// ...
});
}
}
Iniezione delle Dipendenze nel Metodo Boot
Puoi fare dependency-injection sul metodo boot
di un service provider. Il service container infatti inietterà automaticamente tutte le dipendenze di cui hai bisogno:
use Illuminate\Contracts\Routing\ResponseFactory;
/**
* Avvia i servizi dell'applicazione.
*/
public function boot(ResponseFactory $response): void
{
$response->macro('serialized', function (mixed $value) {
// ...
});
}
Registrare i Provider
Tutti i service provider sono registrati nel file di configurazione bootstrap/providers.php
. Questo file restituisce un array che contiene i nomi delle classi dei service provider della tua applicazione:
<?php
return [
App\Providers\AppServiceProvider::class,
];
Quando esegui il comando Artisan make:provider
, Laravel aggiungerà automaticamente il provider generato al file bootstrap/providers.php
. Tuttavia, se hai creato manualmente la classe del provider, devi aggiungerla manualmente all’array:
<?php
return [
App\Providers\AppServiceProvider::class,
App\Providers\ComposerServiceProvider::class, // [tl! add]
];
Deferred Provider
Se il tuo provider sta solo registrando binding nel service container, puoi scegliere di rinviare la sua registrazione fino a quando uno dei binding registrati non è effettivamente necessario. Rinviare il caricamento di un provider di questo tipo migliorerà le prestazioni della tua applicazione, poiché non viene caricato dal filesystem ad ogni richiesta.
Laravel compila e memorizza un elenco di tutti i servizi forniti dai service provider deferred (in differita, per capirci), insieme al nome della classe del service provider. Poi, solo quando tenti di risolvere uno di questi servizi, Laravel carica il provider di cui ha bisogno.
Per rinviare il caricamento di un provider, implementa l’interfaccia \Illuminate\Contracts\Support\DeferrableProvider
e definisci un metodo provides
. Il metodo provides
dovrebbe restituire i binding del service container registrati dal provider:
namespace 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 i servizi dell'applicazione.
*/
public function register(): void
{
$this->app->singleton(Connection::class, function (Application $app) {
return new Connection($app['config']['riak']);
});
}
/**
* Ottieni i servizi forniti dal provider.
*
* @return array<int, string>
*/
public function provides(): array
{
return [Connection::class];
}
}