> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Merge e cache della configurazione dei pacchetti

> Partendo dall'implementazione di ServiceProvider in Laravel 13, scopri la differenza tra merge superficiale e sostituzione ricorsiva, le insidie degli array con chiavi numeriche e come mantenere un pacchetto tenendo conto della cache della configurazione.

Quando aggiungi nuove opzioni alla configurazione di un pacchetto, queste non vengono scritte automaticamente nel file di configurazione che l'utente ha pubblicato in precedenza. Per fornire i valori di default senza rompere la configurazione già pubblicata, devi progettare sia la strategia di merge degli array sia il comportamento con la cache della configurazione.

Questa pagina analizza il `ServiceProvider` di Laravel 13 e spiega come mantenere la configurazione come API pubblica del pacchetto. Presuppone la conoscenza dei [fondamenti dello sviluppo di pacchetti](/it/advanced/package-development) e, per verificare l'implementazione, usa `laravel/framework` alla versione `v13.34.0`.

## Pubblicazione e merge sono operazioni distinte

`publishes()` registra il percorso di origine e quello di destinazione della copia. Finché `vendor:publish` non copia il file, la directory `config` dell'utente non cambia. `mergeConfigFrom()`, invece, aggiorna il repository di configurazione all'avvio senza modificare il file stesso.

```php theme={null}
<?php

namespace Acme\Courier;

use Illuminate\Support\ServiceProvider;

class CourierServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->mergeConfigFrom(
            __DIR__.'/../config/courier.php', 'courier'
        );
    }

    public function boot(): void
    {
        $this->publishes([
            __DIR__.'/../config/courier.php' => config_path('courier.php'),
        ], 'courier-config');
    }
}
```

L'utente pubblica il file di configurazione solo quando gli serve. Anche senza pubblicarlo, in un normale avvio senza cache vengono usati i valori di default grazie al merge in `register()`.

```bash theme={null}
php artisan vendor:publish --tag=courier-config
```

<Warning>
  Se come procedura di aggiornamento ripubblichi il file di configurazione con `--force`, sovrascrivi le modifiche dell'utente. Se devi solo aggiungere nuove opzioni, dai la priorità alla fornitura dei valori di default e alla comunicazione delle modifiche.
</Warning>

## mergeConfigFrom() unisce solo il livello superiore

`ServiceProvider::mergeConfigFrom()` esegue `array_merge()` passando prima la configurazione del pacchetto e poi quella già esistente nell'applicazione. A parità di chiave stringa, prevale il valore dell'applicazione.

L'esempio seguente riproduce il merge del framework usando solo array.

```php theme={null}
<?php

$defaults = [
    'enabled' => true,
    'transport' => [
        'timeout' => 10,
        'retries' => 3,
    ],
];

$overrides = [
    'transport' => [
        'timeout' => 30,
    ],
];

$config = array_merge($defaults, $overrides);

var_export($config);
```

```text theme={null}
array (
  'enabled' => true,
  'transport' =>
  array (
    'timeout' => 30,
  ),
)
```

La chiave di primo livello `enabled` viene aggiunta, ma `transport` viene sostituito per intero. `transport.retries` non viene mantenuto. Il punto importante è che, se l'utente ha già pubblicato un vecchio array `transport`, le nuove chiavi che aggiungi a quello stesso array non vengono integrate.

## Integrare la configurazione annidata con replaceConfigRecursivelyFrom()

Il `ServiceProvider` di Laravel 13 offre anche il metodo protected `replaceConfigRecursivelyFrom()`. Questo esegue `array_replace_recursive()` con lo stesso ordine di argomenti.

Se vuoi un'API di configurazione in cui le chiavi stringa annidate si sovrascrivono singolarmente, modifica il `register()` del provider come segue. Non serve usarlo insieme al `mergeConfigFrom()` visto prima per la stessa chiave di configurazione.

```php theme={null}
public function register(): void
{
    $this->replaceConfigRecursivelyFrom(
        __DIR__.'/../config/courier.php', 'courier'
    );
}
```

Con gli stessi `$defaults` e `$overrides` di prima, il risultato è il seguente.

```php theme={null}
$config = array_replace_recursive($defaults, $overrides);

var_export($config);
```

```text theme={null}
array (
  'enabled' => true,
  'transport' =>
  array (
    'timeout' => 30,
    'retries' => 3,
  ),
)
```

| Contratto della configurazione | Metodo da scegliere | Attenzione |
| - | - | - |
| L'utente specifica per intero gli array annidati | `mergeConfigFrom()` | Le chiavi non specificate all'interno dell'array non vengono integrate |
| L'utente specifica solo una parte delle voci annidate | `replaceConfigRecursivelyFrom()` | Anche le liste con chiavi numeriche sono soggette alla sostituzione ricorsiva |

<Info>
  `replaceConfigRecursivelyFrom()` è un metodo presente nel codice sorgente di Laravel 13 esaminato in questa pagina. Distinguilo da `mergeConfigFrom()`, presentato nella documentazione ufficiale sullo sviluppo di pacchetti, e usalo dopo aver verificato l'implementazione del framework corrispondente.
</Info>

### Le liste con chiavi numeriche non vengono sostituite per intero

La sostituzione ricorsiva non è un'operazione che "rimpiazza l'intero array con i valori dell'utente". Anche con chiavi numeriche sostituisce i valori alla stessa chiave e mantiene le chiavi che l'utente non ha specificato.

