From 0cf9acb70f6e6cb8deb00dec2d209371af2397cd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 7 Nov 2018 13:47:18 +0100 Subject: [PATCH] [Dotenv] add loadEnv(), a smoother alternative to loadForEnv() --- src/Symfony/Component/Dotenv/Dotenv.php | 51 +++++++++++-------- .../Component/Dotenv/Tests/DotenvTest.php | 48 ++++++++--------- 2 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index 6664c45f8da9..b66e9206a72f 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -48,34 +48,41 @@ final class Dotenv */ public function load(string $path, string ...$extraPaths): void { - $this->doLoad(false, false, \func_get_args()); + $this->doLoad(false, \func_get_args()); } /** - * Loads one or several .env and the corresponding .env.$env, .env.local and .env.$env.local files if they exist. + * Loads a .env file and the corresponding .env.local, .env.$env and .env.$env.local files if they exist. * * .env.local is always ignored in test env because tests should produce the same results for everyone. * - * @param string $path A file to load - * @param ...string $extraPaths A list of additional files to load + * @param string $path A file to load + * @param string $varName The name of the env vars that defines the app env + * @param string $defaultEnv The app env to use when none is defined + * @param array $testEnvs A list of app envs for which .env.local should be ignored * * @throws FormatException when a file has a syntax error * @throws PathException when a file does not exist or is not readable - * - * @see https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use */ - public function loadForEnv(string $env, string $path, string ...$extraPaths): void + public function loadEnv(string $path, string $varName = 'APP_ENV', string $defaultEnv = 'dev', array $testEnvs = array('test')): void { - $paths = \func_get_args(); - for ($i = 1; $i < \func_num_args(); ++$i) { - $path = $paths[$i]; - $pathList = array($path, "$path.$env"); - if ('test' !== $env) { - $pathList[] = "$path.local"; - } - $pathList[] = "$path.$env.local"; + $this->load($path); + + if (null === $env = $_SERVER[$varName] ?? $_ENV[$varName] ?? null) { + $this->populate(array($varName => $env = $defaultEnv)); + } - $this->doLoad(false, true, $pathList); + if (!\in_array($env, $testEnvs, true) && file_exists($p = "$path.local")) { + $this->load($p); + $env = $_SERVER[$varName] ?? $_ENV[$varName] ?? $env; + } + + if (file_exists($p = "$path.$env")) { + $this->load($p); + } + + if (file_exists($p = "$path.$env.local")) { + $this->load($p); } } @@ -90,7 +97,7 @@ public function loadForEnv(string $env, string $path, string ...$extraPaths): vo */ public function overload(string $path, string ...$extraPaths): void { - $this->doLoad(true, false, \func_get_args()); + $this->doLoad(true, \func_get_args()); } /** @@ -434,14 +441,14 @@ private function createFormatException($message) return new FormatException($message, new FormatExceptionContext($this->data, $this->path, $this->lineno, $this->cursor)); } - private function doLoad(bool $overrideExistingVars, bool $ignoreMissingExtraPaths, array $paths): void + private function doLoad(bool $overrideExistingVars, array $paths): void { - foreach ($paths as $i => $path) { - if (is_readable($path) && !is_dir($path)) { - $this->populate($this->parse(file_get_contents($path), $path), $overrideExistingVars); - } elseif (!$ignoreMissingExtraPaths || 0 === $i) { + 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 2e9331772aa1..953aa772d17a 100644 --- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php +++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php @@ -186,7 +186,7 @@ public function testLoad() $this->assertSame('BAZ', $bar); } - public function testLoadForEnv() + public function testLoadEnv() { unset($_ENV['FOO']); unset($_ENV['BAR']); @@ -197,50 +197,46 @@ public function testLoadForEnv() @mkdir($tmpdir = sys_get_temp_dir().'/dotenv'); - $path1 = tempnam($tmpdir, 'sf-'); - $path2 = tempnam($tmpdir, 'sf-'); - - file_put_contents($path1, 'FOO=BAR'); - file_put_contents($path2, 'BAR=BAZ'); + $path = tempnam($tmpdir, 'sf-'); // .env - (new DotEnv())->loadForEnv('dev', $path1, $path2); - + file_put_contents($path, 'FOO=BAR'); + (new DotEnv())->loadEnv($path, 'TEST_APP_ENV'); $this->assertSame('BAR', getenv('FOO')); - $this->assertSame('BAZ', getenv('BAR')); - - // .env.dev - - file_put_contents("$path1.dev", 'FOO=devBAR'); - (new DotEnv())->loadForEnv('dev', $path1, $path2); - $this->assertSame('devBAR', getenv('FOO')); + $this->assertSame('dev', getenv('TEST_APP_ENV')); // .env.local - file_put_contents("$path1.local", 'FOO=localBAR'); - (new DotEnv())->loadForEnv('dev', $path1, $path2); + file_put_contents("$path.local", 'FOO=localBAR'); + (new DotEnv())->loadEnv($path, 'TEST_APP_ENV'); $this->assertSame('localBAR', getenv('FOO')); // special case for test - file_put_contents("$path1.local", 'FOO=testBAR'); - (new DotEnv())->loadForEnv('test', $path1, $path2); + $_SERVER['TEST_APP_ENV'] = 'test'; + (new DotEnv())->loadEnv($path, 'TEST_APP_ENV'); $this->assertSame('BAR', getenv('FOO')); + // .env.dev + + unset($_SERVER['TEST_APP_ENV']); + file_put_contents("$path.dev", 'FOO=devBAR'); + (new DotEnv())->loadEnv($path, 'TEST_APP_ENV'); + $this->assertSame('devBAR', getenv('FOO')); + // .env.dev.local - file_put_contents("$path1.dev.local", 'FOO=devlocalBAR'); - (new DotEnv())->loadForEnv('dev', $path1, $path2); + file_put_contents("$path.dev.local", 'FOO=devlocalBAR'); + (new DotEnv())->loadEnv($path, 'TEST_APP_ENV'); $this->assertSame('devlocalBAR', getenv('FOO')); putenv('FOO'); putenv('BAR'); - unlink($path1); - unlink("$path1.dev"); - unlink("$path1.local"); - unlink("$path1.dev.local"); - unlink($path2); + unlink($path); + unlink("$path.dev"); + unlink("$path.local"); + unlink("$path.dev.local"); rmdir($tmpdir); }