From de80a9c061a42faabf16a9f863db1a2dd0db367d Mon Sep 17 00:00:00 2001 From: Clemens Schwaighofer Date: Mon, 11 Oct 2021 08:58:36 +0900 Subject: [PATCH] Create dotenv readEnvFile single function --- Readme.md | 43 ++++++++++++++++++++++ src/read_env_file.php | 83 ++++++++++++++++++++++++++++++++++++++++++ test/.env | 25 +++++++++++++ test/read_env_file.php | 15 ++++++++ 4 files changed, 166 insertions(+) create mode 100644 Readme.md create mode 100644 src/read_env_file.php create mode 100644 test/.env create mode 100644 test/read_env_file.php diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..3a72f9f --- /dev/null +++ b/Readme.md @@ -0,0 +1,43 @@ +# dotenv: readEnvFile() + +A single function implementation of https://github.com/vlucas/phpdotenv + +This is not a functional replacement, but a very simple implementation of the basic functions. + +## How it works + +Put the function where it is needed or put it in a file and load it. + +if not parameter is given it will use `__DIR__` as base path. +Second parameter is file name override. Default is `.env` + +Data is loaded into _ENV only. + +If there is already an entry in _ENV then it will not be overwritten. + +## .env file example + +A valid entry has to start with an alphanumeric string, underscores are allowed and +then have an equal sign (=). After the equal sign the data block starts. Data can be +quoted with double quotes (") and if this is done can stretch over multiple lines. +The openeing double quote must be on the same lign as the requal sign (=). If double +quoted (") charcters are used it will read each line until another double quote (") +character is found. Everything after that is ignored. + +Any spaces before the variable or before and after the equal sign (=) are ignored. + +Line is read until `PHP_EOL`. So any trailing spaces are read too. + +Any line that is not valid is ignored. + +```ini +# this line is ignored +SOMETHING=A +OTHER="A B C" +MULTI_LINE="1 2 3 +4 5 6 +7 8 9" ; and this is ignored +ESCAPE="String \" inside \" other " +DOUBLE="I will be used" +DOUBLE="This will be ignored" +``` diff --git a/src/read_env_file.php b/src/read_env_file.php new file mode 100644 index 0000000..6176ec8 --- /dev/null +++ b/src/read_env_file.php @@ -0,0 +1,83 @@ + abort + if (!is_file($env_file_target)) { + $status = 3; + return $status; + } + // cannot open file -> abort + if (($fp = fopen($env_file_target, 'r')) === false) { + $status = 2; + return $status; + } + // set to readable but not yet any data loaded + $status = 1; + $block = false; + $var = ''; + while ($line = fgets($fp)) { + // main match for variable = value part + if (preg_match("/^\s*([\w_]+)\s*=\s*((\"?).*)/", $line, $matches)) { + $var = $matches[1]; + $value = $matches[2]; + $quotes = $matches[3]; + // wirte only if env is not set yet, and write only the first time + if (empty($_ENV[$var])) { + if (!empty($quotes)) { + $block = true; + // match greedy for first to last so we move any " if there are + if (preg_match('/^"(.*[^\\\])"/U', $value, $matches)) { + $value = $matches[1]; + } else { + // first " in string remove + // add removed new line back because this is a multi line + $value = ltrim($value, '"') . PHP_EOL; + } + } + // if block is set, we strip line of slashes + $_ENV[$var] = $block === true ? stripslashes($value) : $value; + // set successful load + $status = 0; + } + } elseif ($block === true) { + // read line until there is a unescaped " + // this also strips everything after the last " + if (preg_match("/(.*[^\\\])\"/", $line, $matches)) { + $block = false; + // strip ending " and EVERYTHING that follows after that + $line = $matches[1]; + } + // strip line of slashes + $_ENV[$var] .= stripslashes($line); + } + } + fclose($fp); + return $status; +} + +// __END__ diff --git a/test/.env b/test/.env new file mode 100644 index 0000000..cca580b --- /dev/null +++ b/test/.env @@ -0,0 +1,25 @@ +# enviroment file +SOMETHING=A +OTHER="B IS B" +Complex="A B \"D is F" +HAS_SPACE= "ABC"; +FAILURE = ABC +SIMPLEBOX= A B C +TITLE=1 +FOO=1.2 +Test="A" +TEST="B" +TEST="D" +LINE="ABC +DEF" +OTHERLINE="ABC +AF\"ASFASDF +MORESHIT" +SUPERLINE= +"asfasfasf" + __FOO_BAR_1 = b + __FOOFOO = f +123123=number +EMPTY= += flase +asfasdf diff --git a/test/read_env_file.php b/test/read_env_file.php new file mode 100644 index 0000000..95232d8 --- /dev/null +++ b/test/read_env_file.php @@ -0,0 +1,15 @@ +"; +print "ORIG:
" . file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . '.env') . "
"; + +$status = readEnvFile(__DIR__); + +print "STATUS: " . ($status ? 'OK' : 'FAIL') . "
"; +print "ENV:
" . print_r($_ENV, true) . "

"; + +// __END__