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

# Fusion et cache de la configuration des packages

> À partir de l'implémentation de ServiceProvider dans Laravel 13, découvrez la différence entre fusion superficielle et remplacement récursif, les pièges des tableaux à clés numériques et la maintenance d'un package compatible avec le cache de configuration.

Ajouter une option de configuration à votre package ne l'écrit pas automatiquement dans le fichier de configuration que l'utilisateur a publié auparavant. Pour compléter les valeurs par défaut sans casser une configuration déjà publiée, vous devez concevoir à la fois la stratégie de fusion des tableaux et la prise en compte du cache de configuration.

Cette page s'appuie sur la lecture du `ServiceProvider` de Laravel 13 pour expliquer comment maintenir la configuration en tant qu'API publique de votre package. Elle suppose que vous connaissez les [bases du développement de packages](/fr/advanced/package-development), et l'implémentation a été vérifiée sur `laravel/framework` en version `v13.34.0`.

## La publication et la fusion sont deux traitements distincts

`publishes()` enregistre une source et une destination de copie. Tant que `vendor:publish` n'a pas copié le fichier, le répertoire `config` de l'utilisateur reste inchangé. De son côté, `mergeConfigFrom()` met à jour le dépôt de configuration au démarrage, sans réécrire le fichier lui-même.

```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'utilisateur ne publie le fichier de configuration que lorsqu'il en a besoin. Même sans publication, lors d'un démarrage normal sans cache, les valeurs par défaut sont utilisées grâce à la fusion effectuée dans `register()`.

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

<Warning>
  Republier le fichier de configuration avec `--force` lors d'une mise à jour écrase les modifications de l'utilisateur. Si vous ajoutez simplement de nouvelles options, privilégiez le complément par des valeurs par défaut et la documentation des changements.
</Warning>

## mergeConfigFrom() ne fusionne que le premier niveau

`ServiceProvider::mergeConfigFrom()` exécute `array_merge()` en passant d'abord la configuration du package, puis la configuration existante de l'application. Pour une même clé de type chaîne, la valeur de l'application l'emporte.

L'exemple suivant reproduit la fusion du framework uniquement avec des tableaux.

```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 clé de premier niveau `enabled` est bien complétée, mais `transport` est remplacé dans son intégralité. `transport.retries` ne subsiste pas. Retenez ce point : si l'utilisateur a déjà publié un ancien tableau `transport`, les nouvelles clés que vous ajoutez à ce même tableau ne seront pas complétées.

## Compléter une configuration imbriquée avec replaceConfigRecursivelyFrom()

Le `ServiceProvider` de Laravel 13 propose aussi la méthode protégée `replaceConfigRecursivelyFrom()`. Elle exécute `array_replace_recursive()` dans le même ordre.

Si vous voulez une API de configuration qui permet de surcharger individuellement les clés de type chaîne imbriquées, modifiez le `register()` de votre provider comme suit. Il n'est pas nécessaire de l'utiliser en plus de `mergeConfigFrom()` pour la même clé de configuration.

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

Avec les mêmes `$defaults` et `$overrides` que précédemment, vous obtenez le résultat suivant.

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

var_export($config);
```

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

| Contrat de configuration | Traitement à choisir | Point d'attention |
| - | - | - |
| L'utilisateur spécifie les tableaux imbriqués dans leur intégralité | `mergeConfigFrom()` | Les clés non spécifiées dans le tableau ne sont pas complétées |
| L'utilisateur ne spécifie qu'une partie des éléments imbriqués | `replaceConfigRecursivelyFrom()` | Les listes à clés numériques sont aussi soumises au remplacement récursif |

<Info>
  `replaceConfigRecursivelyFrom()` est une méthode présente dans le code source de Laravel 13 examiné sur cette page. Distinguez-la de `mergeConfigFrom()`, présentée dans la documentation officielle sur le développement de packages, et vérifiez l'implémentation du framework correspondant avant de l'utiliser.
</Info>

### Les listes à clés numériques ne sont pas remplacées en bloc

Le remplacement récursif ne consiste pas à « remplacer tout le tableau par les valeurs de l'utilisateur ». Même pour des clés numériques, il remplace la valeur de chaque clé identique et conserve les clés que l'utilisateur n'a pas spécifiées.

```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',
)
```

Même si l'utilisateur ne spécifie que `['slack']`, `database` subsiste. De plus, passer `['channels' => []]` ne vide pas la liste par défaut. Soyez particulièrement vigilant avec les configurations où la spécification de la liste entière a un sens, comme les canaux de notification ou les middlewares.

Si votre package comporte ce type de configuration, réfléchissez à sa structure : par exemple, séparez les listes et les tableaux associatifs partiellement surchargeables dans des clés de premier niveau distinctes, et utilisez une fusion superficielle. Changer de mode de fusion dans un package déjà publié modifie le comportement d'un même fichier de configuration : ne traitez donc pas ce changement comme un simple remplacement d'implémentation.

## Le cache de configuration enregistre les valeurs après fusion

Les deux méthodes ignorent la fusion lorsque l'application implémente `CachesConfiguration` et que `configurationIsCached()` renvoie `true`. Dans une application Laravel classique, c'est le cas des démarrages où un cache de configuration existe.

`ConfigCacheCommand` supprime l'ancien cache de configuration, démarre une nouvelle application et récupère l'ensemble du dépôt de configuration. Lors de ce démarrage, la configuration des providers est fusionnée et le résultat est enregistré dans le fichier de cache. Aux démarrages suivants, `LoadConfiguration` lit ces valeurs.

```mermaid theme={null}
flowchart TD
    A["php artisan config:cache"] --> B["Suppression de l'ancien cache de configuration"]
    B --> C["Démarrage d'une nouvelle application"]
    C --> D["Lecture des fichiers de configuration<br>fusion par les providers"]
    D --> E["Enregistrement de l'ensemble du dépôt de configuration"]
    E --> F["Utilisation de la configuration enregistrée aux démarrages suivants<br>les deux méthodes de fusion sont ignorées"]
