aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--composer.json21
-rw-r--r--src/Compiler/CompilerInterface.php23
-rw-r--r--src/Dotenv.php163
-rw-r--r--src/Exception/RuntimeException.php13
-rw-r--r--src/Loader/LoaderInterface.php16
-rw-r--r--src/Parser/ParserInterface.php18
-rw-r--r--src/Types/KeyValue.php48
8 files changed, 305 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8925195
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.idea
+vendor
+composer.lock \ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..565db47
--- /dev/null
+++ b/composer.json
@@ -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"
+ }
+}
diff --git a/src/Compiler/CompilerInterface.php b/src/Compiler/CompilerInterface.php
new file mode 100644
index 0000000..042a7d0
--- /dev/null
+++ b/src/Compiler/CompilerInterface.php
@@ -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;
+} \ No newline at end of file
diff --git a/src/Dotenv.php b/src/Dotenv.php
new file mode 100644
index 0000000..8e7ac10
--- /dev/null
+++ b/src/Dotenv.php
@@ -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');
+ }
+
+
+} \ No newline at end of file
diff --git a/src/Exception/RuntimeException.php b/src/Exception/RuntimeException.php
new file mode 100644
index 0000000..1a9be9c
--- /dev/null
+++ b/src/Exception/RuntimeException.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * @author: Alexander Kiryukhin <alexander@kiryukhin.su>
+ * @license: MIT
+ */
+
+namespace NeonXP\Dotenv\Exception;
+
+
+class RuntimeException extends \Exception
+{
+
+} \ No newline at end of file
diff --git a/src/Loader/LoaderInterface.php b/src/Loader/LoaderInterface.php
new file mode 100644
index 0000000..1c4f166
--- /dev/null
+++ b/src/Loader/LoaderInterface.php
@@ -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;
+} \ No newline at end of file
diff --git a/src/Parser/ParserInterface.php b/src/Parser/ParserInterface.php
new file mode 100644
index 0000000..b53e29f
--- /dev/null
+++ b/src/Parser/ParserInterface.php
@@ -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;
+} \ No newline at end of file
diff --git a/src/Types/KeyValue.php b/src/Types/KeyValue.php
new file mode 100644
index 0000000..e17dc4d
--- /dev/null
+++ b/src/Types/KeyValue.php
@@ -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;
+ }
+} \ No newline at end of file