#
PHP Dotenv
#
Requirements
- PHP 5.5+
#
Usage
Create a new loader:
<?php
$Loader = new \system\dotEnv\Loader('path/to/.env');
// Parse the .env file
$Loader->parse();
// Send the parsed .env file to the $_ENV variable
$Loader->toEnv();
?>
Most methods return the loader directly, so the following is also possible:
<?php
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->parse()
->toEnv(); // Throws LogicException if ->parse() is not called first
?>
You can use a .env
file with any of the following features:
# comments are allowed
FOO=bar # you can also have comments on the end of a line
export BAR=baz # you can optionally begin with an `export` statement
# both single and double quotes are allowed
BAZ='qux'
QUX="quux"
# as are escaped quotes or similar:
QUUX="corge \" grault"
CORGE='garply" waldo'
# unquoted values containing [null, true, false] are turned into
# their PHP equivalents
PHP_NULL=null
PHP_TRUE=true
PHP_FALSE=false
# when quoted, they are simply string values
STRING_NULL="null"
STRING_TRUE="true"
STRING_FALSE="false"
# spaces are allowed as well
# in a slightly more relaxed form from bash
GRAULT = fred
GARPLY = plugh
SPACES=" quote values with spaces" # will contain preceding space
# When using newlines, you should use quoted values
QUOTED_NEWLINE="newline\\nchar"
# you can even have nested variables using `${VAR}` syntax
# remember to define the nested var *before* using it
WALDO=${xyzzy} # not yet defined, so will result in WALDO = `{}`
THUD=${GARPLY} # will be defined as `plugh`
# note that variables beginning with a character
# other than [a-zA-Z_] shall throw a ParseException
01SKIPPED=skipped
# However, numbers *are* allowed elsewhere in the key
NOT_SKIPPED1=not skipped # will have the value `not`
Example
.env
files are available in thefixtures
directory
#
Defining Constants
You can also define constants automatically from your env file:
<?php
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->parse()
->define(); // Throws LogicException if ->parse() is not called first
?>
Already defined constants will result in an immediate LogicException
.
#
Adding to $_ENV
<?php
$overwriteENV = true;
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->parse()
->toEnv($overwriteENV); // Throws LogicException if ->parse() is not called first
?>
Already defined $_ENV
entries will result in an immediate LogicException
, unless $overwriteENV
is set to true
(default false
).
#
Adding to $_SERVER
<?php
$overwriteSERVER = true;
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->parse()
->toServer($overwriteSERVER); // Throws LogicException if ->parse() is not called first
?>
#
Making available to apache_getenv()
This should be preferred over
getenv
when using the Apache web server withmod_php
.
<?php
$overwrite = true;
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->parse()
->apacheSetenv($overwriteAPACHE); // Throws LogicException if ->parse() is not called first
// May throw a PHP Error if either apache_setenv() or apache_putenv() are not available
?>
Already defined apache_getenv()
entries will result in an immediate LogicException
, unless $overwriteAPACHE
is set to true
(default false
).
#
Making available to getenv()
<?php
$overwrite = true;
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->parse()
->putenv($overwriteENV); // Throws LogicException if ->parse() is not called first
?>
Already defined getenv()
entries will result in an immediate LogicException
, unless $overwriteENV
is set to true
(default false
).
#
Setting key prefixes
<?php
$environment = (new \system\dotEnv\Loader('path/to/.env'))
->parse()
->prefix('FOO')
->toServer(); // BAR=baz becomes FOOBAR=baz
?>
#
Return as array
<?php
$environment = (new \system\dotEnv\Loader('path/to/.env'))
->parse()
->toArray(); // Throws LogicException if ->parse() is not called first
?>
#
Return as json
<?php
$jsonEnvironment = (string)((new \system\dotEnv\Loader('path/to/.env'))->parse());
?>
#
Require environment variables
<?php
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->parse()
->expect('FOO', 'BAR', 'BAZ'); // Throws RuntimeException if variables are missing
?>
#
Turning off exceptions
<?php
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->raiseExceptions(false)
->parse()
->expect('FOO', 'BAR', 'BAZ'); // Returns false if variables are missing
?>
#
Skip existing environment variables
It is possible to skip existing enviroment variables (e.g. in a containerized / Docker setup).
<?php
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->parse()
->skipExisting() //Skip any environment variables that are already present
->putenv();
?>
#
Filtering environments
It is possible to optionally filter the environment data produced by php-dotenv through the use of filter classes. A filter class has an __invoke
method like so:
<?php
class LollipopFilter
{
/**
* Sets every key's value to the string `lollipop`
*
* @param array $environment Array of environment data
* @param array $config Array of configuration data that includes the callable
* @return array
*/
public function __invoke(array $environment, array $config)
{
$newEnvironment = [];
foreach ($environment as $key => $value) {
$newEnvironment[$key] = 'lollipop';
}
return $newEnvironment;
}
}
?>
You can attach filters using the setFilters()
method, which will override all currently specified filters. If an invalid filter is specified, a LogicException will be thrown.
<?php
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->setFilters(['LollipopFilter']); // Takes an array of namespaced class names
?>
Note that you can optionally set configuration for your filters. These are passed to the __invoke
method as the second argument.:
<?php
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->setFilters([
'LollipopFilter' => ['paintshop'],
]); // Takes an array of namespaced class names
?>
Filters can also be callables functions, which is useful in one-off situations. They are wrapped by the special CallableFilter
.
<?php
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->setFilters([function ($data) {
return $data;
}]);
?>
If you need special configuration for your callable filters, you can prefix your callable with __callable__N
, where N
is the integer index the callable is in your array. The callable itself should be contained in a callable
config key, as follows:
<?php
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->setFilters([
'__callable__0' => [
'callable' => function ($data, $config) {
return $data;
},
'someKey' => 'value',
]
]);
?>
Finally, to invoke a filter, you must call filter()
after calling parse()
.
<?php
$Loader = (new \system\dotEnv\Loader('path/to/.env'))
->setFilters(['LollipopFilter'])
->parse()
->filter();
?>
#
Available Filters
The following filters are built into php-dotenv.
= [CallableFilter](./filter/CallableFilter)
: Wraps a callable and invokes it upon the environment.
= [LowercaseKeyFilter](./filter/LowercaseKeyFilter)
: Lowercases all the keys for an environment to a single-depth.
= [NullFilter](./filter/NullFilter)
: Returns the environment data without any changes.
= [RemapKeysFilter](./filter/RemapKeysFilter)
: Remaps specific keys in a $config
array to a set of values at a single-depth.
= [UnderscoreArrayFilter](./filter/UnderscoreArrayFilter)
: Expands a flat array to a nested array. For example, ['0_Foo_Bar' => 'Far']
becomes [['Foo' => ['Bar' => 'Far']]]
.
= [UppercaseFirstKeyFilter](./filter/UppercaseFirstKeyFilter)
: Uppercases the first letter for all the keys for an environment to a single-depth..
= [UrlParseFilter](./filter/UrlParseFilter)
: When there is a key with the suffix _URL
, this filter uses parse_url
to add extra data to the environment.
#
Static Environment Definition
You can also call it via the static load
method call, which takes an array of arguments. If a method name is specified, the method is called with the value in the $options
array being sent into the method.
<?php
system\dotEnv\Loader::load(array(
'filepath' => 'path/to/.env',
'expect' => array('FOO', 'BAR', 'BAZ'),
'toEnv' => true,
'toServer' => true,
'define' => true,
));
?>
#
Validating External Environments
In some cases it may be necessary to validate that a given array of environment data matches your requirements. You can use the Loader->expect()
functionality via the standalone Expect
class:
<?php
use system\dotEnv\Expect;
$expect = new Expect($env);
$expect('FOO'); // Raises a RuntimeException if `env` is missing FOO
// You can turn off exception raising using the second `raise` argument
$expect = new Expect($env, false);
$expect('FOO'); // Returns false if `env` is missing FOO
?>
#
Rules to follow
When using dotEnv
, you should strive to follow the following rules:
= Add your .env
file to a gitignore and use a .default.env
to set defaults for your projects. This allows your development team to override defaults in a method that works for their local environment.
= Always set sane development defaults for any credential. If necessary, disable features when those credentials are invalid
.
= Where necessary, add comments to credentials with information as to what they are, how they are used, and how one might procure new ones.
= As php-dotenv
uses more lax procedures for defining environment variables, ensure your .env
files are compatible with your shell. A good way to test this is to run the following:
# source in your .env file
source .env
# check the environment
env
Simple way to ensure this is to check for the existence of .env
variables or at leaset the .defaults.env
// APP_NAME isn't set in staging/dev
if (!env('APP_NAME')) {
$loader = new system\dotenv\Loader([
__DIR__ '/.env',
__DIR__ '/.default.env'
]);
$loader->parse()->toEnv();
}