```

Par conséquent, même si une mise à jour du package modifie les valeurs par défaut ou le mode de fusion, ces changements ne s'appliquent pas aux applications qui continuent d'utiliser l'ancien cache. Dans les déploiements qui utilisent le cache de configuration, reconstruisez-le avec le code mis à jour.

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

Pour revenir, pendant le développement, à une lecture depuis les fichiers, utilisez `php artisan config:clear`. Ne choisissez pas vous-même l'emplacement du cache : laissez les commandes Laravel le gérer.

<Warning>
  Ne définissez pas de Closure dans les fichiers de configuration. `config:cache` ne peut pas les sérialiser correctement. Si vous devez transmettre un callback, placez par exemple un nom de classe dans la configuration et enregistrez le service réel dans le provider.
</Warning>

## Vérifications avant de publier un changement de configuration

Dans les tests de votre package, prenez en entrée non seulement l'absence de configuration publiée, mais aussi des configurations héritées d'anciennes versions.

* Même sans configuration publiée, les valeurs par défaut nécessaires sont disponibles.
* Avec une ancienne configuration publiée, les valeurs de l'utilisateur l'emportent et les nouvelles options sont complétées comme prévu.
* Le contrat de surcharge reste inchangé pour les tableaux imbriqués, les listes à clés numériques et les tableaux vides.
* `config:cache` réussit dans l'application utilisatrice, et un autre démarrage utilisant le cache produit la même configuration.

Indiquez dans les notes de version les valeurs par défaut des nouvelles clés et la reconstruction du cache nécessaire. Pour la suppression ou le renommage de clés, ainsi que le changement de mode de fusion, évaluez aussi la compatibilité avec les configurations déjà publiées par les utilisateurs.

## Pages associées

<Columns cols={2}>
  <Card title="Tester un package" icon="flask" href="/fr/advanced/package-testing">
    Enregistrez le service provider pour vérifier le comportement de la configuration et des services.
  </Card>

  <Card title="Gestion de la compatibilité des versions" icon="code-branch" href="/fr/advanced/package-versioning">
    Reliez les changements de l'API publique à votre politique de versions et à la maintenance continue.
  </Card>
</Columns>

## Sources primaires consultées

* [Documentation officielle de Laravel : configuration des packages](https://github.com/laravel/docs/blob/13.x/packages.md#configuration)
* [ServiceProvider : implémentation de la fusion et de la publication](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Support/ServiceProvider.php)
* [ConfigCacheCommand : génération du cache de configuration](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Foundation/Console/ConfigCacheCommand.php)
* [LoadConfiguration : chargement de la configuration](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Foundation/Bootstrap/LoadConfiguration.php)
* [ConfigClearCommand : suppression du cache de configuration](https://github.com/laravel/framework/blob/v13.34.0/src/Illuminate/Foundation/Console/ConfigClearCommand.php)


## Related topics

- [Développement de packages Laravel](/fr/advanced/package-development.md)
- [Sujets avancés](/fr/advanced/index.md)
- [Configuration](/fr/configuration.md)
- [Fonctionnement interne de la découverte automatique des packages](/fr/advanced/package-discovery.md)
- [Installation et configuration - VOICEVOX for Laravel](/fr/packages/laravel-voicevox/installation.md)


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