The Dotenv Component
The Dotenv Component parses.env
files to make environment variablesstored in them accessible via$_ENV
or$_SERVER
.
Installation
- $ composer require symfony/dotenv
Note
If you install this component outside of a Symfony application, you mustrequire the vendor/autoload.php
file in your code to enable the classautoloading mechanism provided by Composer. Readthis article for more details.
Usage
Sensitive information and environment-dependent settings should be defined asenvironment variables (as recommended for twelve-factor applications). Usinga .env
file to store those environment variables eases development and CImanagement by keeping them in one "standard" place and agnostic of thetechnology stack you are using (Nginx vs PHP built-in server for instance).
Note
PHP has a lot of different implementations of this "pattern". Thisimplementation's goal is to replicate what source .env
would do. Ittries to be as similar as possible with the standard shell's behavior (sono value validation for instance).
Load a .env
file in your PHP application via Dotenv::load()
:
- use Symfony\Component\Dotenv\Dotenv;
- $dotenv = new Dotenv();
- $dotenv->load(__DIR__.'/.env');
- // You can also load several files
- $dotenv->load(__DIR__.'/.env', __DIR__.'/.env.dev');
Given the following .env
file content:
- # .env
- DB_USER=root
- DB_PASS=pass
Access the value with $_ENV
in your code:
- $dbUser = $_ENV['DB_USER'];
- // you can also use ``$_SERVER``
The load()
method never overwrites existing environment variables. Use theoverload()
method if you need to overwrite them:
- // ...
- $dotenv->overload(__DIR__.'/.env');
As you're working with the Dotenv component you'll notice that you might wantto have different files depending on the environment you're working in. Typicallythis happens for local development or Continuous Integration where you mightwant to have different files for your test
and dev
environments.
You can use Dotenv::loadEnv()
to ease this process:
- use Symfony\Component\Dotenv\Dotenv;
- $dotenv = new Dotenv();
- $dotenv->loadEnv(__DIR__.'/.env');
The Dotenv component will then look for the correct .env
file to loadin the following order whereas the files loaded later override the variablesdefined in previously loaded files:
- If
.env
exists, it is loaded first. In case there's no.env
file but a.env.dist
, this one will be loaded instead. - If one of the previously mentioned files contains the
APP_ENV
variable, thevariable is populated and used to load environment-specific files hereafter. IfAPP_ENV
is not defined in either of the previously mentioned files,dev
isassumed forAPP_ENV
and populated by default. - If there's a
.env.local
representing general local environment variables it's loaded now. - If there's a
.env.$env.local
file, this one is loaded. Otherwise, it fallsback to.env.$env
.This might look complicated at first glance but it gives you the opportunity tocommit multiple environment-specific files that can then be adjusted to yourlocal environment. Given you commit.env
,.env.test
and.env.dev
torepresent different configuration settings for your environments, each of themcan be adjusted by using.env.local
,.env.test.local
and.env.dev.local
respectively.
Note
.env.local
is always ignored in test
environment because tests should produce thesame results for everyone.
You can adjust the variable defining the environment, default environment and testenvironments by passing them as additional arguments to Dotenv::loadEnv()
(see loadEnv()
for details).
New in version 4.2: The Dotenv::loadEnv()
method was introduced in Symfony 4.2.
You should never store a .env
file in your code repository as it mightcontain sensitive information; create a .env.dist
file (or multipleenvironment-specific ones as shown above) with sensible defaults instead.
Note
Symfony Dotenv can be used in any environment of your application:development, testing, staging and even production. However, in productionit's recommended to configure real environment variables to avoid theperformance overhead of parsing the .env
file for every request.
As a .env
file is a regular shell script, you can source
it in your ownshell scripts:
- source .env
Add comments by prefixing them with #
:
- # Database credentials
- DB_USER=root
- DB_PASS=pass # This is the secret password
Use environment variables in values by prefixing variables with $
:
- DB_USER=root
- DB_PASS=${DB_USER}pass # Include the user as a password prefix
Note
The order is important when some env var depends on the value of other envvars. In the above example, DB_PASS
must be defined after DB_USER
.Moreover, if you define multiple .env
files and put DB_PASS
first,its value will depend on the DB_USER
value defined in other filesinstead of the value defined in this file.
Embed commands via $()
(not supported on Windows):
- START_TIME=$(date)
Note
Note that using $()
might not work depending on your shell.