8000 [Dotenv] Add $overrideExistingVars to bootEnv() and loadEnv() · symfony/symfony@f26a730 · GitHub
[go: up one dir, main page]

Skip to content

Commit f26a730

Browse files
committed
[Dotenv] Add $overrideExistingVars to bootEnv() and loadEnv()
1 parent c507235 commit f26a730

File tree

3 files changed

+89
-19
lines changed

3 files changed

+89
-19
lines changed

src/Symfony/Component/Dotenv/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Add `dotenv:dump` command to compile the contents of the .env files into a PHP-optimized file called `.env.local.php`
88
* Add `debug:dotenv` command to list all dotenv files with variables and values
9+
* Add `$overrideExistingVars` on `Dotenv::bootEnv()` and `Dotenv::loadEnv()`
910

1011
5.1.0
1112
-----

src/Symfony/Component/Dotenv/Dotenv.php

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,22 +106,22 @@ public function load(string $path, string ...$extraPaths): void
106106
* @throws FormatException when a file has a syntax error
107107
* @throws PathException when a file does not exist or is not readable
108108
*/
109-
public function loadEnv(string $path, string $envKey = null, string $defaultEnv = 'dev', array $testEnvs = ['test']): void
109+
public function loadEnv(string $path, string $envKey = null, string $defaultEnv = 'dev', array $testEnvs = ['test'], bool $overrideExistingVars = false): void
110110
{
111111
$k = $envKey ?? $this->envKey;
112112

113113
if (is_file($path) || !is_file($p = "$path.dist")) {
114-
$this->load($path);
114+
$this->doLoad($overrideExistingVars, [$path]);
115115
} else {
116-
$this->load($p);
116+
$this->doLoad($overrideExistingVars, [$p]);
117117
}
118118

119119
if (null === $env = $_SERVER[$k] ?? $_ENV[$k] ?? null) {
120-
$this->populate([$k => $env = $defaultEnv]);
120+
$this->populate([$k => $env = $defaultEnv], $overrideExistingVars);
121121
}
122122

123123
if (!\in_array($env, $testEnvs, true) && is_file($p = "$path.local")) {
124-
$this->load($p);
124+
$this->doLoad($overrideExistingVars, [$p]);
125125
$env = $_SERVER[$k] ?? $_ENV[$k] ?? $env;
126126
}
127127

@@ -130,11 +130,11 @@ public function loadEnv(string $path, string $envKey = null, string $defaultEnv
130130
}
131131

132132
if (is_file($p = "$path.$env")) {
133-
$this->load($p);
133+
$this->doLoad($overrideExistingVars, [$p]);
134134
}
135135

136136
if (is_file($p = "$path.$env.local")) {
137-
$this->load($p);
137+
$this->doLoad($overrideExistingVars, [$p]);
138138
}
139139
}
140140

