8000 bug #32943 [Dotenv] search variable values in ENV first then env file… · symfony/symfony@fefb2ff · GitHub
[go: up one dir, main page]

Skip to content

Commit fefb2ff

Browse files
bug #3 8000 2943 [Dotenv] search variable values in ENV first then env file (soufianZantar)
This PR was merged into the 3.4 branch. Discussion ---------- [Dotenv] search variable values in ENV first then env file | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | BC breaks? | no <!-- see https://symfony.com/bc --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | #32595 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> <!-- Replace this notice by a short README for your feature/bugfix. This will help people understand your PR and can be used as a start for the documentation. Additionally (see https://symfony.com/roadmap): - Bug fixes must be submitted against the lowest maintained branch where they apply (lowest branches are regularly merged to upper ones so they get the fixes too). - Features and deprecations must be submitted against branch 4.4. - Legacy code removals go to the master branch. --> I think we must searhing the value of variables in $_ENV before the .env file to fix this issues. before this fix Parse method will return the value in .env file and not the value passed in this command `composer dump-env prod `. **the issue:** In my .env file, I have a variable TEST that depends on the APP_ENV variable like this: ``` # .env file ###> symfony/framework-bundle ### APP_ENV=dev APP_SECRET=2eb810c79fba0dd5c029a2fa53bfdb51 ###< symfony/framework-bundle ### TEST=foo_${APP_ENV} ``` I run composer dump-env dev command to generate my .env.locale.php, everything works fine, the value of my variable TEST is correct. ``` // .env.locale.php return array ( 'APP_ENV' => 'dev', 'TEST' => 'foo_dev', 'APP_SECRET' => '2eb810c79fba0dd5c029a2fa53bfdb51', ); ``` Then I run the same command with prod environment (composer dump-env prod), the value of TEST is wrong (it is same as for dev) ``` // .env.locale.php return array ( 'APP_ENV' => 'prod', 'TEST' => 'foo_dev', 'APP_SECRET' => '2eb810c79fba0dd5c029a2fa53bfdb51', ); ``` Commits ------- 3018041 [Dotenv] search variable values in ENV first then env file
2 parents 49ad46e + 3018041 commit fefb2ff

File tree

3 files changed

+43
-14
lines changed

3 files changed

+43
-14
lines changed

src/Symfony/Component/Dotenv/Dotenv.php

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ private function lexValue()
183183
throw $this->createFormatException('Whitespace are not supported before the value');
184184
}
185185

186+
$loadedVars = array_flip(explode(',', isset($_SERVER['SYMFONY_DOTENV_VARS']) ? $_SERVER['SYMFONY_DOTENV_VARS'] : (isset($_ENV['SYMFONY_DOTENV_VARS']) ? $_ENV['SYMFONY_DOTENV_VARS'] : '')));
187+
unset($loadedVars['']);
186188
$v = '';
187189

188190
do {
@@ -224,8 +226,8 @@ private function lexValue()
224226
++$this->cursor;
225227
$value = str_replace(['\\"', '\r', '\n'], ['"', "\r", "\n"], $value);
226228
$resolvedValue = $value;
227-
$resolvedValue = $this->resolveVariables($resolvedValue);
228-
$resolvedValue = $this->resolveCommands($resolvedValue);
229+
$resolvedValue = $this->resolveVariables($resolvedValue, $loadedVars);
230+
$resolvedValue = $this->resolveCommands($resolvedValue, $loadedVars);
229231
$resolvedValue = str_replace('\\\\', '\\', $resolvedValue);
230232
$v .= $resolvedValue;
231233
} else {
@@ -247,8 +249,8 @@ private function lexValue()
247249
}
248250
$value = rtrim($value);
249251
$resolvedValue = $value;
250-
$resolvedValue = $this->resolveVariables($resolvedValue);
251-
$resolvedValue = $this->resolveCommands($resolvedValue);
252+
$resolvedValue = $this->resolveVariables($resolvedValue, $loadedVars);
253+
$resolvedValue = $this->resolveCommands($resolvedValue, $loadedVars);
252254
$resolvedValue = str_replace('\\\\', '\\', $resolvedValue);
253255

254256
if ($resolvedValue === $value && preg_match('/\s+/', $value)) {
@@ -301,7 +303,7 @@ private function skipEmptyLines()
301303
}
302304
}
303305

