├── .gitignore ├── environ.jpg ├── tests ├── .env ├── directory │ └── env.ini └── EnvironTest.php ├── src ├── Interfaces │ └── EnvironInterface.php └── Environ.php ├── phpunit.xml ├── composer.json ├── LICENSE ├── .github └── workflows │ └── php.yml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | composer.lock 3 | .phpunit.result.cache 4 | -------------------------------------------------------------------------------- /environ.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melbahja/environ/HEAD/environ.jpg -------------------------------------------------------------------------------- /tests/.env: -------------------------------------------------------------------------------- 1 | ; you know this is a comment :) 2 | 3 | APP_MODE = "dev" 4 | 5 | 6 | [API_NAME] 7 | API_KEY = 'appkey' 8 | 9 | [urls] 10 | svn = "http://svn.php.net" 11 | git = "http://git.php.net" -------------------------------------------------------------------------------- /tests/directory/env.ini: -------------------------------------------------------------------------------- 1 | 2 | NULL_VAR = null 3 | 4 | TRUE_VAR = true 5 | 6 | FALSE_VAR = false 7 | 8 | FALSY = 0 9 | 10 | STR_VAR = "hello" 11 | 12 | [API_NAME] 13 | API_KEY = 'newappkey' 14 | -------------------------------------------------------------------------------- /src/Interfaces/EnvironInterface.php: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests/ 14 | 15 | 16 | 17 | 18 | src 19 | 20 | 21 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "melbahja/environ", 3 | "type": "library", 4 | "description": "Load environment variables from .env file ONLY on $_ENV and runtime.", 5 | "keywords": [".env", "env variables", "php7", "env loader", "environment", "ini"], 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Mohamed ELbahja", 10 | "email": "mohamed@elbahja.me", 11 | "homepage": "https://elbahja.me", 12 | "role": "Developer" 13 | } 14 | ], 15 | 16 | "require": { 17 | "php": ">=7.2" 18 | }, 19 | 20 | "autoload":{ 21 | "psr-4": { 22 | "Melbahja\\Environ\\": "src/" 23 | } 24 | }, 25 | 26 | "autoload-dev": { 27 | "psr-4": { 28 | "Melbahja\\Environ\\Tests\\": "tests/" 29 | } 30 | }, 31 | 32 | "require-dev": { 33 | "phpunit/phpunit": "^8.5" 34 | }, 35 | 36 | "minimum-stability":"dev" 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Mohamed Elbahja 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 all 13 | 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 THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/Environ.php: -------------------------------------------------------------------------------- 1 | $v) 24 | { 25 | static::set($k, $v); 26 | } 27 | 28 | return true; 29 | } 30 | } 31 | 32 | return false; 33 | } 34 | 35 | /** 36 | * Get env variable value. 37 | * 38 | * @param string $k 39 | * @param mixed $default 40 | * @return mixed 41 | */ 42 | public static function get(string $k, $default = null) 43 | { 44 | if (isset($_ENV[$k])) { 45 | return $_ENV[$k]; 46 | } 47 | 48 | return getenv($k) ?: $default; 49 | } 50 | 51 | /** 52 | * Set env variable value. 53 | * 54 | * @param string $k 55 | * @param mixed $v 56 | * @return bool 57 | */ 58 | public static function set(string $k, $v): bool 59 | { 60 | $_ENV[$k] = $v; 61 | return is_string($_ENV[$k]) ? putenv("{$k}={$v}") : true; 62 | } 63 | 64 | /** 65 | * Check server api type (example: apache, cli, cgi). 66 | * 67 | * @param string $sapi 68 | * @return bool 69 | */ 70 | public static function is(string $sapi): bool 71 | { 72 | return (substr(PHP_SAPI, 0, strlen($sapi)) === $sapi); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /.github/workflows/php.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | run: 13 | runs-on: ${{ matrix.os }} 14 | continue-on-error: ${{ matrix.experimental }} 15 | strategy: 16 | max-parallel: 2 17 | matrix: 18 | os: 19 | - ubuntu-latest 20 | php: 21 | - 8.0 22 | - 7.4 23 | - 7.2 24 | experimental: [false] 25 | 26 | name: PHP ${{ matrix.php }} test on ${{ matrix.os }} 27 | steps: 28 | - name: Checkout 29 | uses: actions/checkout@master 30 | - name: Install PHP 31 | uses: shivammathur/setup-php@master 32 | with: 33 | php-version: ${{ matrix.php }} 34 | coverage: xdebug 35 | - name: Get composer cache directory 36 | id: composer-cache 37 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 38 | - name: Cache composer dependencies 39 | uses: actions/cache@v1 40 | with: 41 | path: ${{ steps.composer-cache.outputs.dir }} 42 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} 43 | restore-keys: ${{ runner.os }}-composer 44 | - name: Install Composer dependencies 45 | run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader 46 | continue-on-error: ${{ matrix.experimental }} 47 | - name: Testing with PHPUnit 48 | run: vendor/bin/phpunit 49 | continue-on-error: ${{ matrix.experimental }} 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Environ 2 | 3 | Load PHP environment variables from .env (INI syntax) file only on `$_ENV` and runtime. 4 | 5 | ![](environ.jpg?raw=true) 6 | [![Build Status](https://img.shields.io/travis/melbahja/environ/master.svg)](https://travis-ci.org/melbahja/environ) 7 | [![Twitter](https://img.shields.io/twitter/url/https/github.com/melbahja/environ.svg?style=social)](https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Fgithub.com%2Fmelbahja%2Fenviron) 8 | 9 | ## Installation : 10 | 11 | ```bash 12 | composer require melbahja/environ 13 | ``` 14 | 15 | ## Why? 16 | 17 | Some env libraries load variables into `$_SERVER` and `$_REQUEST`, which is a stupid idea that can lead to expose credentials and insert sensitive information into log files. `environ` only load variables to superglobal `$_ENV` and runtime via `putenv`. 18 | 19 | 20 | ## Usage : 21 | 22 | `/path/to/your/project/.env` 23 | 24 | ```ini 25 | 26 | ; set a var 27 | APP_MODE = "dev" 28 | 29 | ; array 30 | [DATABASE] 31 | HOST = '127.0.0.1' 32 | USERNAME = 'root' 33 | PASSWORD = null 34 | 35 | ``` 36 | 37 | YourScript.php 38 | ```php 39 | 40 | require 'vendor/autoload.php'; 41 | 42 | use Melbahja\Environ\Environ; 43 | 44 | // environ looking for .env or env.ini file in your directory 45 | Environ::load('/path/to/your/project'); 46 | 47 | var_dump(Environ::get('APP_MODE')); // string 48 | 49 | var_dump(Environ::get('DATABASE')); // array 50 | 51 | var_dump($_ENV['DATABASE']); // array 52 | 53 | ``` 54 | 55 | ### Note: 56 | Arrays will not be available in `getenv()`, you can only access them via `$_ENV` or `Environ::get()`. 57 | 58 | ## Helper 59 | 60 | ```php 61 | # if you want a helper 62 | function env(string $var, $default = null) 63 | { 64 | return \Melbahja\Environ\Environ::get($var, $default); 65 | } 66 | ``` 67 | 68 | ## Environ methods : 69 | 70 | ```php 71 | Environ::load(string $directory): bool 72 | ``` 73 | ```php 74 | Environ::get(string $var, $default = null): mixed 75 | ``` 76 | ```php 77 | Environ::set(string $var, $value): bool 78 | ``` 79 | ```php 80 | # Example: Environ::is('apache'), Environ::is('cli') 81 | Environ::is(string $sapi): bool 82 | ``` 83 | 84 | 85 | ## License : 86 | 87 | [MIT](https://github.com/melbahja/environ/blob/master/LICENSE) Copyright (c) 2018-present Mohamed Elbahja 88 | -------------------------------------------------------------------------------- /tests/EnvironTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($isEnvFound); 20 | } 21 | 22 | 23 | public function testGetFromTheEnv() 24 | { 25 | $this->assertSame(Environ::get('APP_MODE'), 'dev'); 26 | 27 | $arrayVar = Environ::get('API_NAME'); 28 | 29 | $this->assertArrayHasKey('API_KEY', $arrayVar); 30 | $this->assertSame($arrayVar['API_KEY'], 'appkey'); 31 | 32 | $this->assertSame($_ENV['API_NAME']['API_KEY'], 'appkey'); 33 | 34 | $this->assertArrayHasKey('svn', Environ::get('urls')); 35 | $this->assertArrayHasKey('git', Environ::get('urls')); 36 | 37 | $this->assertArrayHasKey('git', $_ENV['urls']); 38 | $this->assertArrayHasKey('git', $_ENV['urls']); 39 | } 40 | 41 | 42 | public function testNotEnvFoundInDirectory() 43 | { 44 | $this->assertFalse(Environ::load(__DIR__ . 'notExistsDir')); 45 | } 46 | 47 | 48 | public function testOverrideAndLoadEnvDotIni() 49 | { 50 | $isEnvFound = Environ::load(__DIR__ . DIRECTORY_SEPARATOR . 'directory'); 51 | 52 | $this->assertTrue($isEnvFound); 53 | 54 | $arrayVar = Environ::get('API_NAME'); 55 | $this->assertArrayHasKey('API_KEY', $arrayVar); 56 | $this->assertSame($arrayVar['API_KEY'], 'newappkey'); 57 | 58 | 59 | $this->assertSame(Environ::get('NULL_VAR'), ''); 60 | $this->assertSame(Environ::get('NULL_VAR'), getenv('NULL_VAR')); 61 | 62 | $this->assertSame(Environ::get('TRUE_VAR'), '1'); 63 | $this->assertSame(Environ::get('TRUE_VAR'), getenv('TRUE_VAR')); 64 | 65 | $this->assertSame(Environ::get('FALSE_VAR'), ''); 66 | $this->assertSame(Environ::get('FALSE_VAR'), getenv('FALSE_VAR')); 67 | 68 | 69 | $this->assertSame(Environ::get('STR_VAR'), 'hello'); 70 | $this->assertSame(Environ::get('STR_VAR'), getenv('STR_VAR')); 71 | 72 | 73 | $this->assertSame(Environ::get('FALSY'), '0'); 74 | $this->assertSame(Environ::get('FALSY'), getenv('FALSY')); 75 | 76 | } 77 | 78 | 79 | public function testGetOnNonExistedKeyName() 80 | { 81 | $isEnvFound = Environ::load(__DIR__ . DIRECTORY_SEPARATOR . 'directory'); 82 | 83 | $this->assertNull(Environ::get('key_is_not_existed')); 84 | 85 | $this->assertFalse(getenv('key_is_not_existed')); 86 | } 87 | 88 | 89 | public function testGetDefaultValue() 90 | { 91 | $this->assertFalse(Environ::get('key_is_not_existed', getenv('key_is_not_existed'))); 92 | $this->assertTrue(Environ::get('key_is_not_existed', true)); 93 | } 94 | 95 | 96 | public function testIsSapiCli() 97 | { 98 | $this->assertTrue(Environ::is('cli')); 99 | } 100 | 101 | } 102 | --------------------------------------------------------------------------------