Skip to content

Commit 07795ba

Browse files
committed
Added process of quotes
1 parent e6d703b commit 07795ba

File tree

6 files changed

+184
-33
lines changed

6 files changed

+184
-33
lines changed

README.md

+30-8
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,44 @@
44
```
55
APP_ENV=dev
66
DATABASE_DNS=mysql:host=localhost;dbname=test;
7-
DATABASE_USER=root
7+
DATABASE_USER="root"
88
DATABASE_PASSWORD=root
9+
MODULE_ENABLED=true
910
```
1011

11-
**How to use ?**
12+
**Load the variables**
1213

1314
```php
1415
<?php
1516
use DevCoder\DotEnv;
1617

17-
(new DotEnv(__DIR__ . '/.env'))->load();
18+
$absolutePathToEnvFile = __DIR__ . '/.env';
1819

19-
echo getenv('APP_ENV');
20-
// dev
21-
echo getenv('DATABASE_DNS');
22-
// mysql:host=localhost;dbname=test;
20+
(new DotEnv($absolutePathToEnvFile))->load();
2321
```
22+
23+
**Use them!**
24+
```php
25+
/**
26+
* string(33) "mysql:host=localhost;dbname=test;"
27+
*/
28+
var_dump(getenv('DATABASE_DNS'));
29+
30+
/**
31+
* Removes double and single quotes from the variable:
32+
*
33+
* string(4) "root"
34+
*/
35+
var_dump(getenv('DATABASE_USER'));
36+
37+
/**
38+
* Processes booleans as such:
39+
*
40+
* bool(true)
41+
*/
42+
var_dump(getenv('MODULE_ENABLED'));
43+
```
44+
2445
Ideal for small project
25-
Simple and easy!
46+
47+
Simple and easy!

src/DotEnv.php

+42-21
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,6 @@
44

55
class DotEnv
66
{
7-
/**
8-
* Convert true and false to booleans, instead of:
9-
*
10-
* VARIABLE=false -> ['VARIABLE' => 'false']
11-
*
12-
* it will be
13-
*
14-
* VARIABLE=false -> ['VARIABLE' => false]
15-
*
16-
* default = true
17-
*/
18-
const PROCESS_BOOLEANS = 'PROCESS_BOOLEANS';
19-
207
/**
218
* The directory where the .env file can be located.
229
*
@@ -31,6 +18,13 @@ class DotEnv
3118
*/
3219
protected $options = [];
3320

21+
/**
22+
* Process strings to obtain characteristics of it
23+
*
24+
* @var Processor
25+
*/
26+
protected $processor;
27+
3428
public function __construct(string $path, array $options = [])
3529
{
3630
if (!file_exists($path)) {
@@ -40,12 +34,15 @@ public function __construct(string $path, array $options = [])
4034
$this->path = $path;
4135

4236
$this->processOptions($options);
37+
38+
$this->processor = new Processor();
4339
}
4440

4541
private function processOptions(array $options) : void
4642
{
4743
$this->options = array_merge([
48-
static::PROCESS_BOOLEANS => true
44+
Option::PROCESS_BOOLEANS => true,
45+
Option::PROCESS_QUOTES => true
4946
], $options);
5047
}
5148

@@ -78,16 +75,40 @@ public function load() : void
7875
}
7976
}
8077

81-
private function processValue(string $value) {
82-
$trimmedValue = trim($value);
83-
84-
if (!empty($this->options[static::PROCESS_BOOLEANS])) {
85-
$loweredValue = strtolower($trimmedValue);
78+
private function processValue(string $value)
79+
{
80+
/**
81+
* First trim spaces and quotes if configured
82+
*/
83+
$preprocessedValue = $this->preprocessValue($value);
8684

87-
$isBoolean = in_array($loweredValue, ['true', 'false'], true);
85+
/**
86+
* If the value is a boolean resolve it as such
87+
*/
88+
if (!empty($this->options[Option::PROCESS_BOOLEANS])) {
89+
$isBoolean = $this->processor->isBoolean($preprocessedValue);
8890

8991
if ($isBoolean) {
90-
return $loweredValue === 'true';
92+
return $this->processor->resolveAsBoolean($preprocessedValue);
93+
}
94+
}
95+
96+
/**
97+
* Does not match any processor options, return as is
98+
*/
99+
return $preprocessedValue;
100+
}
101+
102+
private function preprocessValue(string $value) : string
103+
{
104+
$trimmedValue = trim($value);
105+
106+
if (!empty($this->options[Option::PROCESS_QUOTES])) {
107+
$wrappedBySingleQuotes = $this->processor->isWrappedByChar($trimmedValue, '\'');
108+
$wrappedByDoubleQuotes = $this->processor->isWrappedByChar($trimmedValue, '"');
109+
110+
if ($wrappedBySingleQuotes || $wrappedByDoubleQuotes) {
111+
return $this->processor->removeFirstAndLastChar($trimmedValue);
91112
}
92113
}
93114

src/Option.php

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace DevCoder;
4+
5+
class Option
6+
{
7+
/**
8+
* Convert true and false to booleans, instead of:
9+
*
10+
* VARIABLE=false -> ['VARIABLE' => 'false']
11+
*
12+
* it will be
13+
*
14+
* VARIABLE=false -> ['VARIABLE' => false]
15+
*
16+
* default = true
17+
*/
18+
const PROCESS_BOOLEANS = 'PROCESS_BOOLEANS';
19+
20+
/**
21+
* Remove double and single quotes at the start and end of the variables, instead of:
22+
*
23+
* VARIABLE="This is a "sample" value" -> ['VARIABLE' => '"This is a "sample" value"']
24+
*
25+
* it will be
26+
*
27+
* VARIABLE="This is a "sample" value" -> ['VARIABLE' => 'This is a "sample" value']
28+
*
29+
* default = true
30+
*/
31+
const PROCESS_QUOTES = 'PROCESS_QUOTES';
32+
}

src/Processor.php

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace DevCoder;
4+
5+
class Processor
6+
{
7+
public function resolveAsBoolean(string $boolean) : bool
8+
{
9+
return strtolower($boolean) === 'true';
10+
}
11+
12+
public function isBoolean(string $value) : bool
13+
{
14+
$loweredValue = strtolower($value);
15+
16+
return in_array($loweredValue, ['true', 'false'], true);
17+
}
18+
19+
public function isWrappedByChar(string $value, string $char) : bool
20+
{
21+
return $value[0] === $char && $value[-1] === $char;
22+
}
23+
24+
public function removeFirstAndLastChar(string $value) : string
25+
{
26+
/**
27+
* Since this function is used for the quote removal
28+
* we don't need mb_substr
29+
*/
30+
return substr($value, 1, -1);
31+
}
32+
}

tests/DotenvTest.php

+41-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Test\DevCoder;
44

55
use DevCoder\DotEnv;
6+
use DevCoder\Option;
67
use PHPUnit\Framework\TestCase;
78

89
class DotenvTest extends TestCase
@@ -50,19 +51,19 @@ public function testFileNotExist() {
5051
public function testProcessBoolean()
5152
{
5253
(new DotEnv($this->env('.env.boolean'), [
53-
DotEnv::PROCESS_BOOLEANS => true
54+
Option::PROCESS_BOOLEANS => true
5455
]))->load();
5556

5657
$this->assertEquals(false, $_ENV['FALSE1']);
5758
$this->assertEquals(false, $_ENV['FALSE2']);
5859
$this->assertEquals(false, $_ENV['FALSE3']);
59-
$this->assertEquals("'false'", $_ENV['FALSE4']);
60+
$this->assertEquals(false, $_ENV['FALSE4']);
6061
$this->assertEquals('0', $_ENV['FALSE5']);
6162

6263
$this->assertEquals(true, $_ENV['TRUE1']);
6364
$this->assertEquals(true, $_ENV['TRUE2']);
6465
$this->assertEquals(true, $_ENV['TRUE3']);
65-
$this->assertEquals("'true'", $_ENV['TRUE4']);
66+
$this->assertEquals(true, $_ENV['TRUE4']);
6667
$this->assertEquals('1', $_ENV['TRUE5']);
6768
}
6869

@@ -72,11 +73,47 @@ public function testProcessBoolean()
7273
public function testDontProcessBoolean()
7374
{
7475
(new DotEnv($this->env('.env.boolean'), [
75-
DotEnv::PROCESS_BOOLEANS => false
76+
Option::PROCESS_BOOLEANS => false
7677
]))->load();
7778

7879
$this->assertEquals('false', $_ENV['FALSE1']);
7980

8081
$this->assertEquals('true', $_ENV['TRUE1']);
8182
}
83+
84+
/**
85+
* @runInSeparateProcess
86+
*/
87+
public function testProcessQuotes()
88+
{
89+
(new DotEnv($this->env('.env.quotes'), [
90+
Option::PROCESS_QUOTES => true
91+
]))->load();
92+
93+
$this->assertEquals('q1', $_ENV['QUOTED1']);
94+
$this->assertEquals('q2', $_ENV['QUOTED2']);
95+
$this->assertEquals('"q3"', $_ENV['QUOTED3']);
96+
$this->assertEquals('This is a "sample" value', $_ENV['QUOTED4']);
97+
$this->assertEquals('\"This is a "sample" value\"', $_ENV['QUOTED5']);
98+
$this->assertEquals('"q6', $_ENV['QUOTED6']);
99+
$this->assertEquals('q7"', $_ENV['QUOTED7']);
100+
}
101+
102+
/**
103+
* @runInSeparateProcess
104+
*/
105+
public function testDontProcessQuotes()
106+
{
107+
(new DotEnv($this->env('.env.quotes'), [
108+
Option::PROCESS_QUOTES => false
109+
]))->load();
110+
111+
$this->assertEquals('"q1"', $_ENV['QUOTED1']);
112+
$this->assertEquals('\'q2\'', $_ENV['QUOTED2']);
113+
$this->assertEquals('""q3""', $_ENV['QUOTED3']);
114+
$this->assertEquals('"This is a "sample" value"', $_ENV['QUOTED4']);
115+
$this->assertEquals('\"This is a "sample" value\"', $_ENV['QUOTED5']);
116+
$this->assertEquals('"q6', $_ENV['QUOTED6']);
117+
$this->assertEquals('q7"', $_ENV['QUOTED7']);
118+
}
82119
}

tests/env/.env.quotes

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
QUOTED1="q1"
2+
QUOTED2='q2'
3+
QUOTED3=""q3""
4+
QUOTED4="This is a "sample" value"
5+
QUOTED5=\"This is a "sample" value\"
6+
QUOTED6="q6
7+
QUOTED7=q7"

0 commit comments

Comments
 (0)