├── .DS_Store ├── .env.example ├── LICENSE ├── cover.png ├── readme.md └── system ├── .DS_Store └── dotenv ├── Dotenv.php ├── Loader.php ├── Validator.php └── autoloader.php /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agungjk/phpdotenv-for-codeigniter/bad795daf2d327184698dc56e24b7871f9e1d1cd/.DS_Store -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | DB_CONNECTION=mysql 2 | DB_HOST=localhost 3 | DB_DATABASE=database 4 | DB_USERNAME=root 5 | DB_PASSWORD=root -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2010-2017 Google, Inc. http://angularjs.org 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agungjk/phpdotenv-for-codeigniter/bad795daf2d327184698dc56e24b7871f9e1d1cd/cover.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # PHP dotenv for codeigniter 2 | > Autodetect environment type and load variables from `.env` to `getenv()` automagically. 3 | 4 | This is a PHP version of the original [Ruby dotenv](https://github.com/bkeepers/dotenv). 5 | 6 | ![](cover.png) 7 | 8 | ## Manual Installation without Composer 9 | 1. Copy folder **system** to your codeigniter projects. 10 | 2. Add this code to your codeigniter index.php before codeigniter core loaded (before this text "* LOAD THE BOOTSTRAP FILE") : 11 | ```php 12 | /* 13 | * -------------------------------------------------------------------- 14 | * LOAD PHP DOT ENV FILE 15 | * -------------------------------------------------------------------- 16 | * 17 | * And away we go... 18 | * 19 | */ 20 | require_once BASEPATH . 'dotenv/autoloader.php'; 21 | 22 | $dotenv = new Dotenv\Dotenv(__DIR__); 23 | $dotenv->load(); 24 | ``` 25 | 26 | ## Configuration 27 | 1. Create **.env** according your environment by copy file **.env.example** for database configuration and the other configuration. 28 | Example : **.env.development**, **.env.testing**, **.env.production** 29 | 30 | 2. Load configuration, in file **application/config/database.php** change to this configuration 31 | ```php 32 | $db['default']['hostname'] = getenv('DB_HOST'); 33 | $db['default']['username'] = getenv('DB_USERNAME'); 34 | $db['default']['password'] = getenv('DB_PASSWORD'); 35 | $db['default']['database'] = getenv('DB_DATABASE'); 36 | $db['default']['dbdriver'] = getenv('DB_CONNECTION'); 37 | ``` 38 | 3. Add ".env" to your .gitignore file 39 | 4. It will be running, thank you 40 | 41 | ## Release History 42 | 43 | * 0.1.1 44 | * CHANGE: Autodetect environment & Update Readme 45 | * 0.1.0 46 | * Initial version 47 | 48 | ## Meta 49 | 50 | Agung Jati Kusumo – [@its_agungjk](https://twitter.com/its_agungjk) – agungjk.social@gmail.com 51 | 52 | Distributed under the MIT license. See ``LICENSE`` for more information. 53 | 54 | [https://github.com/agungjk/phpdotenv-for-codeigniter](https://github.com/agungjk/phpdotenv-for-codeigniter) 55 | 56 | ## Contributing 57 | 58 | 1. Fork it () 59 | 2. Create your feature branch (`git checkout -b feature/fooBar`) 60 | 3. Commit your changes (`git commit -am 'Add some fooBar'`) 61 | 4. Push to the branch (`git push origin feature/fooBar`) 62 | 5. Create a new Pull Request -------------------------------------------------------------------------------- /system/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agungjk/phpdotenv-for-codeigniter/bad795daf2d327184698dc56e24b7871f9e1d1cd/system/.DS_Store -------------------------------------------------------------------------------- /system/dotenv/Dotenv.php: -------------------------------------------------------------------------------- 1 | filePath = $this->getFilePath($path, $file); 32 | } 33 | 34 | /** 35 | * Load `.env` file in given directory. 36 | * 37 | * @return void 38 | */ 39 | public function load() 40 | { 41 | $this->loader = new Loader($this->filePath, $immutable = true); 42 | 43 | return $this->loader->load(); 44 | } 45 | 46 | /** 47 | * Load `.env` file in given directory. 48 | * 49 | * @return void 50 | */ 51 | public function overload() 52 | { 53 | $this->loader = new Loader($this->filePath, $immutable = false); 54 | 55 | return $this->loader->load(); 56 | } 57 | 58 | /** 59 | * Returns the full path to the file ensuring that it's readable. 60 | * 61 | * @param string $path 62 | * @param string $file 63 | * 64 | * @return string 65 | */ 66 | protected function getFilePath($path, $file) 67 | { 68 | if (!is_string($file)) { 69 | $file = '.env'; 70 | } 71 | 72 | $filePath = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$file; 73 | 74 | return $filePath; 75 | } 76 | 77 | /** 78 | * Required ensures that the specified variables exist, and returns a new Validation object. 79 | * 80 | * @param mixed $variable 81 | * 82 | * @return \Dotenv\Validator 83 | */ 84 | public function required($variable) 85 | { 86 | return new Validator((array) $variable, $this->loader); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /system/dotenv/Loader.php: -------------------------------------------------------------------------------- 1 | filePath = $filePath; 41 | $this->immutable = $immutable; 42 | } 43 | 44 | /** 45 | * Load `.env` file in given directory. 46 | * 47 | * @return void 48 | */ 49 | public function load() 50 | { 51 | $this->ensureFileIsReadable(); 52 | 53 | $filePath = $this->filePath; 54 | $lines = $this->readLinesFromFile($filePath); 55 | foreach ($lines as $line) { 56 | if ($this->isComment($line)) { 57 | continue; 58 | } 59 | if ($this->looksLikeSetter($line)) { 60 | $this->setEnvironmentVariable($line); 61 | } 62 | } 63 | 64 | return $lines; 65 | } 66 | 67 | /** 68 | * Ensures the given filePath is readable. 69 | * 70 | * @throws \InvalidArgumentException 71 | * 72 | * @return void 73 | */ 74 | protected function ensureFileIsReadable() 75 | { 76 | $filePath = $this->filePath; 77 | if (!is_readable($filePath) || !is_file($filePath)) { 78 | echo "Related \".env\" not found, please configure \"". basename($filePath) ."\" it before running codeigniter application"; exit; 79 | // throw new InvalidArgumentException(sprintf( 80 | // 'Dotenv: Environment file .env not found or not readable. '. 81 | // 'Create file with your environment settings at %s', 82 | // $filePath 83 | // )); 84 | } 85 | } 86 | 87 | /** 88 | * Normalise the given environment variable. 89 | * 90 | * Takes value as passed in by developer and: 91 | * - ensures we're dealing with a separate name and value, breaking apart the name string if needed 92 | * - cleaning the value of quotes 93 | * - cleaning the name of quotes 94 | * - resolving nested variables 95 | * 96 | * @param $name 97 | * @param $value 98 | * 99 | * @return array 100 | */ 101 | protected function normaliseEnvironmentVariable($name, $value) 102 | { 103 | list($name, $value) = $this->splitCompoundStringIntoParts($name, $value); 104 | list($name, $value) = $this->sanitiseVariableName($name, $value); 105 | list($name, $value) = $this->sanitiseVariableValue($name, $value); 106 | $value = $this->resolveNestedVariables($value); 107 | 108 | return array($name, $value); 109 | } 110 | 111 | /** 112 | * Process the runtime filters. 113 | * 114 | * Called from the `VariableFactory`, passed as a callback in `$this->loadFromFile()`. 115 | * 116 | * @param string $name 117 | * @param string $value 118 | * 119 | * @return array 120 | */ 121 | public function processFilters($name, $value) 122 | { 123 | list($name, $value) = $this->splitCompoundStringIntoParts($name, $value); 124 | list($name, $value) = $this->sanitiseVariableName($name, $value); 125 | list($name, $value) = $this->sanitiseVariableValue($name, $value); 126 | 127 | return array($name, $value); 128 | } 129 | 130 | /** 131 | * Read lines from the file, auto detecting line endings. 132 | * 133 | * @param string $filePath 134 | * 135 | * @return array 136 | */ 137 | protected function readLinesFromFile($filePath) 138 | { 139 | // Read file into an array of lines with auto-detected line endings 140 | $autodetect = ini_get('auto_detect_line_endings'); 141 | ini_set('auto_detect_line_endings', '1'); 142 | $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 143 | ini_set('auto_detect_line_endings', $autodetect); 144 | 145 | return $lines; 146 | } 147 | 148 | /** 149 | * Determine if the line in the file is a comment, e.g. begins with a #. 150 | * 151 | * @param string $line 152 | * 153 | * @return bool 154 | */ 155 | protected function isComment($line) 156 | { 157 | return strpos(trim($line), '#') === 0; 158 | } 159 | 160 | /** 161 | * Determine if the given line looks like it's setting a variable. 162 | * 163 | * @param string $line 164 | * 165 | * @return bool 166 | */ 167 | protected function looksLikeSetter($line) 168 | { 169 | return strpos($line, '=') !== false; 170 | } 171 | 172 | /** 173 | * Split the compound string into parts. 174 | * 175 | * If the `$name` contains an `=` sign, then we split it into 2 parts, a `name` & `value` 176 | * disregarding the `$value` passed in. 177 | * 178 | * @param string $name 179 | * @param string $value 180 | * 181 | * @return array 182 | */ 183 | protected function splitCompoundStringIntoParts($name, $value) 184 | { 185 | if (strpos($name, '=') !== false) { 186 | list($name, $value) = array_map('trim', explode('=', $name, 2)); 187 | } 188 | 189 | return array($name, $value); 190 | } 191 | 192 | /** 193 | * Strips quotes from the environment variable value. 194 | * 195 | * @param string $name 196 | * @param string $value 197 | * 198 | * @throws \InvalidArgumentException 199 | * 200 | * @return array 201 | */ 202 | protected function sanitiseVariableValue($name, $value) 203 | { 204 | $value = trim($value); 205 | if (!$value) { 206 | return array($name, $value); 207 | } 208 | 209 | if ($this->beginsWithAQuote($value)) { // value starts with a quote 210 | $quote = $value[0]; 211 | $regexPattern = sprintf( 212 | '/^ 213 | %1$s # match a quote at the start of the value 214 | ( # capturing sub-pattern used 215 | (?: # we do not need to capture this 216 | [^%1$s\\\\] # any character other than a quote or backslash 217 | |\\\\\\\\ # or two backslashes together 218 | |\\\\%1$s # or an escaped quote e.g \" 219 | )* # as many characters that match the previous rules 220 | ) # end of the capturing sub-pattern 221 | %1$s # and the closing quote 222 | .*$ # and discard any string after the closing quote 223 | /mx', 224 | $quote 225 | ); 226 | $value = preg_replace($regexPattern, '$1', $value); 227 | $value = str_replace("\\$quote", $quote, $value); 228 | $value = str_replace('\\\\', '\\', $value); 229 | } else { 230 | $parts = explode(' #', $value, 2); 231 | $value = trim($parts[0]); 232 | 233 | // Unquoted values cannot contain whitespace 234 | if (preg_match('/\s+/', $value) > 0) { 235 | throw new InvalidArgumentException('Dotenv values containing spaces must be surrounded by quotes.'); 236 | } 237 | } 238 | 239 | return array($name, trim($value)); 240 | } 241 | 242 | /** 243 | * Resolve the nested variables. 244 | * 245 | * Look for {$varname} patterns in the variable value and replace with an existing 246 | * environment variable. 247 | * 248 | * @param $value 249 | * 250 | * @return mixed 251 | */ 252 | protected function resolveNestedVariables($value) 253 | { 254 | if (strpos($value, '$') !== false) { 255 | $loader = $this; 256 | $value = preg_replace_callback( 257 | '/\${([a-zA-Z0-9_]+)}/', 258 | function ($matchedPatterns) use ($loader) { 259 | $nestedVariable = $loader->getEnvironmentVariable($matchedPatterns[1]); 260 | if (is_null($nestedVariable)) { 261 | return $matchedPatterns[0]; 262 | } else { 263 | return $nestedVariable; 264 | } 265 | }, 266 | $value 267 | ); 268 | } 269 | 270 | return $value; 271 | } 272 | 273 | /** 274 | * Strips quotes and the optional leading "export " from the environment variable name. 275 | * 276 | * @param string $name 277 | * @param string $value 278 | * 279 | * @return array 280 | */ 281 | protected function sanitiseVariableName($name, $value) 282 | { 283 | $name = trim(str_replace(array('export ', '\'', '"'), '', $name)); 284 | 285 | return array($name, $value); 286 | } 287 | 288 | /** 289 | * Determine if the given string begins with a quote. 290 | * 291 | * @param string $value 292 | * 293 | * @return bool 294 | */ 295 | protected function beginsWithAQuote($value) 296 | { 297 | return strpbrk($value[0], '"\'') !== false; 298 | } 299 | 300 | /** 301 | * Search the different places for environment variables and return first value found. 302 | * 303 | * @param string $name 304 | * 305 | * @return string 306 | */ 307 | public function getEnvironmentVariable($name) 308 | { 309 | switch (true) { 310 | case array_key_exists($name, $_ENV): 311 | return $_ENV[$name]; 312 | case array_key_exists($name, $_SERVER): 313 | return $_SERVER[$name]; 314 | default: 315 | $value = getenv($name); 316 | return $value === false ? null : $value; // switch getenv default to null 317 | } 318 | } 319 | 320 | /** 321 | * Set an environment variable. 322 | * 323 | * This is done using: 324 | * - putenv 325 | * - $_ENV 326 | * - $_SERVER. 327 | * 328 | * The environment variable value is stripped of single and double quotes. 329 | * 330 | * @param $name 331 | * @param string|null $value 332 | * 333 | * @return void 334 | */ 335 | public function setEnvironmentVariable($name, $value = null) 336 | { 337 | list($name, $value) = $this->normaliseEnvironmentVariable($name, $value); 338 | 339 | // Don't overwrite existing environment variables if we're immutable 340 | // Ruby's dotenv does this with `ENV[key] ||= value`. 341 | if ($this->immutable === true && !is_null($this->getEnvironmentVariable($name))) { 342 | return; 343 | } 344 | 345 | putenv("$name=$value"); 346 | $_ENV[$name] = $value; 347 | $_SERVER[$name] = $value; 348 | } 349 | } 350 | -------------------------------------------------------------------------------- /system/dotenv/Validator.php: -------------------------------------------------------------------------------- 1 | variables = $variables; 37 | $this->loader = $loader; 38 | 39 | $this->assertCallback( 40 | function ($value) { 41 | return !is_null($value); 42 | }, 43 | 'is missing' 44 | ); 45 | } 46 | 47 | /** 48 | * Assert that each variable is not empty. 49 | * 50 | * @return \Dotenv\Validator 51 | */ 52 | public function notEmpty() 53 | { 54 | return $this->assertCallback( 55 | function ($value) { 56 | return (strlen(trim($value)) > 0); 57 | }, 58 | 'is empty' 59 | ); 60 | } 61 | 62 | /** 63 | * Assert that each variable is amongst the given choices. 64 | * 65 | * @param string[] $choices 66 | * 67 | * @return \Dotenv\Validator 68 | */ 69 | public function allowedValues(array $choices) 70 | { 71 | return $this->assertCallback( 72 | function ($value) use ($choices) { 73 | return in_array($value, $choices); 74 | }, 75 | 'is not an allowed value' 76 | ); 77 | } 78 | 79 | /** 80 | * Assert that the callback returns true for each variable. 81 | * 82 | * @param callable $callback 83 | * @param string $message 84 | * 85 | * @return \Dotenv\Validator 86 | */ 87 | protected function assertCallback($callback, $message = 'failed callback assertion') 88 | { 89 | if (!is_callable($callback)) { 90 | throw new \InvalidArgumentException('Callback must be callable'); 91 | } 92 | 93 | $variablesFailingAssertion = array(); 94 | foreach ($this->variables as $variableName) { 95 | $variableValue = $this->loader->getEnvironmentVariable($variableName); 96 | if (call_user_func($callback, $variableValue) === false) { 97 | $variablesFailingAssertion[] = $variableName." $message"; 98 | } 99 | } 100 | 101 | if (count($variablesFailingAssertion) > 0) { 102 | throw new \RuntimeException(sprintf( 103 | 'One or more environment variables failed assertions: %s', 104 | implode(', ', $variablesFailingAssertion) 105 | )); 106 | } 107 | 108 | return $this; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /system/dotenv/autoloader.php: -------------------------------------------------------------------------------- 1 |