Skip to content

Commit ad9eb3f

Browse files
Implemented Dotenv::parse()
Thanks for @taylorotwell for the name!
1 parent 2ed1021 commit ad9eb3f

File tree

4 files changed

+122
-0
lines changed

4 files changed

+122
-0
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,24 @@ VAR=value # comment
311311
```
312312

313313

314+
### Parsing Without Loading
315+
316+
Sometimes you just wanna parse the file and resolve the nested environment variables, by giving us a string, and have an array returned back to you. While this is already possible, it is a little fiddly, so we have provided a direct way to do this:
317+
318+
```php
319+
// ['FOO' => 'Bar', 'BAZ' => 'Hello Bar']
320+
Dotenv\Dotenv::parse("FOO=Bar\nBAZ=\"Hello \${FOO}\"");
321+
```
322+
323+
This is exactly the same as:
324+
325+
```php
326+
Dotenv\Dotenv::createArrayBacked(__DIR__)->load();
327+
```
328+
329+
only, instead of providing the directory to find the file, you have directly provided the file contents.
330+
331+
314332
### Usage Notes
315333

316334
When a new developer clones your codebase, they will have an additional

src/Dotenv.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
use Dotenv\Loader\LoaderInterface;
1010
use Dotenv\Parser\Parser;
1111
use Dotenv\Parser\ParserInterface;
12+
use Dotenv\Repository\Adapter\ArrayAdapter;
1213
use Dotenv\Repository\Adapter\PutenvAdapter;
1314
use Dotenv\Repository\RepositoryBuilder;
1415
use Dotenv\Repository\RepositoryInterface;
1516
use Dotenv\Store\StoreBuilder;
1617
use Dotenv\Store\StoreInterface;
18+
use Dotenv\Store\StringStore;
1719

1820
class Dotenv
1921
{
@@ -170,6 +172,44 @@ public static function createUnsafeImmutable($paths, $names = null, bool $shortC
170172
return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding);
171173
}
172174

175+
/**
176+
* Create a new dotenv instance with an array backed repository.
177+
*
178+
* @param string|string[] $paths
179+
* @param string|string[]|null $names
180+
* @param bool $shortCircuit
181+
* @param string|null $fileEncoding
182+
*
183+
* @return \Dotenv\Dotenv
184+
*/
185+
public static function createArrayBacked($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null)
186+
{
187+
$repository = RepositoryBuilder::createWithNoAdapters()->addAdapter(ArrayAdapter::class)->make();
188+
189+
return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding);
190+
}
191+
192+
/**
193+
* Parse the given content and resolve nested variables.
194+
*
195+
* This method behaves just like load(), only without mutating your actual
196+
* environment. We do this by using an array backed repository.
197+
*
198+
* @param string $content
199+
*
200+
* @throws \Dotenv\Exception\InvalidFileException
201+
*
202+
* @return array<string,string|null>
203+
*/
204+
public static function parse(string $content)
205+
{
206+
$repository = RepositoryBuilder::createWithNoAdapters()->addAdapter(ArrayAdapter::class)->make();
207+
208+
$phpdotenv = new self(new StringStore($content), new Parser(), new Loader(), $repository);
209+
210+
return $phpdotenv->load();
211+
}
212+
173213
/**
174214
* Read and load environment file(s).
175215
*

src/Store/StringStore.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Dotenv\Store;
6+
7+
final class StringStore implements StoreInterface
8+
{
9+
/**
10+
* The file content.
11+
*
12+
* @var string
13+
*/
14+
private $content;
15+
16+
/**
17+
* Create a new string store instance.
18+
*
19+
* @param string $content
20+
*
21+
* @return void
22+
*/
23+
public function __construct(string $content)
24+
{
25+
$this->content = $content;
26+
}
27+
28+
/**
29+
* Read the content of the environment file(s).
30+
*
31+
* @return string
32+
*/
33+
public function read()
34+
{
35+
return $this->content;
36+
}
37+
}

tests/Dotenv/DotenvTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,4 +349,31 @@ public function testDirectConstructor()
349349
'NULL' => '',
350350
], $dotenv->load());
351351
}
352+
353+
public function testDotenvParseExample1()
354+
{
355+
$output = Dotenv::parse(
356+
"BASE_DIR=\"/var/webroot/project-root\"\nCACHE_DIR=\"\${BASE_DIR}/cache\"\nTMP_DIR=\"\${BASE_DIR}/tmp\"\n"
357+
);
358+
359+
self::assertSame($output, [
360+
'BASE_DIR' => '/var/webroot/project-root',
361+
'CACHE_DIR' => '/var/webroot/project-root/cache',
362+
'TMP_DIR' => '/var/webroot/project-root/tmp',
363+
]);
364+
}
365+
366+
public function testDotenvParseExample2()
367+
{
368+
$output = Dotenv::parse("FOO=Bar\nBAZ=\"Hello \${FOO}\"");
369+
370+
self::assertSame($output, ['FOO' => 'Bar', 'BAZ' => 'Hello Bar']);
371+
}
372+
373+
public function testDotenvParseEmptyCase()
374+
{
375+
$output = Dotenv::parse('');
376+
377+
self::assertSame($output, []);
378+
}
352379
}

0 commit comments

Comments
 (0)