This commit is contained in:
Александр Кирюхин 2018-01-19 01:01:01 +03:00
commit 75721abf6f
8 changed files with 305 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.idea
vendor
composer.lock

21
composer.json Normal file
View file

@ -0,0 +1,21 @@
{
"name": "neonxp/dotenv",
"description": "Library to load .env files",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Alexander Kiryukhin",
"email": "alexander@kiryukhin.su"
}
],
"require": {},
"autoload": {
"psr-4": {
"NeonXP\\Dotenv\\": "src"
}
},
"require-dev": {
"phpunit/phpunit": "^6.5"
}
}

View file

@ -0,0 +1,23 @@
<?php
/**
* @author: Alexander Kiryukhin <alexander@kiryukhin.su>
* @license: MIT
*/
namespace NeonXP\Dotenv\Compiler;
use NeonXP\Dotenv\Types\KeyValue;
interface CompilerInterface
{
/**
* @param KeyValue[] $collection
*/
function setRawCollection(array $collection): void;
/**
* @param KeyValue $keyValue
* @return KeyValue
*/
function compileKeyValue(KeyValue $keyValue): KeyValue;
}

163
src/Dotenv.php Normal file
View file

@ -0,0 +1,163 @@
<?php
/**
* @author: Alexander Kiryukhin <alexander@kiryukhin.su>
* @license: MIT
*/
namespace NeonXP\Dotenv;
use NeonXP\Dotenv\Compiler\CompilerInterface;
use NeonXP\Dotenv\Exception\RuntimeException;
use NeonXP\Dotenv\Loader\LoaderInterface;
use NeonXP\Dotenv\Parser\ParserInterface;
use NeonXP\Dotenv\Types\KeyValue;
class Dotenv implements \ArrayAccess, \IteratorAggregate
{
/**
* @var LoaderInterface
*/
private $loader;
/**
* @var ParserInterface
*/
private $parser;
/**
* @var CompilerInterface
*/
private $compiler;
/**
* @var array
*/
private $loadedValues;
/**
* Dotenv constructor.
* @param LoaderInterface $loader
* @param ParserInterface $parser
* @param CompilerInterface $compiler
*/
public function __construct(LoaderInterface $loader = null, ParserInterface $parser = null, CompilerInterface $compiler = null)
{
$this->loader = $loader;
$this->parser = $parser;
$this->compiler = $compiler;
}
/**
* Load .env file using loader and parse it
* @param string $filePath
* @return Dotenv
*/
public function load(string $filePath = '.env'): Dotenv
{
$lines = $this->loader->load($filePath);
$rawData = array_map([$this->parser, 'parseLine'], $lines);
$this->compiler->setRawCollection($rawData);
$this->loadedValues = array_reduce(
array_map([$this->compiler, 'compileKeyValue'], $rawData),
function (array $acc, KeyValue $current) {
$acc[$current->getKey()] = $current->getValue();
return $acc;
},
[]
);
return $this;
}
/**
* Is key exists
* @param string $key
* @return bool
* @throws RuntimeException
*/
public function has(string $key): bool
{
$this->checkIsLoaded();
return isset($this->loadedValues[$key]);
}
/**
* @param string $key
* @param mixed|null $default
* @return mixed
* @throws RuntimeException
*/
public function get(string $key, mixed $default = null): mixed
{
if (!$this->has($key)) {
return $default;
}
return $this->loadedValues[$key];
}
/**
* @internal
* @throws RuntimeException
* @return void
*/
protected function checkIsLoaded(): void
{
if (!$this->loadedValues) {
throw new RuntimeException('Dotenv file not loaded');
}
}
/**
* @inheritdoc
* @return \ArrayIterator|\Traversable
* @throws RuntimeException
*/
public function getIterator()
{
$this->checkIsLoaded();
return new \ArrayIterator($this->loadedValues);
}
/**
* @inheritdoc
* @param string $offset
* @return bool
* @throws RuntimeException
*/
public function offsetExists($offset)
{
return $this->has($offset);
}
/**
* @inheritdoc
* @param string $offset
* @return mixed
* @throws RuntimeException
*/
public function offsetGet($offset)
{
return $this->get($offset);
}
/**
* @inheritdoc
* @param string $offset
* @param mixed $value
* @throws RuntimeException
*/
public function offsetSet($offset, $value)
{
throw new RuntimeException('Collection is immutable');
}
/**
* @inheritdoc
* @param string $offset
* @throws RuntimeException
*/
public function offsetUnset($offset)
{
throw new RuntimeException('Collection is immutable');
}
}

View file

@ -0,0 +1,13 @@
<?php
/**
* @author: Alexander Kiryukhin <alexander@kiryukhin.su>
* @license: MIT
*/
namespace NeonXP\Dotenv\Exception;
class RuntimeException extends \Exception
{
}

View file

@ -0,0 +1,16 @@
<?php
/**
* @author: Alexander Kiryukhin <alexander@kiryukhin.su>
* @license: MIT
*/
namespace NeonXP\Dotenv\Loader;
interface LoaderInterface
{
/**
* @param string $filePath
* @return string[]
*/
public function load(string $filePath = '.env'): array;
}

View file

@ -0,0 +1,18 @@
<?php
/**
* @author: Alexander Kiryukhin <alexander@kiryukhin.su>
* @license: MIT
*/
namespace NeonXP\Dotenv\Parser;
use NeonXP\Dotenv\Types\KeyValue;
interface ParserInterface
{
/**
* @param string $line
* @return KeyValue
*/
public function parseLine(string $line): KeyValue;
}

48
src/Types/KeyValue.php Normal file
View file

@ -0,0 +1,48 @@
<?php
/**
* @author: Alexander Kiryukhin <alexander@kiryukhin.su>
* @license: MIT
*/
namespace NeonXP\Dotenv\Types;
class KeyValue
{
/**
* @var string
*/
private $key;
/**
* @var string
*/
private $value;
/**
* KeyValue constructor.
* @param string $key
* @param mixed $value
*/
public function __construct(string $key, mixed $value)
{
$this->key = $key;
$this->value = $value;
}
/**
* @return string
*/
public function getKey(): string
{
return $this->key;
}
/**
* @return mixed
*/
public function getValue(): mixed
{
return $this->value;
}
}