Buy
Buy

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

Login Subscribe

When you deploy to production, you're supposed to set all these environment variables correctly. If you look back at index.php:

40 lines public/index.php
... lines 1 - 9
// The check is to ensure we don't use .env in production
if (!isset($_SERVER['APP_ENV'])) {
if (!class_exists(Dotenv::class)) {
throw new \RuntimeException('APP_ENV environment variable is not defined. You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency to load variables from a .env file.');
}
(new Dotenv())->load(__DIR__.'/../.env');
}
... lines 17 - 40

If the APP_ENV environment variable is set already, it knows to skip loading the .env file.

Tip

If you start a new project today, you won't see this APP_ENV logic. It's been moved to a config/bootstrap.php file.

In reality... in a lot of server environments, setting environment variables can be a pain. You can do it in your Apache virtual host or in PHP-FPM. Oh, and you'll need to make sure it's set at the command line too, so you can run bin/console.

If you use a Platform-as-a-Service like Platform.sh or Heroku, then setting environment variables is super easy! Lucky you!

But if setting environment variable is tough in your situation, well, you could still use the .env file. I mean if we deployed right now, we could create this file, put all the real values inside, and Symfony would use that! Well, if you're planning on doing this, make sure to move the dotenv library from the require-dev section of your composer.json to require by removing and re-adding it:

composer remove symfony/dotenv
composer require symfony/dotenv

The reason that using .env isn't recommended is mostly because the logic to parse this file isn't optimized: it's not meant for production! So, you'll lose a small amount of performance - probably just a couple of milliseconds, but you can profile it to be sure.

Tip

The performance cost of .env has been shown to be low. It is ok to use a .env file in production if that's the most convenient way for you to set environment variables.

Casting Environment Variables

But... there is one other limitation of environment variables that affects everyone: environment variables are always strings! But, what if you need an environment variable that's set to true or false? Well... when you read it with the special syntax, "false" will literally be the string "false". Boo!

Don't worry! Environment variables have one more trick! You can cast values by prefixing the name with, for example, string::

nexy_slack:
endpoint: '%env(string:SLACK_WEBHOOK_ENDPOINT)%'

Well, this is already a string, but you get the idea!

To show some better examples, Google for Symfony Advanced Environment Variables to find a blog post about this feature. Cooooool. This DATABASE_PORT should be an int so... we cast it! You can also use bool or float.

Setting Default Environment Variables

This is great... but then, the Symfony devs went crazy. First, as you'll see in this blog post, you can set default environment variable values under the parameters key. For example, by adding an env(SECRET_FILE) parameter, you've just defined a default SECRET_FILE environment value. If a real SECRET_FILE environment variable were set, it would override this.

Custom Processing

More importantly, there are 5 other prefixes you can use for special processing:

  • First, resolve: will resolve parameters - the %foo% things - if you have them inside your environment variable;

  • Second, you can use file: to return the contents of a file, when that file's path is stored in an environment variable;

  • Third, base64: will base64_decode a value: that's handy if you have a value that contains line breaks or special characters: you can base64_encode it to make it easier to set as an environment variable;

  • Fourth, constant: allows you to read PHP constants;

  • And finally, json: will, yep, call your friend Jason on the phone. Hey Jason! I mean, it will json_decode() a string.

And, ready for the coolest part? You can chain these: like, open a file, and then decode its JSON:

app.secrets: '%env(json:file:SECRETS_FILE)%'

Actually, sorry, there's more! You can even create your own, custom prefix - like blackhole: and write your own custom processing logic.

Ok, I'll shut up already about environment variables! They're cool, yadda, yadda, yadda.

Let's move on to a super fun, super unknown "extra" with autowiring.

Leave a comment!

  • 2018-08-08 Diego Aguiar

    Hmm, nice question and to be honest I'm not totally sure but I would choose a place that is outside of the public web directory (I'm not sure if you can do that in a shared hosting)

  • 2018-08-07 Mike

    Thanks for the fast reply!

    Since most "shared web hosting companys" do not provide access to the apache virtual host file, whats the best solution for this case?

  • 2018-08-07 Diego Aguiar

    Hey Mike

    If the variable may change depending on the machine (server) where the project lives, then, it must be an "Environment" variable, if not, then, it can be an application's variable.

    I would recommend storing your env variables inside the vhost config file instead of ".htaccess" file because it's more secure

    Cheers!

  • 2018-08-07 Mike

    Example:
    Apache production webhost, do I understand you right that it is recommended to set the env variable via (by example):

    SF-Project/public/.htaccess

    SetEnv SLACK_WEBHOOK_ENDPOINT https://...
    [...Symfony other stuff...]

    Is this the correct way for apache?
    I keep asking myself because it seems to make sense to keep this project related informations inside the project itself rather than inside an apache vhost config file.

  • 2018-05-21 Kegan VanSickle

    Exactly, that's how I've always done it. Thank you for the reassuring response!

  • 2018-05-21 Victor Bocharsky

    Hey Kegan,

    You're right, it was app/config/parameters.yml file for server-specific parameters, which should not be committed, but there's should be another one - app/config/parameters.yml.dist which should and hold the same keys but different (dummy) values which work for dev/test environment.

    Cheers!

  • 2018-05-20 Kegan VanSickle

    For the environment variables, previous convention in Symfony 2 and 3, (or so I thought), was to store them in separate environment config yaml files that are ignored and not committed, but live in the config directory.

  • 2018-02-16 Diego Aguiar

    Hey Jose Diaz

    Good observation, but remember that is not recommended to use it on production, maybe if you have developed a small app, and you just want to deploy it, you could rely on it so you can avoid the over head of configuring environment variables manually, but as soon as your project starts growing, you should consider removing that bundle from production, and use "your" particular method of setting up env variables

    Cheers!

  • 2018-02-16 Jose Diaz

    Hi, on 1:16 I don't think you meant to have the --dev on the composer call, because you are explaining how to add it for production. Thanks!