```php theme={null}
<?php

$defaults = ['channels' => ['mail', 'database']];
$overrides = ['channels' => ['slack']];

$config = array_replace_recursive($defaults, $overrides);

var_export($config['channels']);
```

```text theme={null}
array (
  0 => 'slack',
  1 => 'database',
)
```

Anche se l'utente specifica solo `['slack']`, `database` rimane. Inoltre, passando `['channels' => []]` la lista di default non diventa vuota. Fai particolare attenzione con configurazioni in cui conta specificare l'intera lista, come destinazioni delle notifiche o middleware.

Se hai configurazioni di questo tipo, valuta la struttura stessa della configurazione, ad esempio separando le liste e gli array associativi sovrascrivibili in parte in chiavi di primo livello diverse e usando il merge superficiale. Se cambi la strategia di merge in un pacchetto già pubblicato, lo stesso file di configurazione si comporterà in modo diverso, quindi non trattarla come una semplice sostituzione dell'implementazione.

## La cache della configurazione salva i valori dopo il merge

Entrambi i metodi saltano il merge quando l'applicazione implementa `CachesConfiguration` e `configurationIsCached()` restituisce `true`. In una normale applicazione Laravel, questo accade negli avvii in cui esiste la cache della configurazione.

`ConfigCacheCommand` elimina la vecchia cache della configurazione, avvia una nuova applicazione e ottiene l'intero repository di configurazione. Durante quell'avvio la configurazione dei provider viene unita e il risultato viene salvato nel file di cache. Negli avvii successivi `LoadConfiguration` legge quei valori.

```mermaid theme={null}
flowchart TD
    A["php artisan config:cache"] --> B["Elimina la vecchia cache della configurazione"]
    B --> C["Avvia una nuova applicazione"]
    C --> D["Legge i file di configurazione<br>e li unisce nei provider"]
    D --> E["Salva l'intero repository di configurazione"]
    E --> F["Gli avvii successivi usano la configurazione salvata<br>entrambi i metodi di merge vengono saltati"]
```

Di conseguenza, anche se aggiorni il pacchetto e cambiano i valori di default o la strategia di merge, le modifiche non si riflettono sulle applicazioni che continuano a usare la vecchia cache. Nei deploy che usano la cache della configurazione, ricostruiscila con il codice aggiornato.

```bash theme={null}
php artisan config:cache
```

Se durante lo sviluppo vuoi tornare a leggere la configurazione dai file, usa `php artisan config:clear`. Non decidere autonomamente dove generare la cache e lascia che siano i comandi di Laravel a gestirla.

<Warning>
  Non definire Closure nei file di configurazione. `config:cache` non riesce a serializzarle correttamente. Se devi passare una callback, inserisci nella configurazione un nome di classe o simili ed esegui la registrazione effettiva del servizio nel provider.
</Warning>

## Verifiche prima di rilasciare modifiche alla configurazione

Nei test del pacchetto considera come input non solo la configurazione non pubblicata, ma anche quella rimasta dalle versioni precedenti.

* Anche senza configurazione pubblicata, ottieni i valori di default necessari.
* Con una vecchia configurazione pubblicata, i valori dell'utente hanno la precedenza e le nuove voci vengono integrate come previsto.
* Il contratto di sovrascrittura non cambia per array annidati, liste con chiavi numeriche e array vuoti.
* `config:cache` va a buon fine nell'applicazione che usa il pacchetto e un altro avvio che usa la cache produce la stessa configurazione.

Indica nelle note di rilascio i valori di default delle nuove chiavi e l'eventuale ricostruzione della cache necessaria. Valuta la rimozione o la ridenominazione di chiavi e i cambi di strategia di merge tenendo conto anche della compatibilità con la configurazione già pubblicata dagli utenti.

## Pagine correlate

<Columns cols={2}>
  <Card title="Test dei pacchetti" icon="flask" href="/it/advanced/package-testing">
    Registra il service provider e verifica il comportamento della configurazione e dei servizi.
  </Card>

  <Card title="Gestione della compatibilità delle versioni" icon="code-branch" href="/it/advanced/package-versioning">
    Collega le modifiche all'API pubblica alla politica di rilascio e alla manutenzione continua.
  </Card>
</Columns>

## Fonti primarie consultate

* [Documentazione ufficiale di Laravel: configurazione dei pacchetti](https://github.com/laravel/docs/blob/13.x/packages.md#configuration)
* [ServiceProvider: implementazione di merge e pubblicazione](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Support/ServiceProvider.php)
* [ConfigCacheCommand: generazione della cache della configurazione](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Foundation/Console/ConfigCacheCommand.php)
* [LoadConfiguration: caricamento della configurazione](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Foundation/Bootstrap/LoadConfiguration.php)
* [ConfigClearCommand: eliminazione della cache della configurazione](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Foundation/Console/ConfigClearCommand.php)


## Related topics

- [Sviluppo di pacchetti Laravel](/it/advanced/package-development.md)
- [Argomenti avanzati](/it/advanced/index.md)
- [Configurazione](/it/configuration.md)
- [Riferimento della configurazione - VOICEVOX for Laravel](/it/packages/laravel-voicevox/configuration.md)
- [Struttura interna del package auto-discovery](/it/advanced/package-discovery.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.