Open jelen07 opened 5 years ago
Implementing ENV variables into neon
is generally a problem...
There are two packages by community, that tries it:
1) https://www.componette.com/wodcz/nette-dotenv/ 2) https://www.componette.com/rixxi/env/
Usage of the first one package in similar to your example
session:
cookieSecure: ::getenv(COOKIE_SECURE)
cookieSecure: @env::get(COOKIE_SECURE, no)
But the problem is a method in generated container looks like this:
public function createServiceSession__session(): Nette\Http\Session
{
$service = new Nette\Http\Session(....));
$service->setOptions(['cookieSecure' => $this->getService('env.env')->get('COOKIE_SECURE', FALSE)]);
return $service;
}
So the .env
file is loaded/parsed everytime. This can be fixed by loading ENV veriables only once in compile-time and pass it as an array into ServiceDefinition - ENV variables will be an static array in a Container's file.
But there is a another problem - if some CompilerExtension validates type of an configuration option like this:
Nette\Utils\Validator::assertField($config, 'name', 'string');
it will fails bcs @env::get('NAME')
will be translated as instance of Nette\DI\Statement(['@env', 'get'], ['NAME'])
so validation fails. Another example is in SessionExtension
:
public function loadConfiguration()
{
# ...
if (isset($config['cookieSecure']) && $config['cookieSecure'] === 'auto') {
$config['cookieSecure'] = $builder::literal('$this->getByType(Nette\Http\IRequest::class)->isSecured()');
}
# ...
}
If you set an cookieSecure
option to auto
in the .env
file and you pass a value into configuration as cookieSecure: @env::get('COOKIE_SECURE')
the vlaue of $config['cookieSeecure']
is instance of Nette\DI\Statement
, not string auto
. So another unpredictable behavior...
The second package by rixxi
is based on native DI parameters => extension loads ENV variables into DI parameters. This solution had a lot of limitations and its not compatible with a nette 2.4
because parameters are now processed before any CompilerExtension
.
The only solution I came up with is to extend Nette\Configurator
(used in bootstrap.php
), override method Configurator::createLoader()
and pass custom NeonAdapter
into Loader
, that will return parsed neon with ENV variables.
But i think the solution is ugly :confused: ...
Just load environment parameters to container parameters through configurator. Nothing more is needed
ATM we have configuration files in project like
It would be nice if we could write some syntax in neon to load this setting. This example is just a boolean, so it would be easy
But there are more complicated structures, even the whole block could not be used.
So something like:
::parseEnv(DATABASE_URL, Kdyby\Doctrine\EnvConfig)
Or any other hints? Will it be profit?