Fichier configuration avec Symfony 6

Les applications Symfony sont configurées avec les fichiers stockés dans le répertoire config/, qui a cette structure par défaut :

your-project/
├─ config/
│  ├─ packages/
│  ├─ bundles.php
│  ├─ routes.yaml
│  └─ services.yaml
├─ ...

Le fichier routes.yaml définit la configuration du routage ; le fichier services.yaml configure les services du conteneur de services ; le fichier bundles.php active/désactive les paquets dans votre application.

Vous travaillerez principalement dans le répertoire config/packages/. Ce répertoire stocke la configuration de chaque paquet installé dans votre application. Les paquets (également appelés « bundles » dans Symfony et « plugins/modules » dans d’autres projets) ajoutent des fonctionnalités prêtes à l’emploi à vos projets.

Lorsque vous utilisez Symfony Flex, qui est activé par défaut dans les applications Symfony, les packages mettent à jour le fichier bundles.php et créent de nouveaux fichiers dans config/packages/ automatiquement pendant leur installation. Par exemple, voici le fichier par défaut créé par le paquet « API Platform » :

# config/packages/api_platform.yaml
api_platform:
    mapping:
        paths: ['%kernel.project_dir%/src/Entity']

La division de la configuration en un grand nombre de petits fichiers est intimidante pour certains nouveaux venus dans Symfony. Cependant, vous vous y habituerez rapidement et vous aurez rarement besoin de modifier ces fichiers après l’installation du paquet.

Pour connaître toutes les options de configuration disponibles, consultez la référence de configuration de Symfony ou exécutez la commande config:dump-reference.

Formats de configuration

Contrairement à d’autres frameworks, Symfony ne vous impose pas un format spécifique pour configurer vos applications. Symfony vous laisse choisir entre YAML, XML et PHP et dans toute la documentation de Symfony, tous les exemples de configuration seront présentés dans ces trois formats.

Il n’y a pas de différence pratique entre les formats. En fait, Symfony les transforme et les met en cache en PHP avant d’exécuter l’application, donc il n’y a même pas de différence de performance entre eux.

YAML est utilisé par défaut lors de l’installation de paquets car il est concis et très lisible. Ce sont les principaux avantages et inconvénients de chaque format :

  • YAML : simple, propre et lisible, mais tous les IDE ne prennent pas en charge l’autocomplétion et la validation pour ce langage. Apprenez la syntaxe YAML ;
  • XML : autocomplétion/validation par la plupart des IDE et est analysé nativement par PHP, mais il génère parfois une configuration jugée trop verbeuse. Apprenez la syntaxe XML ;
  • PHP : très puissant, il permet de créer une configuration dynamique avec des tableaux ou un ConfigBuilder.

Par défaut, Symfony ne charge que les fichiers de configuration définis au format YAML. Si vous définissez une configuration au format XML et/ou PHP, mettez à jour le fichier src/Kernel.php pour ajouter le support des extensions de fichiers .xml et .php.

Importation de fichiers de configuration

Symfony charge les fichiers de configuration à l’aide du composant Config, qui offre des fonctionnalités avancées telles que l’importation d’autres fichiers de configuration, même s’ils utilisent un format différent :

# config/services.yaml
imports:
    - { resource: 'legacy_config.php' }

    # glob expressions are also supported to load multiple files
    - { resource: '/etc/myapp/*.yaml' }

    # ignore_errors: not_found silently discards errors if the loaded file doesn't exist
    - { resource: 'my_config_file.xml', ignore_errors: not_found }
    # ignore_errors: true silently discards all errors (including invalid code and not found)
    - { resource: 'my_other_config_file.xml', ignore_errors: true }

# ...

Paramètres de configuration

Parfois, la même valeur de configuration est utilisée dans plusieurs fichiers de configuration. Au lieu de la répéter, vous pouvez la définir comme un « paramètre », qui est comme une valeur de configuration réutilisable. Par convention, les paramètres sont définis sous la clé parameters dans le fichier config/services.yaml :

# config/services.yaml
parameters:
    # the parameter name is an arbitrary string (the 'app.' prefix is recommended
    # to better differentiate your parameters from Symfony parameters).
    app.admin_email: 'something@example.com'

    # boolean parameters
    app.enable_v2_protocol: true

    # array/collection parameters
    app.supported_locales: ['en', 'es', 'fr']

    # binary content parameters (encode the contents with base64_encode())
    app.some_parameter: !!binary VGhpcyBpcyBhIEJlbGwgY2hhciAH

    # PHP constants as parameter values
    app.some_constant: !php/const GLOBAL_CONSTANT
    app.another_constant: !php/const App\Entity\BlogPost::MAX_ITEMS

# ...

Une fois définie, vous pouvez faire référence à la valeur de ce paramètre à partir de n’importe quel autre fichier de configuration en utilisant une syntaxe spéciale : entourez le nom du paramètre de deux % (par exemple, %app.admin_email%) :

