How can I retrieve my environment variables in a parameter file in Symfony4 structure?
Asked Answered
A

2

9

I did a fresh Symfony installation by using Symfony Flex and the new skeleton belong to the next Symfony 4 directory structure.

I add and configure a first third-party bundle : HWIOAuthBundle. This bundle is used to connect via Twitter using two secret information.

I declare my consumer_id and my consumer_secret in the config/packages/hwi_oauth.yaml file.

hwi_oauth:
    firewall_names: [secured_area]
    resource_owners:
        twitter:
            type:          twitter
            client_id:     XXXXXMyIdXXXXX
            client_secret: XXXXXMyTopSecretKeyXXXXX

My application works fine. But I cannot commit my secrets on github!

I want to have a hwi_oauth.yaml file like this one:

hwi_oauth:
    firewall_names: [secured_area]
    resource_owners:
        twitter:
            type:          twitter
            client_id:     '%twitter_consumer_id%'
            client_secret: '%twitter_consumer_secret%'

I read the Symfony4 best practices about the new DotEnv package.

Using environment variables, while far from being perfect, have many benefits over what we currently do. Environment variables are a more "standard" way of managing settings that depend on the environment (no need to manage a parameters.yml.dist for instance).

As suggested in best practices, I append these two line to .env file:

TWITTER_CONSUMER_ID=XXXXXMyIdXXXXX
TWITTER_CONSUMER_SECRET=XXXXXMyTopSecretKeyXXXXX

But I encountered this error:

You have requested a non-existent parameter "twitter_consumer_id".

I tried with %kernel.twitter_consumer_id% , %env.twitter_consumer_id% , %env(TWITTER_CONSUMER_ID)% with no more success.

The last test is returning this error message:

An exception has been thrown during the rendering of a template ("Environment variable not found: "TWITTER_CONSUMER_ID".").

How can I retrieve my ENV variables in a parameter file like hwi_oauth.yaml?

Assort answered 25/8, 2017 at 19:49 Comment(2)
Are you loading the .env with the DotEnv component?Oogenesis
Thanks @Oogenesis ! The public\index.php contains if (!getenv('APP_ENV')) { (new Dotenv())->load(__DIR__.'/../.env'); } and this .env was not loaded. It works now ! But the check is to ensure we don't use .env in production. I don't understand how to use it in dev and still protect my prod... Is it secured to repace the test !getenv('APP_ENV') by this one: in_array(getenv('APP_ENV'), ['dev','test']) ?Assort
O
8

You need to load the .env file during your bootstrap process, in order for those environment variables to be available:

(new DotEnv())->load(__DIR__ . '/../.env');

You should plan to put secret keys in environment variables on development, staging, and production. How you do that depends, though. In development and staging, perhaps you use .env files, while on production you use Apache to inject.

Personally, I always use .env files, and I keep a blank one in my repository. That way it's super simple to deploy, and there aren't any special cases.

If you only want to use .env files in specific environments, you can do:

if (in_array(getenv('APP_ENV'), [ 'dev', 'test' ])) {
    (new DotEnv())->load(__DIR__ . '/../.env');
}
Oogenesis answered 25/8, 2017 at 20:25 Comment(3)
+1 Even though getenv('APP_ENV') will require to set APP_ENV env var in your local dev machine. I'd suggest add the default one too if (!getenv('APP_ENV') || ...).Desiredesirea
Indeed, @yceruto. One having to set an environment variable to load environment variables. O_o Part of the reason I unconditionally use env files.Oogenesis
@Oogenesis it means we need to set an environment variable (APP_ENV) to be able to load the .env file? This is what @Desiredesirea is warning I think :/Ondometer
D
5

For test environments I'd suggest also create a bootstrap.php script to override the .env parameters:

tests/bootstrap.php:

<?php

use Symfony\Component\Dotenv\Dotenv;

require_once __DIR__.'/../vendor/autoload.php';

$dotEnv = new Dotenv();
$dotEnv->load(__DIR__.'/../.env');
$dotEnv->populate([
    'APP_ENV' => 'test',
    'DATABASE_URL' => '...'
    // ...
]);

phpunit.xml.dist:

<?xml version="1.0" encoding="UTF-8"?>

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
         bootstrap="tests/bootstrap.php" <--- set
         ...
>
    ...
</phpunit>
Desiredesirea answered 25/8, 2017 at 21:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.