Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This tutorial has a new version, check it out!

dotenv: Environmental Variables

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $10.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

The $debug and $environment variables are hardcoded in index.php. So if we deploy this, we'll either have a web debug toolbar on production, or we'll need to manually modify this file to set $debug to false. Both situations stink.

PHP dotenv Fanciness

To help, we'll install a new library: composer require vlucas/phpdotenv:

composer require vlucas/phpdotenv

While we're waiting, Google for that library and find its documentation.

This is a popular library these days, and I really like it too. It allows you to have a .env file at the root of your project. It'll look something like this:

S3_BUCKET="dotenv"
SECRET_KEY="souper_seekret_key"

This library reads these values and turns S3_BUCKET and SECRET_KEY into environment variables. Then, in our app, whenever we need some configuration - like whether we're in debug mode, the database password or the S3 bucket - we'll read from the environment variables. When you eventually deploy, you can set those variables in two different ways. First, you can have a .env file. Or second, you can set the variables via something like your web server configuration. Some platforms - like Heroku also have a way to set environment variables. The important point is that your app isn't bound to a configuration file: it's just reading environment variables, which is a pretty standard way of setting config.

Our .env File

The first things we want to set are the $env and $debug flags. Create a .env file and say SYMFONY_ENV=dev and SYMFONY_DEBUG=1:

4 lines .env
# basic setup
SYMFONY_ENV=dev
SYMFONY_DEBUG=1

Remove the old variables in index.php. Replace it with $dotenv = new DotEnv\DotEnv(). The argument is the directory where the .env file lives - it's actually up one directory from here. Then, call $dotenv->load():

26 lines web/index.php
... lines 1 - 9
// load the environmental variables
$dotenv = new Dotenv\Dotenv(__DIR__.'/../');
$dotenv->load();
... lines 13 - 26

At this point, those two flags have been set as environment variables. That means we can say $env = $_SERVER['SYMFONY_ENV']; and $debug = $_SERVER['SYMFONY_DEBUG'];:

26 lines web/index.php
... lines 1 - 9
// load the environmental variables
$dotenv = new Dotenv\Dotenv(__DIR__.'/../');
$dotenv->load();
$env = $_SERVER['SYMFONY_ENV'];
$debug = $_SERVER['SYMFONY_DEBUG'];
... lines 15 - 26

Go back and refresh the new setup - we should still see the toolbar. Yep, there it is. But now go back to .env and set SYMFONY_DEBUG to 0. Because of config.yml, this should turn the toolbar off. Change the environment to prod too - that's not being used anywhere yet, but it may avoid a temporary cache error:

4 lines .env
# basic setup
SYMFONY_ENV=prod
SYMFONY_DEBUG=0

Try it out: no web debug toolbar.

Add .env to the .gitignore file - this shouldn't be committed:

5 lines .gitignore
... lines 1 - 3
/.env

But copy .env to .env.example - we will commit this so that new developers have something they can use as a guide.

Leave a comment!

11
Login or Register to join the conversation
Default user avatar
Default user avatar mgrachev | posted 1 year ago

Another useful tool - https://github.com/dotenv-l....
It’s a lightning-fast linter for .env files. Written in Rust.

Reply

Hey @mgrachev,

Thanks for sharing it with others. It might be useful for someone, or might be an overkill, depends on the project.

Cheers!

Reply

Do we need to use "vlucas/phpdotenv" or "symffony/dotenv" ? what's is the diffrence any way Is it possible to access to environments into a syfmony command ? I'm facing this error In EnvVarProcessor.php line 76 and I'm using symfony/dotenv
[Symfony\Component\DependencyInjection\Exception\EnvNotFoundException]
Environment variable not found
withh symfony3.4

Reply

Hey ahmedbhs!

First, this IS a bit of an old tutorial, as modern Symfony handles all of this for you :). But, the questions are still interesting! So, let's see:

