From eb0749b102f5e5de7777a9fd0d6964f13beef951 Mon Sep 17 00:00:00 2001 From: Oleg Voronkovich Date: Sun, 30 Jul 2017 18:08:10 +0300 Subject: [PATCH 1/2] Add support for overriding existing envs --- src/Symfony/Component/Dotenv/CHANGELOG.md | 5 +++++ src/Symfony/Component/Dotenv/Dotenv.php | 16 +++++++++++++--- .../Component/Dotenv/Tests/DotenvTest.php | 10 ++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Dotenv/CHANGELOG.md b/src/Symfony/Component/Dotenv/CHANGELOG.md index 2204282c26ca6..3af8c85639b34 100644 --- a/src/Symfony/Component/Dotenv/CHANGELOG.md +++ b/src/Symfony/Component/Dotenv/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +3.4.0 +----- + + * added support for overriding existing envs + 3.3.0 ----- diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index 2e907b8c980b8..c58a9c5aec7c4 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -36,6 +36,18 @@ final class Dotenv private $state; private $values; + private $overrideExistingVars; + + /** + * Constructor. + * + * @param bool $overrideExistingVars Override existing environment variables + */ + public function __construct($overrideExistingVars = false) + { + $this->overrideExistingVars = $overrideExistingVars; + } + /** * Loads one or several .env files. * @@ -60,14 +72,12 @@ public function load($path/*, ...$paths*/) /** * Sets values as environment variables (via putenv, $_ENV, and $_SERVER). * - * Note that existing environment variables are never overridden. - * * @param array $values An array of env variables */ public function populate($values) { foreach ($values as $name => $value) { - if (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name)) { + if (!$this->overrideExistingVars && (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name))) { continue; } diff --git a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php index 47598030a87f1..e7b6f248c40e7 100644 --- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php +++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php @@ -214,4 +214,14 @@ public function testEnvVarIsNotOverriden() $this->assertSame('original_value', getenv('TEST_ENV_VAR')); } + + public function testOverrideEnvVar() + { + putenv('TEST_ENV_VAR=original_value'); + + $dotenv = new DotEnv(true); + $dotenv->populate(array('TEST_ENV_VAR' => 'new_value')); + + $this->assertSame('new_value', getenv('TEST_ENV_VAR')); + } } From bf3264697b941aff330c64e6cf3f9d97beda3f94 Mon Sep 17 00:00:00 2001 From: Oleg Voronkovich Date: Mon, 31 Jul 2017 14:59:56 +0300 Subject: [PATCH 2/2] Add a dedicated method to override existing envs --- src/Symfony/Component/Dotenv/Dotenv.php | 45 +++++++++++-------- .../Component/Dotenv/Tests/DotenvTest.php | 36 ++++++++++++++- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index c58a9c5aec7c4..acd3199e50144 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -36,20 +36,23 @@ final class Dotenv private $state; private $values; - private $overrideExistingVars; - /** - * Constructor. + * Loads one or several .env files. + * + * @param string $path A file to load + * @param ...string $paths A list of additional files to load * - * @param bool $overrideExistingVars Override existing environment variables + * @throws FormatException when a file has a syntax error + * @throws PathException when a file does not exist or is not readable */ - public function __construct($overrideExistingVars = false) + public function load($path/*, ...$paths*/) { - $this->overrideExistingVars = $overrideExistingVars; + // func_get_args() to be replaced by a variadic argument for Symfony 4.0 + $this->doLoad(func_get_args(), false); } /** - * Loads one or several .env files. + * Loads one or several .env files with overriding existing vars. * * @param string $path A file to load * @param ...string $paths A list of additional files to load @@ -57,27 +60,22 @@ public function __construct($overrideExistingVars = false) * @throws FormatException when a file has a syntax error * @throws PathException when a file does not exist or is not readable */ - public function load($path/*, ...$paths*/) + public function overload($path/*, ...$paths*/) { // func_get_args() to be replaced by a variadic argument for Symfony 4.0 - foreach (func_get_args() as $path) { - if (!is_readable($path) || is_dir($path)) { - throw new PathException($path); - } - - $this->populate($this->parse(file_get_contents($path), $path)); - } + $this->doLoad(func_get_args(), true); } /** * Sets values as environment variables (via putenv, $_ENV, and $_SERVER). * - * @param array $values An array of env variables + * @param array $values An array of env variables + * @param bool $overrideExistingVars Override the existing env variables */ - public function populate($values) + public function populate($values, $overrideExistingVars = false) { foreach ($values as $name => $value) { - if (!$this->overrideExistingVars && (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name))) { + if (!$overrideExistingVars && (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name))) { continue; } @@ -384,4 +382,15 @@ private function createFormatException($message) { return new FormatException($message, new FormatExceptionContext($this->data, $this->path, $this->lineno, $this->cursor)); } + + private function doLoad(array $paths, $overrideExistingVars = false) + { + foreach ($paths as $path) { + if (!is_readable($path) || is_dir($path)) { + throw new PathException($path); + } + + $this->populate($this->parse(file_get_contents($path), $path), $overrideExistingVars); + } + } } diff --git a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php index e7b6f248c40e7..b65aa73ce2a3e 100644 --- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php +++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php @@ -186,6 +186,38 @@ public function testLoad() $this->assertSame('BAZ', $bar); } + public function testOverload() + { + unset($_ENV['FOO']); + unset($_SERVER['FOO']); + putenv('FOO'); + $_ENV['BAR'] = 'BAR'; + $_SERVER['BAR'] = 'BAR'; + putenv('BAR=BAR'); + + @mkdir($tmpdir = sys_get_temp_dir().'/dotenv'); + + $path1 = tempnam($tmpdir, 'sf-'); + $path2 = tempnam($tmpdir, 'sf-'); + + file_put_contents($path1, 'FOO=FOO'); + file_put_contents($path2, 'BAR=BAZ'); + + (new DotEnv())->overload($path1, $path2); + + $foo = getenv('FOO'); + $bar = getenv('BAR'); + + putenv('FOO'); + putenv('BAR'); + unlink($path1); + unlink($path2); + rmdir($tmpdir); + + $this->assertSame('FOO', $foo); + $this->assertSame('BAZ', $bar); + } + /** * @expectedException \Symfony\Component\Dotenv\Exception\PathException */ @@ -219,8 +251,8 @@ public function testOverrideEnvVar() { putenv('TEST_ENV_VAR=original_value'); - $dotenv = new DotEnv(true); - $dotenv->populate(array('TEST_ENV_VAR' => 'new_value')); + $dotenv = new DotEnv(); + $dotenv->populate(array('TEST_ENV_VAR' => 'new_value'), true); $this->assertSame('new_value', getenv('TEST_ENV_VAR')); }