Skip to content

Commit c99280b

Browse files
authored
Merge pull request #3 from adhocore/develop
Develop
2 parents 2b7741f + 680f491 commit c99280b

File tree

6 files changed

+45
-21
lines changed

6 files changed

+45
-21
lines changed

readme.md

+13-5
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use Ahc\Env\Loader;
4343
4444
### ENV Format
4545

46-
Supports `#` or `;` comments and multilines. Literal double quote should be escaped like `\"`. See more examples below:
46+
Supports `#` or `;` comments. Literal double quote should be escaped like `""`. See more examples below:
4747

4848
```
4949
# comment line
@@ -54,17 +54,25 @@ c=$3#
5454
d="lol"
5555
# empty
5656
e=
57-
f=\"6\"
57+
# f is `"6"`
58+
f=""6""
5859
1_2=one_two
5960
# empty too
6061
E=""
6162
A_B=Apple Ball
62-
# multiline
63-
MUL="line 1
64-
line 2"
6563
x=Y
6664
```
6765

66+
Reference is possible like so:
67+
68+
```
69+
MAIN=1
70+
REF=${MAIN}/2
71+
REF2=${REF}/3
72+
# below will not be parsed as INV is not resolved
73+
REF3=${INV}
74+
```
75+
6876
### Retrieving
6977

7078
```php

src/Loader.php

+15-5
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,9 @@ public function load($file, $override = false, $mode = self::PUTENV)
4949
throw new \InvalidArgumentException('The .env file does not exist or is not readable');
5050
}
5151

52-
// Get file contents, fix the comments, quote the values and parse as ini.
52+
// Get file contents, fix the comments and parse as ini.
5353
$content = \preg_replace('/^\s*#/m', ';', \file_get_contents($file));
54-
$content = \preg_replace('/=([^"\r?\n].*)$/Um', '="$1"', $content);
55-
56-
$flag = defined('INI_SCANNER_TYPED') ? \INI_SCANNER_TYPED : \INI_SCANNER_NORMAL;
57-
$parsed = \parse_ini_string($content, false, $flag);
54+
$parsed = \parse_ini_string($content, false, INI_SCANNER_RAW);
5855

5956
if ($parsed === false) {
6057
throw new \RuntimeException('The .env file cannot be parsed due to malformed values');
@@ -80,12 +77,25 @@ protected function setEnv(array $vars, $override, $mode = self::PUTENV)
8077
continue;
8178
}
8279

80+
$value = $this->resolveRef($value);
81+
8382
$this->toEnv($key, $value, $mode);
8483
$this->toServer($key, $value, $mode);
8584
$this->toPutenv($key, $value, $mode);
8685
}
8786
}
8887

88+
protected function resolveRef($value)
89+
{
90+
if (!$value || \strpos($value, '${') === false) {
91+
return $value;
92+
}
93+
94+
return \preg_replace_callback('~\$\{(\w+)\}~', function ($m) {
95+
return (null === $ref = Retriever::getEnv($m[1], null)) ? $m[0] : $ref;
96+
}, $value);
97+
}
98+
8999
private function toEnv($key, $value, $mode)
90100
{
91101
if ($mode & self::ENV) {

tests/LoaderTest.php

+9-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public function testLoadPutenv()
2222
$this->assertEquals('"6"', getenv('f'), 'Escaped numeric string');
2323
$this->assertEquals('one_two', getenv('1_2'), 'Underscored string');
2424
$this->assertEquals('Apple Ball', getenv('A_B'), 'Multi word string');
25-
$this->assertEquals("line 1\nline 2", getenv('MUL'), 'Multi line string');
2625

2726
$this->assertFalse(getenv('MuL'), 'Key should be case sensitive');
2827

@@ -47,7 +46,6 @@ public function testLoadGlobals()
4746
$this->assertEquals('"6"', $source['f'], 'Escaped numeric string');
4847
$this->assertEquals('one_two', $source['1_2'], 'Underscored string');
4948
$this->assertEquals('Apple Ball', $source['A_B'], 'Multi word string');
50-
$this->assertEquals("line 1\nline 2", $source['MUL'], 'Multi line string');
5149

5250
$this->assertArrayNotHasKey('mUl', $source, 'Key should be case sensitive');
5351
}
@@ -71,7 +69,6 @@ public function testLoadOverrideAll()
7169
$this->assertEquals('o$3#', getenv('c'), 'Unquoted string new');
7270
$this->assertEquals('olol', getenv('d'), 'Quoted string new');
7371
$this->assertEquals('"o6"', getenv('f'), 'Escaped numeric string new');
74-
$this->assertEquals("oline 1\nline 2", getenv('MUL'), 'Multi line string new');
7572

7673
foreach (['SERVER', 'ENV'] as $name) {
7774
$source = $name === 'ENV' ? $_ENV : $_SERVER;
@@ -81,17 +78,24 @@ public function testLoadOverrideAll()
8178
$this->assertNotEquals('$3#', $source['c'], 'Unquoted string old');
8279
$this->assertNotEquals('lol', $source['d'], 'Quoted string old');
8380
$this->assertNotEquals('"6"', $source['f'], 'Escaped numeric string old');
84-
$this->assertNotEquals("line 1\nline 2", $source['MUL'], 'Multi line string old');
8581

8682
$this->assertEquals('o1', $source['a'], 'Unquoted number new');
8783
$this->assertEquals('o2', $source['b'], 'Quoted number new');
8884
$this->assertEquals('o$3#', $source['c'], 'Unquoted string new');
8985
$this->assertEquals('olol', $source['d'], 'Quoted string new');
9086
$this->assertEquals('"o6"', $source['f'], 'Escaped numeric string new');
91-
$this->assertEquals("oline 1\nline 2", $source['MUL'], 'Multi line string new');
9287
}
9388
}
9489

90+
public function testRef()
91+
{
92+
(new Loader)->load(__DIR__ . '/stubs/ref.env');
93+
94+
$this->assertSame('1/2', getenv('REF'));
95+
$this->assertSame('1/2/3', getenv('REF2'));
96+
$this->assertSame('${INV}', getenv('REF3'));
97+
}
98+
9599
/**
96100
* @expectedException \InvalidArgumentException
97101
* @expectedExceptionMessage The .env file does not exist or is not readable

tests/stubs/override.env

+1-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,4 @@ c=o$3#
55
; also comment line
66
d="olol"
77
e=
8-
f=\"o6\"
9-
MUL="oline 1
10-
line 2"
8+
f=""o6""

tests/stubs/ref.env

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# comment line
2+
MAIN=1
3+
REF=${MAIN}/2
4+
REF2=${REF}/3
5+
REF3=${INV}

tests/stubs/test.env

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ c=$3#
55
; also comment line
66
d="lol"
77
e=
8-
f=\"6\"
8+
f=""6""
99
1_2=one_two
1010
E=""
1111
A_B=Apple Ball
12-
MUL="line 1
13-
line 2"
12+
MUL="line 1line 2"
1413
x=Y

0 commit comments

Comments
 (0)