# config/packages/some_package.yaml
some_package:
    # any string surrounded by two % is replaced by that parameter value
    email_address: '%app.admin_email%'

    # ...

Si une valeur de paramètre inclut le caractère %, vous devez l’échapper en ajoutant un autre % afin que Symfony ne le considère pas comme une référence à un nom de paramètre :

# config/services.yaml
parameters:
    # Parsed as 'https://symfony.com/?foo=%s&bar=%d'
    url_pattern: 'https://symfony.com/?foo=%%s&bar=%%d'

En raison de la manière dont les paramètres sont résolus, vous ne pouvez pas les utiliser pour construire dynamiquement des chemins dans les importations. Cela signifie que quelque chose comme ce qui suit ne fonctionne pas :

# config/services.yaml
imports:
    - { resource: '%kernel.project_dir%/somefile.yaml' }

Les paramètres de configuration sont très courants dans les applications Symfony. Certains paquets définissent même leurs propres paramètres (par exemple, lors de l’installation du paquet de traduction, un nouveau paramètre de locale est ajouté au fichier config/services.yaml).

Environnements de configuration

Vous n’avez qu’une seule application, mais que vous le réalisiez ou non, vous avez besoin qu’elle se comporte différemment à différents moments :

  • Pendant le développement, vous voulez que tout soit consigné et que de bons outils de débogage soient disponibles ;
  • Après le déploiement en production, vous voulez que cette même application soit optimisée pour la vitesse et qu’elle ne consigne que les erreurs.

Les fichiers stockés dans config/packages/ sont utilisés par Symfony pour configurer les services de l’application. En d’autres termes, vous pouvez modifier le comportement de l’application en changeant les fichiers de configuration qui sont chargés. C’est l’idée des environnements de configuration de Symfony.

Une application Symfony typique commence avec trois environnements : dev (pour le développement local), prod (pour les serveurs de production) et test (pour les tests automatisés). Lors de l’exécution de l’application, Symfony charge les fichiers de configuration dans cet ordre (les derniers fichiers peuvent remplacer les valeurs définies dans les précédents) :

  1. config/packages/*.yaml (et aussi les fichiers *.xml et .php) ;
  2. config/packages/<environment-name>/*.yaml (and *.xml and *.php files too);
  3. config/services.yaml (ainsi que les fichiers services.xml et services.php) ;
  4. config/services_.yaml (ainsi que les fichiers services_.xml et services_.php).

Prenons l’exemple du paquetage framework, installé par défaut :

  • Tout d’abord, config/packages/framework.yaml est chargé dans tous les environnements et il configure le framework avec quelques options ;
  • Dans l’environnement prod, rien de supplémentaire ne sera défini car il n’y a pas de fichier config/packages/prod/framework.yaml ;
  • Dans l’environnement dev, il n’y a pas non plus de fichier ( config/packages/dev/framework.yaml n’existe pas).
  • Dans l’environnement de test, le fichier config/packages/test/framework.yaml est chargé pour remplacer certains des paramètres précédemment configurés dans config/packages/framework.yaml.

En réalité, chaque environnement ne diffère que peu des autres. Cela signifie que tous les environnements partagent une large base de configuration commune, qui est placée dans des fichiers directement dans le répertoire config/packages/.

Sélection de l’environnement actif

Les applications Symfony sont livrées avec un fichier appelé .env situé dans le répertoire racine du projet. Ce fichier est utilisé pour définir la valeur des variables d’environnement et il est expliqué en détail plus loin dans cet article.

Ouvrez le fichier .env (ou mieux, le fichier .env.local si vous en avez créé un) et modifiez la valeur de la variable APP_ENV pour changer l’environnement dans lequel l’application s’exécute. Par exemple, pour exécuter l’application en production :

# .env (or .env.local)
APP_ENV=prod

Cette valeur est utilisée à la fois pour le Web et pour les commandes de la console. Cependant, vous pouvez la remplacer pour les commandes en définissant la valeur APP_ENV avant de les exécuter :

php bin/console command_name


APP_ENV=prod php bin/console command_name

Créer un nouvel environnement

Les trois environnements par défaut fournis par Symfony sont suffisants pour la plupart des projets, mais vous pouvez également définir vos propres environnements. Par exemple, voici comment vous pouvez définir un environnement staging où le client peut tester le projet avant de le mettre en production :

  • Créez un répertoire de configuration portant le même nom que l’environnement (dans ce cas, config/packages/staging/) ;
  • Ajouter les fichiers de configuration nécessaires dans config/packages/staging/ pour définir le comportement du nouvel environnement. Symfony charge les fichiers config/packages/*.yaml en premier, donc vous avez seulement besoin de configurer les différences avec ces fichiers ;
  • Sélectionnez l’environnement de staging en utilisant la var env APP_ENV comme expliqué dans la section précédente.