> Do we need to use "vlucas/phpdotenv" or "symfony/dotenv" ?

It basically doesn't matter. Symfony made their version specifically to be a bit less fancy and more shell-like. And then more features were added.

> Is it possible to access to environments into a symfony command

Definitely! There are a few ways, the easiest (but maybe not cleanest) would be to grab it form $_SERVER - like $_SERVER['MY_VAR']. A more advanced way would be to inject it into your commands by leveraging the dependency injection container. And... it looks like maybe you are trying this?

> I'm facing this error In EnvVarProcessor.php line 76 and I'm using symfony/dotenv
[Symfony\Component\DependencyInjection\Exception\EnvNotFoundException]
Environment variable not found

Can you show me your code? This would usually happen if you're configuring a service and using the %env(SOME_VAR)% format to access an environment var (which is good!). But, for some reason your environment variable isn't found. The logic that class uses is pretty simple - you can see it here: https://github.com/symfony/...

Share some code related to this if you can and I'm sure we can get it working :). Btw, using symfony/dotenv vs vlucas for this specific piece should not make a difference.

Cheers!

Reply
Csaba B. Avatar
Csaba B. Avatar Csaba B. | posted 3 years ago

What is the difference? Which environment var used by Symfony 4.x?

SYMFONY_DEBUG vs APP_DEBUG and APP_ENV vs SYMFONY_ENV?

Reply

Yo Csaba B.!

Ah, great question! In practice, very little :). This tutorial pre-dates Symfony 4 and Symfony Flex by quite a long time. But some of its ideas were eventually used in Symfony 4, and this is one of them. In this tutorial, SYMFONY_ENV becomes the Symfony environment and in Symfony 4, APP_ENV becomes the Symfony environment. There are some subtle differences, but basically they do the same thing. The same is true for the DEBUG env vars, except that you don't *need* to define APP_DEBUG in Symfony 4 - if you don't define it, it's "guessed" from the APP_ENV value.

Cheers!

Reply
Csaba B. Avatar

Thank you so much :)

I found some useful info too about env variables on Fabien's blog site. See the "Environment Variables" part here: http://fabien.potencier.org...

1 Reply

Yes, great resource! Thanks for sharing!

1 Reply
Default user avatar
Default user avatar Caim Astraea | posted 4 years ago

Hello
Anyone knows how to define the databse url ? Been trying out https://medium.com/@fabpot/...
but it doesn't seem to like the url my mysql also uses a password unlike the example.
Tried like this DATABASE_URL=mysql://newuser:Dorobanti71#$@127.0.0.1:3306/symfony?charset=utf8mb4
but am getting
DBALException in DriverManager.php line 259:
Malformed parameter "url".
in DriverManager.php line 259
at DriverManager::parseDatabaseUrl(array('url' => 'mysql://newuser:Dorobanti71#$@127.0.0.1:3306/symfony?charset=utf8mb4', 'host' => 'localhost', 'port' => null, 'user' => 'root', 'password' => null, 'driver' => 'pdo_mysql', 'driverOptions' => array(), 'defaultTableOptions' => array())) in DriverManager.php line 144

Reply
Default user avatar

hmm weird it works with root user without password
seems the parseDatabaseUrl function https://github.com/doctrine... doesn't like that url string.

Reply

Yo Caim Astraea!

I don't know the answer specifically, but I do know that the DriverManager you linked to uses parse_url to break the URL into pieces. So that should, in theory, work fine. However, you might need to urlencode some of the special characters in your password. Check out the latest commit to that class, which add support for this: https://github.com/doctrine..., and the PR behind it: https://github.com/doctrine...

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "symfony/symfony": "^2.7", // v2.7.2
        "sensio/framework-extra-bundle": "^3.0", // v3.0.9
        "vlucas/phpdotenv": "^2.0", // v2.0.1
        "symfony/monolog-bundle": "^2.7" // v2.7.1
    }
}