-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Dotenv][WebServerBundle] Override previously loaded variables #23799
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][WebServerBundle] Override previously loaded variables #23799
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost good, just this missing:
--- a/src/Symfony/Bundle/WebServerBundle/WebServer.php
+++ b/src/Symfony/Bundle/WebServerBundle/WebServer.php
@@ -154,6 +154,11 @@ class WebServer
$process->setWorkingDirectory($config->getDocumentRoot());
$process->setTimeout(null);
+ if (in_array('APP_ENV', explode(',', getenv('SYMFONY_DOTENV_VARS')))) {
+ $process->setEnv(array('APP_ENV' => false));
+ $process->inheritEnvironmentVariables();
+ }
+
return $process;
}
* @param array $values An array of env variables | ||
*/ | ||
public function populate($values) | ||
{ | ||
$loadedVars = getenv('SYMFONY_DOTENV_VARS') ? explode(',', getenv('SYMFONY_DOTENV_VARS')) : array(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
array_flip(explode(',', getenv('SYMFONY_DOTENV_VARS')))
(no need for the check, the resulting array is good enough)
foreach ($values as $name => $value) { | ||
if (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name)) { | ||
if (!in_array($name, $loadedVars) && (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isset($loadedVars[$name]) || ...
continue; | ||
} | ||
|
||
putenv("$name=$value"); | ||
$_ENV[$name] = $value; | ||
$_SERVER[$name] = $value; | ||
|
||
$loadedVars[] = $name; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$loadedVars[$name] = true;
} | ||
|
||
$loadedVars = implode(',', $loadedVars); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (1 < count($loadedVars)) { ... }
("1" because of the empty string - or we should remove it before)
@nicolas-grekas, Thanks for the code review! I've fixed all issues you pointed out. |
It should be merged in 3.4 to me, even maybe in 3.3 as bug fix? |
@nicolas-grekas, It introduces a BC break: // This code will work differently for a current version and the new one:
(new Dotenv())->populate([ 'FOO' => 'foo', 'FOO' => 'bar' ]);
// Current version echoes: "foo", new version echoes "bar"
echo getenv('FOO'); IMHO, we don't need this feature in the Symfony 3.x because it doesn't use the Dotenv component. |
Not sure to get your example, you can't define an array with two identical keys. |
@nicolas-grekas, Sorry, example should be: (new Dotenv())->populate([ 'FOO' => 'foo' ]);
(new Dotenv())->populate([ 'FOO' => 'bar' ]);
echo getenv('FOO'); |
Ok :) |
@nicolas-grekas, Ok, I've changed the base branch to 3.3. |
} | ||
|
||
$loadedVars = implode(',', array_keys($loadedVars)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this block of 4 lines should be inside an if ($loadedVars) {...}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nicolas-grekas, I think you're right. I've moved that block inside an if
statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3.3 LGTM
@@ -60,20 +60,32 @@ public function load($path/*, ...$paths*/) | |||
/** | |||
* Sets values as environment variables (via putenv, $_ENV, and $_SERVER). | |||
* | |||
* Note that existing environment variables are never overridden. | |||
* Existing environment variables are never overridden, unless they are listed in the SYMFONY_DOTENV_VARS env var. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not document this feature as this is really just a hack to make the internal PHP web server work. Not a feature we want to promote.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fabpot, Ok, I've removed that comment.
Thank you @voronkovich. |
…bles (voronkovich) This PR was squashed before being merged into the 3.3 branch (closes #23799). Discussion ---------- [Dotenv][WebServerBundle] Override previously loaded variables | Q | A | ------------- | --- | Branch? | 3.3 | Bug fix? | yes | New feature? | no | BC breaks? | yes | Deprecations? | no | Tests pass? | yes | Fixed tickets | #23723 | License | MIT This PR implements @nicolas-grekas's idea about how we could refresh loaded environment variables. See his comment #23723 (comment) Commits ------- c5a1218 [Dotenv][WebServerBundle] Override previously loaded variables
guys, i am grateful for all your hard work, but this change is a breaking change and it is not mentioned :( |
to give you more info why it is a BC, please see our <?php
/** @var \Composer\Autoload\ClassLoader $loader */
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\Dotenv\Exception\PathException;
$loader = require __DIR__ . '/autoload.php';
$dotenv = new Dotenv;
try {
// existing environment variables are never overridden
$dotenv->load(__DIR__ . '/config/.env');
} catch (PathException $e) {
}
// existing environment variables are never overridden
$dotenv->load(__DIR__ . '/config/.env.dist');
return $loader; |
@tiger-seo Please open a dedicated issue so that we can look at possible alternatives. Comments on closed PR/issues are lost. |
@tiger-seo, I think you could try to load the // existing environment variables are never overridden
$dotenv->load(__DIR__ . '/config/.env.dist');
try {
// existing environment variables are never overridden
$dotenv->load(__DIR__ . '/config/.env');
} catch (PathException $e) {
}
return $loader; |
@voronkovich yes, this is exactly how we've fixed it, but we spent at least 5 man-hours of our team to find(debug) and fix the issue. Symfony promises seamless upgrade for minor releases, but not this time. |
Sorry, @tiger-seo! We thought that the BC break is so small, so nobody would notice it :) |
This PR implements @nicolas-grekas's idea about how we could refresh loaded environment variables. See his comment #23723 (comment)