304-
private function resolveCommands($value)
306+
private function resolveCommands($value, $loadedVars)
305307
{
306308
if (false === strpos($value, '$')) {
307309
return $value;
@@ -317,7 +319,7 @@ private function resolveCommands($value)
317319
)
318320
/x';
319321

320-
return preg_replace_callback($regex, function ($matches) {
322+
return preg_replace_callback($regex, function ($matches) use ($loadedVars) {
321323
if ('\\' === $matches[1]) {
322324
return substr($matches[0], 1);
323325
}
@@ -332,7 +334,15 @@ private function resolveCommands($value)
332334

333335
$process = new Process('echo '.$matches[0]);
334336
$process->inheritEnvironmentVariables(true);
335-
$process->setEnv($this->values);
337+
338+
$env = [];
339+
foreach ($this->values as $name => $value) {
340+
if (isset($loadedVars[$name]) || (!isset($_ENV[$name]) && !(isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')))) {
341+
$env[$name] = $value;
342+
}
343+
}
344+
$process->setEnv($env);
345+
336346
try {
337347
$process->mustRun();
338348
} catch (ProcessException $e) {
@@ -343,7 +353,7 @@ private function resolveCommands($value)
343353
}, $value);
344354
}
345355

346-
private function resolveVariables($value)
356+
private function resolveVariables($value, array $loadedVars)
347357
{
348358
if (false === strpos($value, '$')) {
349359
return $value;
@@ -359,7 +369,7 @@ private function resolveVariables($value)
359369
(?P<closing_brace>\})? # optional closing brace
360370
/x';
361371

362-
$value = preg_replace_callback($regex, function ($matches) {
372+
$value = preg_replace_callback($regex, function ($matches) use ($loadedVars) {
363373
// odd number of backslashes means the $ character is escaped
364374
if (1 === \strlen($matches['backslashes']) % 2) {
365375
return substr($matches[0], 1);
@@ -375,14 +385,16 @@ private function resolveVariables($value)
375385
}
376386

377387
$name = $matches['name'];
378-
if (isset($this->values[$name])) {
388+
if (isset($loadedVars[$name]) && isset($this->values[$name])) {
379389
$value = $this->values[$name];
380-
} elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) {
381-
$value = $_SERVER[$name];
382390
} elseif (isset($_ENV[$name])) {
383391
$value = $_ENV[$name];
392+
} elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) {
393+
$value = $_SERVER[$name];
394+
} elseif (isset($this->values[$name])) {
395+
$value = $this->values[$name];
384396
} else {
385-
$value = (string) getenv($name);
397+
$value = '';
386398
}
387399

388400
if (!$matches['opening_brace'] && isset($matches['closing_brace'])) {

src/Symfony/Component/Dotenv/Tests/DotenvTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public function testParse($data, $expected)
6363
public function getEnvData()
6464
{
6565
putenv('LOCAL=local');
66+
$_ENV['LOCAL'] = 'local';
6667
$_ENV['REMOTE'] = 'remote';
6768

6869
$tests = [
@@ -295,4 +296,20 @@ public function testOverridingEnvVarsWithNamesMemorizedInSpecialVar()
295296
$this->assertSame('baz1', getenv('BAZ'));
296297
$this->assertSame('/var/www', getenv('DOCUMENT_ROOT'));
297298
}
299+
300+
public function testGetVariablesValueFromEnvFirst()
301+
{
302+
$_ENV['APP_ENV'] = 'prod';
303+
$dotenv = new Dotenv(true);
304+
305+
$test = "APP_ENV=dev\nTEST1=foo1_\${APP_ENV}";
306+
$values = $dotenv->parse($test);
307+
$this->assertSame('foo1_prod', $values['TEST1']);
308+
309+
if ('\\' !== \DIRECTORY_SEPARATOR) {
310+
$test = "APP_ENV=dev\nTEST2=foo2_\$(php -r 'echo \$_SERVER[\"APP_ENV\"];')";
311+
$values = $dotenv->parse($test);
312+
$this->assertSame('foo2_prod', $values['TEST2']);
313+
}
314+
}
298315
}

src/Symfony/Component/Dotenv/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"php": "^5.5.9|>=7.0.8"
2020
},
2121
"require-dev": {
22-
"symfony/process": "~3.2|~4.0"
22+
"symfony/process": "^3.4.2|^4.0"
2323
},
2424
"autoload": {
2525
"psr-4": { "Symfony\\Component\\Dotenv\\": "" },

0 commit comments

Comments
 (0)
0