Skip to main content

À propos de cette page

Dans Développement de packages Laravel, nous avons vu qu’il suffit de renseigner la section extra.laravel du composer.json pour que les service providers et les façades soient enregistrés automatiquement. Cette page en explique les coulisses, en décryptant au niveau du code source le fonctionnement de la classe Illuminate\Foundation\PackageManifest.
Cette page complète Développement de packages Laravel. Nous vous recommandons de lire d’abord l’utilisation de base de la découverte automatique.

Vue d’ensemble du mécanisme de découverte automatique

La classe PackageManifest

Le cœur de la découverte automatique est Illuminate\Foundation\PackageManifest. Voici (en résumé) l’implémentation dans le framework en version 13.x.
Trois points à retenir :
  • Le manifeste est mis en cache en mémoire dès sa première lecture (propriété $this->manifest). Même si providers() est appelée plusieurs fois dans la même requête, l’accès disque n’a lieu qu’une seule fois.
  • build() n’est exécuté que si le fichier manifeste n’existe pas. En fonctionnement normal, il n’est pas reconstruit à chaque requête.
  • Le fichier lui-même n’est qu’un simple tableau PHP retourné via return (bootstrap/cache/packages.php), la forme la plus rapide qui peut être chargée par un simple require.

Processus de construction du manifeste

C’est la méthode build() qui agrège les informations issues des composer.json.
Le point important est que Laravel ne lit pas directement le composer.json : il consulte vendor/composer/installed.json. Ce fichier est généré par Composer lors de composer install / composer update et regroupe les métadonnées de tous les packages installés. Les sections extra déclarées dans le composer.json de chaque package y sont agrégées, si bien que Laravel ne se fie qu’aux informations sous la responsabilité de Composer.
Comme installed.json est en général ignoré par Git (.gitignore), la découverte automatique ne fonctionne pas lors du tout premier setup (quand vendor/ n’existe pas). Le cache n’est construit qu’après un premier composer install.

Deux manières d’utiliser dont-discover

dont-discover peut être déclaré dans le composer.json du package ou dans celui de l’application, mais avec des significations différentes.
composer.json côté package
composer.json côté application
En observant l’implémentation de build(), on voit que le tableau $ignore est alimenté en cumulant, via array_merge, la valeur configuration['dont-discover'] de chaque package. Un package peut donc techniquement « désactiver la découverte automatique de ses propres dépendances » (par exemple pour éviter la double inscription d’un provider de sous-package qu’il utilise en interne). En pratique, la désactivation est cependant surtout utilisée côté application.

Utiliser * dans dont-discover

Si le tableau retourné par packagesToIgnore() contient *, $ignoreAll vaut true et la découverte automatique est complètement désactivée pour tous les packages. C’est utile en CI ou en environnement de test pour éviter le coût de la découverte, ou lorsque vous souhaitez tout gérer manuellement dans bootstrap/providers.php.

Le fichier de cache

getCachedPackagesPath() renvoie la valeur de la variable d’environnement APP_PACKAGES_CACHE si elle est définie, sinon bootstrap/cache/packages.php.
Si vous ouvrez ce fichier, vous constaterez qu’il se contente de retourner un tableau associatif simple.
Comme les clés sont les noms de packages, la sortie de php artisan package:discover vous permet de vérifier « quels packages ont été détectés ».

Quand le cache est-il reconstruit ?

Illuminate\Foundation\ComposerScripts s’abonne à trois événements Composer et appelle à chaque fois la même méthode clearCompiled().
Autrement dit, quel que soit l’événement (composer install / composer update / composer dump-autoload), les caches de configuration, de services et de packages sont supprimés d’un seul coup. Au démarrage suivant de Laravel, PackageManifest::build() s’exécute et reconstruit tout à partir de la dernière version d’installed.json. Ce comportement standard des projets Laravel est déclaré dans les scripts du composer.json.
composer.json d'une application Laravel (extrait)

Reconstruction manuelle via php artisan package:discover

Si le cache est resté obsolète, ou si vendor/ a été modifié sans passer par Composer, vous pouvez reconstruire manuellement le manifeste via la commande package:discover.
Cette commande n’est qu’un fin wrapper.
Elle se limite à appeler $manifest->build() puis à afficher le résultat : il n’y a quasiment aucune logique propre. Dans un pipeline CI qui utilise composer install --no-scripts par exemple, les événements Composer ne sont pas déclenchés et il faut donc appeler explicitement cette commande.
Si vous testez votre package avec Orchestra Testbench, sachez que Testbench fournit sa propre commande vendor/bin/testbench package:discover. Reportez-vous à Tester un package avec Testbench pour plus de détails. Elle est distincte de package:discover d’Artisan et construit le manifeste pour l’application squelette dédiée à Testbench.

Points d’attention lors du déploiement

En production, on exécute couramment composer install --no-dev --optimize-autoloader. Mais avec l’option --no-scripts, le cache des packages n’est pas mis à jour. Il est donc plus sûr d’ajouter une étape explicite de reconstruction à votre script de déploiement.
L’ordre compte : lancez package:discover avant config:cache. Si le cache de configuration est généré en premier, la configuration ajoutée ultérieurement par les packages (par exemple via mergeConfigFrom) risque de ne pas être prise en compte.

Récapitulatif

  • La découverte automatique s’appuie non pas sur le contenu statique du composer.json, mais sur vendor/composer/installed.json généré par Composer.
  • Le résultat est mis en cache dans bootstrap/cache/packages.php sous forme de tableau PHP brut, lisible très rapidement via un simple require.
  • Ce cache est automatiquement supprimé lors des événements composer install/update/dump-autoload, puis reconstruit au prochain démarrage.
  • Dans les environnements qui appellent Composer avec --no-scripts, il faut invoquer php artisan package:discover explicitement.
  • En plaçant * dans dont-discover, vous désactivez entièrement la découverte automatique.

Pages associées

Dernière modification le 2 août 2026