· 7 min read
A la découverte des variables d'environnement de Symfony
Dans cet article, nous allons partir à la découverte des variables d'environnement de Symfony, et vous allez voir qu'il y a une infinité de façons de les définir ou des les utiliser!
Objectifs
Dans cet article, nous allons partir à la découverte des variables d’environnement de Symfony, et vous allez voir qu’il y a une infinité de façons de les définir ou des les utiliser!
Au programme :
- Définir des variables d’environnement
- Définir des variables d’environnement avec un fichier
.env
et.env.local
- Hierarchie des fichiers de variables d’environnement
- Définir des variables d’environnement avec un fichier
- La CLI
- Dumper les variables d’environnement
- Lister les variables d’environnement en CLI
- Accéder aux variables d’environnement
- Accéder aux variables d’environnement depuis les contrôleurs
- Accéder aux variables d’environnement depuis les services
- Accéder aux variables d’environnement depuis Twig
- Mettez vos variables d’environnement en sécurité
- Utilisation du systeme de gestion des secrets de Symfony
Initier notre projet Symfony
Créons notre projet et entrons dans le dossier :
symfony new variables_environement --webapp
cd variables_environement
Créons un controller de test :
symfony console make:controller TestController
Démarrons notre application :
symfony serve -d
Et supprimons toutes références à Webpack dans le fichier templates/base.html.twig
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>">
{# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #}
{% block stylesheets %}
{% endblock %}
{% block javascripts %}
{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
Définir des variables d’environnement
Définir des variables d’environnement avec un fichier .env
et .env.local
Par default, Symfony utilise les variables d’environnement définies dans le fichier .env
pour définir les variables d’environnement.
Si on consulte ce fichier on peut voir qu’il y a plusieurs variables d’environnement (j’ai supprimé les commentaires) :
APP_ENV=dev
APP_SECRET=d039c490ad66d067877186a6640183ab
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
DATABASE_URL="postgresql://symfony:ChangeMe@127.0.0.1:5432/app?serverVersion=13&charset=utf8"
La bonne façon de définir des variables d’environnement est de créer un fichier .env.local
qui contient les variables d’environnement à utiliser pour le développement sur votre machine et de ne jamais définir des variables d’environnement dans le fichier .env
(qui est commit sur Git).
Finalement, le fichier .env
est une sorte de template qui permet de définir des variables d’environnement utilisées dans le projet.
Copions donc le fichier .env
dans un fichier .env.local
.
cp .env .env.local
Nous pouvons checker les variables d’environnement avec la debug barre :
Ajoutons une variable d’environnement :
- Dans le fichier
.env
DEMO=
- Dans le fichier
.env.local
DEMO="Ceci est une démo"
Et checkons les variables d’environnement :
Hierarchie des fichiers de variables d’environnement
Nous l’avons juste avant, le fichier .env.local
est prioritaire sur le fichier .env
.
Mais il est possible d’ajouter encore de la finesse dans votre architecture de projet en créant un fichier .env.dev
qui contient des variables d’environnement spécifiques à un environnement de développement.
Et copions le contenu du fichier .env.local
dans le fichier .env.dev
:
cp .env.local .env.dev
Et modifiont légèrement le contenu du fichier .env.dev
:
DEMO="Ceci est une démo depuis le fichier .env.local"
Nous constatons que le fichier .env.dev
est prioritaire sur le fichier .env.local
:
Poussons encore plus loin dans notre architecture de projet en créant un fichier .env.dev.local
en y copiant le contenu du fichier .env.dev
:
cp .env.dev .env.dev.local
Nous constatons que le fichier .env.dev.local
est prioritaire sur le fichier .env.dev
:
La CLI
Dumper les variables d’environnement
Pour des raisons de performances, noatement en production, et afin d’éviter de parser les fichiers .env
à chaque requête, nous pouvons utiliser la commande dump-env
pour afficher les variables d’environnement dans un fichier PHP :
composer dump-env dev # ou prod
Un fichier .env.php
sera créé à la racine du projet :
<?php
// This file was generated by running "composer dump-env dev"
return array (
'APP_ENV' => 'dev',
'APP_SECRET' => 'd039c490ad66d067877186a6640183ab',
'MESSENGER_TRANSPORT_DSN' => 'doctrine://default?auto_setup=0',
'DATABASE_URL' => 'postgresql://symfony:ChangeMe@127.0.0.1:5432/app?serverVersion=13&charset=utf8',
'DEMO' => 'Ceci est une démo depuis le fichier .env.dev.local',
);
Modifier le contenu du fichier .env.php
(A ne jamais faire, c’est uniquement pour la démo) :
<?php
// This file was generated by running "composer dump-env dev"
return array (
'APP_ENV' => 'dev',
'APP_SECRET' => 'd039c490ad66d067877186a6640183ab',
'MESSENGER_TRANSPORT_DSN' => 'doctrine://default?auto_setup=0',
'DATABASE_URL' => 'postgresql://symfony:ChangeMe@127.0.0.1:5432/app?serverVersion=13&charset=utf8',
'DEMO' => 'Ceci est une démo depuis le fichier .env.local.php',
);
Et vérifions que les variables d’environnement sont bien modifiées :
Lister les variables d’environnement en CLI
La multiplicité des fichiers peut rendre la lecture des variables d’environnement difficile. C’est pourquoi il existe une commande qui permet de lister les variables d’environnement :
symfony console debug:dotenv
Le résultat de la commande est hyper clair :
Accéder aux variables d’environnement
Maintenant que nous avons vu comment récupérer les variables d’environnement, nous pouvons les utiliser dans notre application.
Accéder aux variables d’environnement depuis les contrôleurs
Afin d’acceder à vos variables d’environnement depuis les contrôleurs, nous devons les ajouter dans notre fichier config/services.yaml
:
parameters:
DEMO: '%env(DEMO)%'
Vérifions avec une nouvelle commande que notre variable d’environnement est bien présente :
symfony console debug:container --env-vars
Dans notre controlleur src/Controller/TestController.php
ajoutons de quoi accéder à la variable d’environnement :
#[Route('/test', name: 'app_test')]
public function index(): Response
{
$demo = $this->getParameter('DEMO');
dd($demo);
return $this->render('test/index.html.twig', [
'controller_name' => 'TestController',
]);
}
Et vérifions !
Accéder aux variables d’environnement depuis les services
Voyons maintenant comment accéder aux variables d’environnement depuis les services.
La méthode “manuelle”
Commençons par créer un service dans le fichier src/Service/DemoService.php
qui permet de récupérer les variables d’environnement :
<?php
namespace App\Service;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class DemoService
{
public function __construct(ParameterBagInterface $parameterBag)
{
$this->parameterBag = $parameterBag;
}
public function getDemo(): string
{
return $this->parameterBag->get('DEMO');
}
}
Et modifions notre controlleur src/Controller/TestController.php
pour utiliser notre service :
<?php
namespace App\Controller;
use App\Service\DemoService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class TestController extends AbstractController
{
#[Route('/test', name: 'app_test')]
public function index(DemoService $demoService): Response
{
dd($demoService->getDemo());
return $this->render('test/index.html.twig', [
'controller_name' => 'TestController',
]);
}
}
On rafraichit notre page, c’est bien le contenu de la variable d’environnement qui est affiché :
La méthode “automatique”
Plutôt que d’utiliser le ParameterBagInterface
dans le service pour récupérer les variables d’environnement, nous pouvons utiliser la méthode “automatique” de Symfony pour injecter les variables d’environnement.
Dans notre fichier config/services.yaml
ajoutons :
parameters:
DEMO: '%env(DEMO)%'
services:
# ...
App\Service\DemoService:
arguments:
$demo: '%env(DEMO)%'
Et utilisons notre argument $demo
dans notre service :
<?php
namespace App\Service;
class DemoService
{
public function __construct(
public string $demo
) {
}
public function getDemo(): string
{
return $this->demo;
}
}
Nous pouvons vérifier que tout fonctionne :
Accéder aux variables d’environnement depuis Twig
Nous pouvons aussi accéder aux variables d’environnement depuis Twig.
Pour cela, nous devons ajouter une variable d’environnement dans notre fichier config/packages/twig.yaml
:
twig:
default_path: '%kernel.project_dir%/templates'
globals:
DEMO: '%env(DEMO)%'
Et dans notre fichier templates/test/index.html.twig
nous pouvons accéder à la variable d’environnement directement :
{% extends 'base.html.twig' %}
{% block title %}Hello TestController!{% endblock %}
{% block body %}
{{ DEMO }}
{% endblock %}
Et on rafraichit notre page, c’est bien le contenu de la variable d’environnement qui est affiché :
Mettez vos variables d’environnement en sécurité
Comme nous l’avons vu jusqu’ici, nous pouvons accéder aux variables d’environnement depuis n’importe quel endroit de notre application. Nos stockons les variables d’environnement dans un simple fichier.
C’est certe pratique mais pas necessairement sécurisé.
Utilisation du systeme de gestion des secrets de Symfony
Symfony propose un système de gestion des secrets basé sur un systeme de clés cryptographiques.
Génération des clés
Première étape, nous allons générer les clés :
php bin/console secrets:generate-keys
Nous constatons que les clés sont générées avec succès dans les deux fichiers suivants :
- config/secrets/dev/dev.decrypt.private.php
- config/secrets/dev/dev.decrypt.public.php
Si vous souhaitez générer les clés pour la production :
APP_ENV=prod php bin/console secrets:generate-keys
Nous constatons que les clés sont générées avec succès dans les deux fichiers suivants :
- config/secrets/prod/prod.decrypt.private.php
- config/secrets/prod/prod.decrypt.public.php
Pensez à vérifier que votre fichier prod.decrypt.private.php
est bien présent dans votre .gitignore
:
/config/secrets/prod/prod.decrypt.private.php
Ajouter une variable d’environnement à la liste des secrets
Pour ajouter un nouveau secret (DEMO_SECRET: Ceci est un secret
) nous devons utiliser la commande suivante :
php bin/console secrets:set DEMO_SECRET
Pour la production :
APP_RUNTIME_ENV=prod php bin/console secrets:set DEMO_SECRET
Nous constatons la création d’un nouveau fichier config/secrets/dev/dev.DEMO_SECRET.80921a.php
qui contient notre variable d’environnement chiffrée :
<?php // dev.DEMO_SECRET.80921a on Mon, 07 Mar 2022 10:07:38 +0100
return "\xCD\x9B\x7F6\xDC\xC9\x82\xE6\xEB\xE2\x808\xBF\xA9P\xA8\x9BL\x3A\xA5\xC0\xBD\xA6\xA6\xA7\x7D\x10\xCD\xE9\xD0\xBEg\xA3ez\x8A\xC2\x91k\xD04DDLo\x9D\xB9\x17\xCD\xC9\x989\x24\x3A\xC3U\xFCFP\x5CQ\xC0\xB9\xA3T\x60";
Et accédons à notre variable d’environnement depuis Twig :
twig:
default_path: '%kernel.project_dir%/templates'
globals:
DEMO: '%env(DEMO)%'
DEMO_SECRET: '%env(DEMO_SECRET)%'
Modifions notre fichier twig templates/test/index.html.twig
:
{% extends 'base.html.twig' %}
{% block title %}Hello TestController!{% endblock %}
{% block body %}
{{ DEMO_SECRET }}
{% endblock %}
Dumpons nos variables d’environnement :
composer dump-env dev
Et constatons le résultat :
Set d’un secret en local
Vous pouvez aussi set un secret en local (valable uniquement sur votre machine) :
php bin/console secrets:set --local DEMO_SECRET
Dumpons nos variables d’environnement :
composer dump-env dev
Et vérifions :
Quelques outils pour gérer les secrets
- Lister les secrets :
php bin/console secrets:list --reveal
------------- ---------------------- ----------------------------
Secret Value Local Value
------------- ---------------------- ----------------------------
DEMO_SECRET "Ceci est un secret" "Ceci est un secret local"
------------- ---------------------- ----------------------------
- Supprimer un secret :
php bin/console secrets:remove DEMO_SECRET