[Dotenv] add loadEnv(), a smoother alternative to loadForEnv()
This commit is contained in:
parent
8d277ce3e5
commit
0cf9acb70f
@ -48,34 +48,41 @@ final class Dotenv
|
|||||||
*/
|
*/
|
||||||
public function load(string $path, string ...$extraPaths): void
|
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.
|
* .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 $path A file to load
|
||||||
* @param ...string $extraPaths A list of additional files 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 FormatException when a file has a syntax error
|
||||||
* @throws PathException when a file does not exist or is not readable
|
* @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();
|
$this->load($path);
|
||||||
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->doLoad(false, true, $pathList);
|
if (null === $env = $_SERVER[$varName] ?? $_ENV[$varName] ?? null) {
|
||||||
|
$this->populate(array($varName => $env = $defaultEnv));
|
||||||
|
}
|
||||||
|
|
||||||
|
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 @@ final class Dotenv
|
|||||||
*/
|
*/
|
||||||
public function overload(string $path, string ...$extraPaths): void
|
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 @@ final class Dotenv
|
|||||||
return new FormatException($message, new FormatExceptionContext($this->data, $this->path, $this->lineno, $this->cursor));
|
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) {
|
foreach ($paths as $path) {
|
||||||
if (is_readable($path) && !is_dir($path)) {
|
if (!is_readable($path) || is_dir($path)) {
|
||||||
$this->populate($this->parse(file_get_contents($path), $path), $overrideExistingVars);
|
|
||||||
} elseif (!$ignoreMissingExtraPaths || 0 === $i) {
|
|
||||||
throw new PathException($path);
|
throw new PathException($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->populate($this->parse(file_get_contents($path), $path), $overrideExistingVars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ class DotenvTest extends TestCase
|
|||||||
$this->assertSame('BAZ', $bar);
|
$this->assertSame('BAZ', $bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadForEnv()
|
public function testLoadEnv()
|
||||||
{
|
{
|
||||||
unset($_ENV['FOO']);
|
unset($_ENV['FOO']);
|
||||||
unset($_ENV['BAR']);
|
unset($_ENV['BAR']);
|
||||||
@ -197,50 +197,46 @@ class DotenvTest extends TestCase
|
|||||||
|
|
||||||
@mkdir($tmpdir = sys_get_temp_dir().'/dotenv');
|
@mkdir($tmpdir = sys_get_temp_dir().'/dotenv');
|
||||||
|
|
||||||
$path1 = tempnam($tmpdir, 'sf-');
|
$path = tempnam($tmpdir, 'sf-');
|
||||||
$path2 = tempnam($tmpdir, 'sf-');
|
|
||||||
|
|
||||||
file_put_contents($path1, 'FOO=BAR');
|
|
||||||
file_put_contents($path2, 'BAR=BAZ');
|
|
||||||
|
|
||||||
// .env
|
// .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('BAR', getenv('FOO'));
|
||||||
$this->assertSame('BAZ', getenv('BAR'));
|
$this->assertSame('dev', getenv('TEST_APP_ENV'));
|
||||||
|
|
||||||
// .env.dev
|
|
||||||
|
|
||||||
file_put_contents("$path1.dev", 'FOO=devBAR');
|
|
||||||
(new DotEnv())->loadForEnv('dev', $path1, $path2);
|
|
||||||
$this->assertSame('devBAR', getenv('FOO'));
|
|
||||||
|
|
||||||
// .env.local
|
// .env.local
|
||||||
|
|
||||||
file_put_contents("$path1.local", 'FOO=localBAR');
|
file_put_contents("$path.local", 'FOO=localBAR');
|
||||||
(new DotEnv())->loadForEnv('dev', $path1, $path2);
|
(new DotEnv())->loadEnv($path, 'TEST_APP_ENV');
|
||||||
$this->assertSame('localBAR', getenv('FOO'));
|
$this->assertSame('localBAR', getenv('FOO'));
|
||||||
|
|
||||||
// special case for test
|
// special case for test
|
||||||
|
|
||||||
file_put_contents("$path1.local", 'FOO=testBAR');
|
$_SERVER['TEST_APP_ENV'] = 'test';
|
||||||
(new DotEnv())->loadForEnv('test', $path1, $path2);
|
(new DotEnv())->loadEnv($path, 'TEST_APP_ENV');
|
||||||
$this->assertSame('BAR', getenv('FOO'));
|
$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
|
// .env.dev.local
|
||||||
|
|
||||||
file_put_contents("$path1.dev.local", 'FOO=devlocalBAR');
|
file_put_contents("$path.dev.local", 'FOO=devlocalBAR');
|
||||||
(new DotEnv())->loadForEnv('dev', $path1, $path2);
|
(new DotEnv())->loadEnv($path, 'TEST_APP_ENV');
|
||||||
$this->assertSame('devlocalBAR', getenv('FOO'));
|
$this->assertSame('devlocalBAR', getenv('FOO'));
|
||||||
|
|
||||||
putenv('FOO');
|
putenv('FOO');
|
||||||
putenv('BAR');
|
putenv('BAR');
|
||||||
unlink($path1);
|
unlink($path);
|
||||||
unlink("$path1.dev");
|
unlink("$path.dev");
|
||||||
unlink("$path1.local");
|
unlink("$path.local");
|
||||||
unlink("$path1.dev.local");
|
unlink("$path.dev.local");
|
||||||
unlink($path2);
|
|
||||||
rmdir($tmpdir);
|
rmdir($tmpdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user