@@ -145,16 +145,16 @@ public function loadEnv(string $path, string $envKey = null, string $defaultEnv
145145
*
146146
* See method loadEnv() for rules related to .env files.
147147
*/
148-
public function bootEnv(string $path, string $defaultEnv = 'dev', array $testEnvs = ['test']): void
148+
public function bootEnv(string $path, string $defaultEnv = 'dev', array $testEnvs = ['test'], bool $overrideExistingVars = false): void
149149
{
150150
$p = $path.'.local.php';
151151
$env = is_file($p) ? include $p : null;
152152
$k = $this->envKey;
153153

154154
if (\is_array($env) && (!isset($env[$k]) || ($_SERVER[$k] ?? $_ENV[$k] ?? $env[$k]) === $env[$k])) {
155-
$this->populate($env);
155+
$this->populate($env, $overrideExistingVars);
156156
} else {
157-
$this->loadEnv($path, $k, $defaultEnv, $testEnvs);
157+
$this->loadEnv($path, $k, $defaultEnv, $testEnvs, $overrideExistingVars);
158158
}
159159

160160
$_SERVER += $_ENV;
@@ -227,8 +227,6 @@ public function populate(array $values, bool $overrideExistingVars = false): voi
227227
* @param string $data The data to be parsed
228228
* @param string $path The original file name where data where stored (used for more meaningful error messages)
229229
*
230-
* @return array
231-
*
232230
* @throws FormatException when a file has a syntax error
233231
*/
234232
public function parse(string $data, string $path = '.env'): array

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

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -236,61 +236,117 @@ public function testLoadEnv()
236236
putenv('SYMFONY_DOTENV_VARS');
237237
putenv('FOO');
238238
putenv('TEST_APP_ENV');
239+
240+
$_ENV['EXISTING_KEY'] = $_SERVER['EXISTING_KEY'] = 'EXISTING_VALUE';
241+
putenv('EXISTING_KEY=EXISTING_VALUE');
239242
};
240243

241244
@mkdir($tmpdir = sys_get_temp_dir().'/dotenv');
242245

243246
$path = tempnam($tmpdir, 'sf-');
244247

245248
// .env
246-
file_put_contents($path, 'FOO=BAR');
249+
file_put_contents($path, "FOO=BAR\nEXISTING_KEY=NEW_VALUE");
247250

248251
$resetContext();
249252
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
250253
$this->assertSame('BAR', getenv('FOO'));
251254
$this->assertSame('dev', getenv('TEST_APP_ENV'));
255+
$this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
256+
$this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
257+
258+
$resetContext();
259+
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
260+
$this->assertSame('BAR', getenv('FOO'));
261+
$this->assertSame('dev', getenv('TEST_APP_ENV'));
262+
$this->assertSame('NEW_VALUE', getenv('EXISTING_KEY'));
263+
$this->assertSame('NEW_VALUE', $_ENV['EXISTING_KEY']);
252264

253265
// .env.local
254-
file_put_contents("$path.local", 'FOO=localBAR');
266+
file_put_contents("$path.local", "FOO=localBAR\nEXISTING_KEY=localNEW_VALUE");
255267

256268
$resetContext();
257269
$_SERVER['TEST_APP_ENV'] = 'local';
258270
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
259271
$this->assertSame('localBAR', getenv('FOO'));
272+
$this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
273+
$this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
274+
275+
$resetContext();
276+
$_SERVER['TEST_APP_ENV'] = 'local';
277+
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
278+
$this->assertSame('localBAR', getenv('FOO'));
279+
$this->assertSame('localNEW_VALUE', getenv('EXISTING_KEY'));
280+
$this->assertSame('localNEW_VALUE', $_ENV['EXISTING_KEY']);
260281

261282
// special case for test
262283
$resetContext();
263284
$_SERVER['TEST_APP_ENV'] = 'test';
264285
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
265286
$this->assertSame('BAR', getenv('FOO'));
287+
$this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
288+
$this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
289+
290+
$resetContext();
291+
$_SERVER['TEST_APP_ENV'] = 'test';
292+
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
293+
$this->assertSame('BAR', getenv('FOO'));
294+
$this->assertSame('NEW_VALUE', getenv('EXISTING_KEY'));
295+
$this->assertSame('NEW_VALUE', $_ENV['EXISTING_KEY']);
266296

267297
// .env.dev
268-
file_put_contents("$path.dev", 'FOO=devBAR');
298+
file_put_contents("$path.dev", "FOO=devBAR\nEXISTING_KEY=devNEW_VALUE");
269299

270300
$resetContext();
271301
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
272302
$this->assertSame('devBAR', getenv('FOO'));
303+
$this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
304+
$this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
305+
306+
$resetContext();
307+
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
308+
$this->assertSame('devBAR', getenv('FOO'));
309+
$this->assertSame('devNEW_VALUE', getenv('EXISTING_KEY'));
310+
$this->assertSame('devNEW_VALUE', $_ENV['EXISTING_KEY']);
273311

274312
// .env.dev.local
275-
file_put_contents("$path.dev.local", 'FOO=devlocalBAR');
313+
file_put_contents("$path.dev.local", "FOO=devlocalBAR\nEXISTING_KEY=devlocalNEW_VALUE");
276314

277315
$resetContext();
278316
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
279317
$this->assertSame('devlocalBAR', getenv('FOO'));
318+
$this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
319+
$this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
320+
321+
$resetContext();
322+
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
323+
$this->assertSame('devlocalBAR', getenv('FOO'));
324+
$this->assertSame('devlocalNEW_VALUE', getenv('EXISTING_KEY'));
325+
$this->assertSame('devlocalNEW_VALUE', $_ENV['EXISTING_KEY']);
280326
unlink("$path.local");
281327
unlink("$path.dev");
282328
unlink("$path.dev.local");
283329

284330
// .env.dist
285-
file_put_contents("$path.dist", 'FOO=distBAR');
331+
file_put_contents("$path.dist", "FOO=distBAR\nEXISTING_KEY=distNEW_VALUE");
286332

287333
$resetContext();
288334
unlink($path);
289335
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV');
290336
$this->assertSame('distBAR', getenv('FOO'));
337+
$this->assertSame('EXISTING_VALUE', getenv('EXISTING_KEY'));
338+
$this->assertSame('EXISTING_VALUE', $_ENV['EXISTING_KEY']);
339+
340+
$resetContext();
341+
(new Dotenv())->usePutenv()->loadEnv($path, 'TEST_APP_ENV', 'dev', ['test'], true);
342+
$this->assertSame('distBAR', getenv('FOO'));
343+
$this->assertSame('distNEW_VALUE', getenv('EXISTING_KEY'));
344+
$this->assertSame('distNEW_VALUE', $_ENV['EXISTING_KEY']);
291345
unlink("$path.dist");
292346

293347
$resetContext();
348+
unset($_ENV['EXISTING_KEY'], $_SERVER['EXISTING_KEY']);
349+
putenv('EXISTING_KEY');
294350
rmdir($tmpdir);
295351
}
296352

@@ -490,22 +546,37 @@ public function testBootEnv()
490546
unset($_SERVER['TEST_APP_ENV'], $_ENV['TEST_APP_ENV']);
491547
unset($_SERVER['TEST_APP_DEBUG'], $_ENV['TEST_APP_DEBUG']);
492548
unset($_SERVER['FOO'], $_ENV['FOO']);
549+
550+
$_ENV['EXISTING_KEY'] = $_SERVER['EXISTING_KEY'] = 'EXISTING_VALUE';
493551
};
494552

495553
@mkdir($tmpdir = sys_get_temp_dir().'/dotenv');
496554
$path = tempnam($tmpdir, 'sf-');
497555

498-
file_put_contents($path, 'FOO=BAR');
556+
file_put_contents($path, "FOO=BAR\nEXISTING_KEY=NEW_VALUE");
499557
$resetContext();
500558
(new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path);
501559
$this->assertSame('BAR', $_SERVER['FOO']);
560+
$this->assertSame('EXISTING_VALUE', $_SERVER['EXISTING_KEY']);
561+
562+
$resetContext();
563+
(new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path, 'dev', ['test'], true);
564+
$this->assertSame('BAR', $_SERVER['FOO']);
565+
$this->assertSame('NEW_VALUE', $_SERVER['EXISTING_KEY']);
502566
unlink($path);
503567

504-
file_put_contents($path.'.local.php', '<?php return ["TEST_APP_ENV" => "dev", "FOO" => "BAR"];');
568+
file_put_contents($path.'.local.php', '<?php return ["TEST_APP_ENV" => "dev", "FOO" => "BAR", "EXISTING_KEY" => "localphpNEW_VALUE"];');
505569
$resetContext();
506570
(new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path);
507571
$this->assertSame('BAR', $_SERVER['FOO']);
508572
$this->assertSame('1', $_SERVER['TEST_APP_DEBUG']);
573+
$this->assertSame('EXISTING_VALUE', $_SERVER['EXISTING_KEY']);
574+
575+
$resetContext();
576+
(new Dotenv('TEST_APP_ENV', 'TEST_APP_DEBUG'))->bootEnv($path, 'dev', ['test'], true);
577+
$this->assertSame('BAR', $_SERVER['FOO']);
578+
$this->assertSame('1', $_SERVER['TEST_APP_DEBUG']);
579+
$this->assertSame('localphpNEW_VALUE', $_SERVER['EXISTING_KEY']);
509580
unlink($path.'.local.php');
510581

511582
$resetContext();

0 commit comments

Comments
 (0)
0