7
votes

I am trying to make a Symfony bundle. But I am unable to read the ENV vars I use in the config. (They are only loaded as placeholder) I created a config tree, with some values I'd like an application to use with ENV vars.

The applications config file looks like this:

bundle_name:
    config_value: "%env(NAME_OF_ENV_VALUE)%"

My Bundle extension class looks like:

public function load(array $configs, ContainerBuilder $container): void
{
    $loader = new XmlFileLoader(
        $container,
        new FileLocator(__DIR__.'/../Resources/config')
    );

    $configuration = new Configuration();
    $loader->load('services.xml');
    $config = $this->processConfiguration($configuration, $configs);

    print_r($config);
}

The result of the print_r($config) looks like:

 [config_value] => env_NAME_OF_ENV_VALUE_2ae7ade5b0635007828f2e7e6765cd4d

Also, I am getting this exception:

EnvParameterException

Environment variables "ENV_VAR_NAME" are never used. Please, check your container's configuration. in PhpDumper.php (line 271)

Now, my question is

How do I (what turns out to be an ENV placeholder) into the actual value of the ENV var?

Some things I tried

I know there is a ContainerBuilder->compile(true) option, which is supposed to resolve these ENV vars. But I can't figure out where I should put this in my bundle. Everything I tried gives errors.

I also know there is a CompilerPass (Symfony\Component\DependencyInjection\Compiler\ResolveEnvPlaceholdersPass) which (according to the name) is supposed to Resolve the env vars, but this doesn't do anything. I tried adding $container->addCompilerPass(new ResolveEnvPlaceholdersPass()); to my Bundle class' build() method, but nothing happens.

Some additional info

  • I'm using Symfony 4,
  • PHP 7.2
  • Tested this both on Mac OS and Windows 7.
  • The ENV var is loaded correctly. print_r($_ENV) shows this.
2

2 Answers

3
votes

@PavelAlazankin almost had it. Actual evaluations of env values are indeed deferred to later.

To get past the "never used" error message, you need to actually use it someplace. I think it is a protection against typos. The easiest way to to just make a parameter out of it.

public function load(array $configs, ContainerBuilder $container)
{
    print_r($configs);
    // Makes the not used error go away
    $container->setParameter('config_value',$configs[0]['config_value']);
}

In your case it would be something like:

public function load(array $configs, ContainerBuilder $container): void
{
    $loader = new XmlFileLoader(
        $container,
        new FileLocator(__DIR__.'/../Resources/config')
    );

    $configuration = new Configuration();
    $loader->load('services.xml');
    $config = $this->processConfiguration($configuration, $configs);

    $container->setParameter('config_value',$config['config_value']);
1
votes

You debug your application in wrong place. It is normal symfony behavior, some dynamic parameters are lazy loaded from env variables on demand.

To be sure configuration is set up correctly you can get this parameter from container (e.g. in controller or somewhere else):

$configValue = $this->getParameter('bundle_name.config_value');

and dump it with dump() or var_dump() or print_r().

You can try to debug $container->getParameter() method with xDebug to see what's happening behind the scenes inside of auto-generated container class.