Skip to content

Added process of booleans #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use DevCoder\DotEnv;

echo getenv('APP_ENV');
// dev
echo getenv('DATABASE_DNS')
echo getenv('DATABASE_DNS');
// mysql:host=localhost;dbname=test;
```
Ideal for small project
Expand Down
58 changes: 54 additions & 4 deletions src/DotEnv.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,56 @@

class DotEnv
{
/**
* Convert true and false to booleans, instead of:
*
* VARIABLE=false -> ['VARIABLE' => 'false']
*
* it will be
*
* VARIABLE=false -> ['VARIABLE' => false]
*
* default = true
*/
const PROCESS_BOOLEANS = 'PROCESS_BOOLEANS';

/**
* The directory where the .env file can be located.
*
* @var string
*/
protected $path;

public function __construct(string $path)
/**
* Configure the options on which the parsed will act
*
* @var array
*/
protected $options = [];

public function __construct(string $path, array $options = [])
{
if(!file_exists($path)) {
if (!file_exists($path)) {
throw new \InvalidArgumentException(sprintf('%s does not exist', $path));
}

$this->path = $path;

$this->processOptions($options);
}

public function load() :void
private function processOptions(array $options) : void
{
$this->options = array_merge([
static::PROCESS_BOOLEANS => true
], $options);
}

/**
* Processes the $path of the instances and parses the values into $_SERVER and $_ENV, also returns all the data that has been read.
* Skips empty and commented lines.
*/
public function load() : void
{
if (!is_readable($this->path)) {
throw new \RuntimeException(sprintf('%s file is not readable', $this->path));
Expand All @@ -34,7 +68,7 @@ public function load() :void

list($name, $value) = explode('=', $line, 2);
$name = trim($name);
$value = trim($value);
$value = $this->processValue($value);

if (!array_key_exists($name, $_SERVER) && !array_key_exists($name, $_ENV)) {
putenv(sprintf('%s=%s', $name, $value));
Expand All @@ -43,4 +77,20 @@ public function load() :void
}
}
}

private function processValue(string $value) {
$trimmedValue = trim($value);

if (!empty($this->options[static::PROCESS_BOOLEANS])) {
$loweredValue = strtolower($trimmedValue);

$isBoolean = in_array($loweredValue, ['true', 'false'], true);

if ($isBoolean) {
return $loweredValue === 'true';
}
}

return $trimmedValue;
}
}
59 changes: 56 additions & 3 deletions tests/DotenvTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@

namespace Test\DevCoder;


use DevCoder\DotEnv;
use PHPUnit\Framework\TestCase;

class DotenvTest extends TestCase
{
private function env(string $file)
{
return __DIR__ . DIRECTORY_SEPARATOR . 'env' . DIRECTORY_SEPARATOR . $file;
}

/**
* @runInSeparateProcess
*/
public function testLoad() {
(new DotEnv(__DIR__ . '/.env'))->load();
(new DotEnv($this->env('.env.default')))->load();
$this->assertEquals('dev', getenv('APP_ENV'));
$this->assertEquals('mysql:host=localhost;dbname=test;', getenv('DATABASE_DNS'));
$this->assertEquals('root', getenv('DATABASE_USER'));
Expand All @@ -35,6 +41,53 @@ public function testLoad() {

public function testFileNotExist() {
$this->expectException(\InvalidArgumentException::class);
(new DotEnv(__DIR__ . '/.env.local'))->load();
(new DotEnv($this->env('.env.not-exists')))->load();
}

/**
* @runInSeparateProcess
*/
public function testLoadReturnsValues()
{
$loaded = (new DotEnv($this->env('.env.return')))->load();

$this->assertEquals('returned', $loaded['VALUE']);
$this->assertEquals('returned', $_ENV['VALUE']);
}

/**
* @runInSeparateProcess
*/
public function testProcessBoolean()
{
(new DotEnv($this->env('.env.boolean'), [
DotEnv::PROCESS_BOOLEANS => true
]))->load();

$this->assertEquals(false, $_ENV['FALSE1']);
$this->assertEquals(false, $_ENV['FALSE2']);
$this->assertEquals(false, $_ENV['FALSE3']);
$this->assertEquals("'false'", $_ENV['FALSE4']);
$this->assertEquals('0', $_ENV['FALSE5']);

$this->assertEquals(true, $_ENV['TRUE1']);
$this->assertEquals(true, $_ENV['TRUE2']);
$this->assertEquals(true, $_ENV['TRUE3']);
$this->assertEquals("'true'", $_ENV['TRUE4']);
$this->assertEquals('1', $_ENV['TRUE5']);
}

/**
* @runInSeparateProcess
*/
public function testDontProcessBoolean()
{
(new DotEnv($this->env('.env.boolean'), [
DotEnv::PROCESS_BOOLEANS => false
]))->load();

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

$this->assertEquals('true', $_ENV['TRUE1']);
}
}
10 changes: 10 additions & 0 deletions tests/env/.env.boolean
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FALSE1=false
FALSE2= false
FALSE3=FALSE
FALSE4='false'
FALSE5=0
TRUE1=true
TRUE2= true
TRUE3=TRUE
TRUE4='true'
TRUE5=1
File renamed without changes.
1 change: 1 addition & 0 deletions tests/env/.env.return
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VALUE=returned