Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dotenv] Loading of env variables depends on the php parameter variables_order #45266

Closed
kaznovac opened this issue Feb 1, 2022 · 6 comments
Closed

Comments

@kaznovac
Copy link
Contributor

kaznovac commented Feb 1, 2022

Symfony version(s) affected

^5.4, most possibly others

Description

Loaded env vars are not the same depending on the variables_order parameter setting.

The recommended development/production setting does not load the $_ENV superglobal. see: https://github.com/php/php-src/blob/master/php.ini-production#L636-L647

When the $_ENV is not loaded the actual env variables are not considered and that breaks this stance in configuration documentation

Real environment variables always win over env vars created by any of the .env files.

Possible cause for the issue is this change (it removed the call to getenv) f76e420#diff-2585c97d75081932a10834cb311d918012a7e0588d28ebd5216c8591b15d15aeL73

How to reproduce

  • run any symfony project using .env file and few of those env vars in console
  • try php configured with variables_order = "GPCS" and variables_order = "EGPCS"
  • observe the variables in the profiler's 'server parameters'
  • compare with expected (the env vars in console should take precedence)

Possible Solution

utilize getenv to load the variable, investigate other solutions for the rootcause of #23502

Additional Context

No response

@nicolas-grekas
Copy link
Member

If which SAPI does this happen?
When using php -S this is a known issue: env vars aren't populated in $_SERVER. All other SAPIs do add to $_SERVER, so that they should not be affected.
A workaround would be to execute $_SERVER += getenv(); before using Dotenv when 'cli-server' === PHP_SAPI.
The better alternative is to use the symfony binary instead of php -S
That's not something we can fix in Dotenv.

@nicolas-grekas
Copy link
Member

We could fix that in symfony/runtime maybe.

@kaznovac
Copy link
Contributor Author

kaznovac commented Feb 1, 2022

haven't used php -S built-in web server.

PHP_SAPI is, depending on context, either apache2handler, cli

I've built a docker image based on official php 8.1-apache
with recommended php.ini-production configuration (i.e. RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini)

With the variables_order = "GPCS" the $_SERVER is loaded as expected (with the correct value for env vars), and the $_ENV is [] so in the Dotenv::populate the check will fail in line ($_ENV is empty)

if (!isset($loadedVars[$name]) && !$overrideExistingVars && isset($_ENV[$name])) {

and the correct env variable value will be, later in the same method, overwritten with the value read in from the .env.local.php at lines
$_ENV[$name] = $value;
if ($notHttpName) {
$_SERVER[$name] = $value;
}

This is the commit that removed the $_SERVER check 08291b1

edit
The same commit also copied the vars from $_SERVER to $_ENV... so this should work :|

if (isset($_SERVER[$name]) && $notHttpName && !isset($_ENV[$name])) {
$_ENV[$name] = $_SERVER[$name];
}

@nicolas-grekas
Copy link
Member

The same commit also copied the vars from $_SERVER to $_ENV... so this should work :|

that's what I would say also... so it's something else I guess

@nicolas-grekas
Copy link
Member

Closing for now, please report back when you have more info.

@annuh
Copy link

annuh commented Feb 27, 2023

Thanks for the hint about variables_order.

I was having issues after enabling the php.ini-production. Real environment variables were not resolved correctly:

I was using the following environment variable: MYSQL_HOST=external.host (configured via AWS ECS) and the following configs:

# .env
MYSQL_HOST=localhost
# packages/doctrine.yaml
doctrine:
    dbal:
        host: '%env(resolve:MYSQL_HOST)%'

Our application tried to connect to localhost, instead of external.host.
This was fixed after adding variables_order = "EGPCS" to our php.ini (which is loaded after php.ini-production)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants