Skip to content

Commit e61e0a0

Browse files
author
F. Michel
authored
Merge pull request #3 from jaumarar/process-quotes
Added process of quotes
2 parents e6d703b + 1c906db commit e61e0a0

9 files changed

+269
-42
lines changed

README.md

+43-7
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,58 @@
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
46+
2547
Simple and easy!
48+
49+
# Processors
50+
51+
Also the variables are parsed according to the configuration passed as parameter to the constructor. The available processors are:
52+
53+
## BooleanProcessor
54+
55+
``VARIABLE=false`` will be processed to ```bool(false)```
56+
57+
NOTE: ``VARIABLE="true"`` will be processed to ```string(4) "true"```
58+
59+
## QuotedProcessor
60+
61+
``VARIABLE="anything"`` will be processed to ```string(8) "anything"```

src/DotEnv.php

+47-28
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,12 @@
22

33
namespace DevCoder;
44

5+
use DevCoder\Processor\AbstractProcessor;
6+
use DevCoder\Processor\BooleanProcessor;
7+
use DevCoder\Processor\QuotedProcessor;
8+
59
class DotEnv
610
{
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-
2011
/**
2112
* The directory where the .env file can be located.
2213
*
@@ -27,26 +18,42 @@ class DotEnv
2718
/**
2819
* Configure the options on which the parsed will act
2920
*
30-
* @var array
21+
* @var string[]
3122
*/
32-
protected $options = [];
23+
protected $processors = [];
3324

34-
public function __construct(string $path, array $options = [])
25+
public function __construct(string $path, array $processors = null)
3526
{
3627
if (!file_exists($path)) {
3728
throw new \InvalidArgumentException(sprintf('%s does not exist', $path));
3829
}
3930

4031
$this->path = $path;
4132

42-
$this->processOptions($options);
33+
$this->setProcessors($processors);
4334
}
4435

45-
private function processOptions(array $options) : void
36+
private function setProcessors(array $processors = null) : DotEnv
4637
{
47-
$this->options = array_merge([
48-
static::PROCESS_BOOLEANS => true
49-
], $options);
38+
/**
39+
* Fill with default processors
40+
*/
41+
if ($processors === null) {
42+
$this->processors = [
43+
BooleanProcessor::class,
44+
QuotedProcessor::class
45+
];
46+
47+
return $this;
48+
}
49+
50+
foreach ($processors as $processor) {
51+
if (is_subclass_of($processor, AbstractProcessor::class)) {
52+
$this->processors[] = $processor;
53+
}
54+
}
55+
56+
return $this;
5057
}
5158

5259
/**
@@ -78,19 +85,31 @@ public function load() : void
7885
}
7986
}
8087

81-
private function processValue(string $value) {
88+
/**
89+
* Process the value with the configured processors
90+
*
91+
* @param string $value The value to process
92+
* @return string|bool
93+
*/
94+
private function processValue(string $value)
95+
{
96+
/**
97+
* First trim spaces and quotes if configured
98+
*/
8299
$trimmedValue = trim($value);
83100

84-
if (!empty($this->options[static::PROCESS_BOOLEANS])) {
85-
$loweredValue = strtolower($trimmedValue);
86-
87-
$isBoolean = in_array($loweredValue, ['true', 'false'], true);
101+
foreach ($this->processors as $processor) {
102+
/** @var AbstractProcessor $processorInstance */
103+
$processorInstance = new $processor($trimmedValue);
88104

89-
if ($isBoolean) {
90-
return $loweredValue === 'true';
105+
if ($processorInstance->canBeProcessed()) {
106+
return $processorInstance->execute();
91107
}
92108
}
93109

110+
/**
111+
* Does not match any processor options, return as is
112+
*/
94113
return $trimmedValue;
95114
}
96115
}

src/Processor/AbstractProcessor.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
namespace DevCoder\Processor;
3+
4+
abstract class AbstractProcessor implements IProcessor
5+
{
6+
/**
7+
* The value to process
8+
* @var string
9+
*/
10+
protected $value;
11+
12+
public function __construct(string $value)
13+
{
14+
$this->value = $value;
15+
}
16+
}

src/Processor/BooleanProcessor.php

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
namespace DevCoder\Processor;
3+
4+
class BooleanProcessor extends AbstractProcessor
5+
{
6+
public function canBeProcessed(): bool
7+
{
8+
$loweredValue = strtolower($this->value);
9+
10+
return in_array($loweredValue, ['true', 'false'], true);
11+
}
12+
13+
public function execute()
14+
{
15+
return strtolower($this->value) === 'true';
16+
}
17+
}

src/Processor/IProcessor.php

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
namespace DevCoder\Processor;
3+
4+
interface IProcessor
5+
{
6+
public function __construct(string $value);
7+
8+
public function canBeProcessed(): bool;
9+
10+
public function execute();
11+
}

src/Processor/QuotedProcessor.php

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

0 commit comments

Comments
 (0)