Skip to content

Commit

Permalink
bug #23799 [Dotenv][WebServerBundle] Override previously loaded varia…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
fabpot committed Aug 22, 2017
2 parents e6d0368 + c5a1218 commit 2204f91
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/Symfony/Bundle/WebServerBundle/WebServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ private function createServerProcess(WebServerConfig $config)
$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;
}

Expand Down
16 changes: 14 additions & 2 deletions src/Symfony/Component/Dotenv/Dotenv.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* Note that existing environment variables are not overridden.
*
* @param array $values An array of env variables
*/
public function populate($values)
{
$loadedVars = array_flip(explode(',', getenv('SYMFONY_DOTENV_VARS')));
unset($loadedVars['']);

foreach ($values as $name => $value) {
if (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name)) {
if (!isset($loadedVars[$name]) && (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name))) {
continue;
}

putenv("$name=$value");
$_ENV[$name] = $value;
$_SERVER[$name] = $value;

$loadedVars[$name] = true;
}

if ($loadedVars) {
$loadedVars = implode(',', array_keys($loadedVars));
putenv("SYMFONY_DOTENV_VARS=$loadedVars");
$_ENV['SYMFONY_DOTENV_VARS'] = $loadedVars;
$_SERVER['SYMFONY_DOTENV_VARS'] = $loadedVars;
}
}

Expand Down
56 changes: 56 additions & 0 deletions src/Symfony/Component/Dotenv/Tests/DotenvTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,60 @@ public function testEnvVarIsNotOverriden()

$this->assertSame('original_value', getenv('TEST_ENV_VAR'));
}

public function testMemorizingLoadedVarsNamesInSpecialVar()
{
// Special variable not exists
unset($_ENV['SYMFONY_DOTENV_VARS']);
unset($_SERVER['SYMFONY_DOTENV_VARS']);
putenv('SYMFONY_DOTENV_VARS');

unset($_ENV['APP_DEBUG']);
unset($_SERVER['APP_DEBUG']);
putenv('APP_DEBUG');
unset($_ENV['DATABASE_URL']);
unset($_SERVER['DATABASE_URL']);
putenv('DATABASE_URL');

$dotenv = new DotEnv();
$dotenv->populate(array('APP_DEBUG' => '1', 'DATABASE_URL' => 'mysql://root@localhost/db'));

$this->assertSame('APP_DEBUG,DATABASE_URL', getenv('SYMFONY_DOTENV_VARS'));

// Special variable has a value
$_ENV['SYMFONY_DOTENV_VARS'] = 'APP_ENV';
$_SERVER['SYMFONY_DOTENV_VARS'] = 'APP_ENV';
putenv('SYMFONY_DOTENV_VARS=APP_ENV');

$_ENV['APP_DEBUG'] = '1';
$_SERVER['APP_DEBUG'] = '1';
putenv('APP_DEBUG=1');
unset($_ENV['DATABASE_URL']);
unset($_SERVER['DATABASE_URL']);
putenv('DATABASE_URL');

$dotenv = new DotEnv();
$dotenv->populate(array('APP_DEBUG' => '0', 'DATABASE_URL' => 'mysql://root@localhost/db'));
$dotenv->populate(array('DATABASE_URL' => 'sqlite:///somedb.sqlite'));

$this->assertSame('APP_ENV,DATABASE_URL', getenv('SYMFONY_DOTENV_VARS'));
}

public function testOverridingEnvVarsWithNamesMemorizedInSpecialVar()
{
putenv('SYMFONY_DOTENV_VARS=FOO,BAR,BAZ');

putenv('FOO=foo');
putenv('BAR=bar');
putenv('BAZ=baz');
putenv('DOCUMENT_ROOT=/var/www');

$dotenv = new DotEnv();
$dotenv->populate(array('FOO' => 'foo1', 'BAR' => 'bar1', 'BAZ' => 'baz1', 'DOCUMENT_ROOT' => '/boot'));

$this->assertSame('foo1', getenv('FOO'));
$this->assertSame('bar1', getenv('BAR'));
$this->assertSame('baz1', getenv('BAZ'));
$this->assertSame('/var/www', getenv('DOCUMENT_ROOT'));
}
}

0 comments on commit 2204f91

Please sign in to comment.