feature #29767 Nullable environment variable processor (bpolaszek)
This PR was merged into the 4.3-dev branch.
Discussion
----------
Nullable environment variable processor
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
| Doc PR | todo
Hey there,
Because environment variables are strings by design, empty environment variables are evaluated to `""` by default.
In the same way, `MY_ENV_VAR=null` will be evaluated to `"null"`, as a string.
What I suggest is to allow some environment variables to be evaluated to `null` (the real one) when their strings are _blank_ or equal _null_, _Null_ or _NULL_.
This can be easily done through a new `nullable` processor:
```bash
# .env
API_KEY=
```
```yaml
# config/services.yaml
services:
FooService:
arguments:
$apiKey: %env(nullable:API_KEY)%
```
```php
# src/Services/FooService
namespace App\Services;
final class FooService
{
/**
* @var string|null
*/
private $apiKey;
/**
* FooService constructor.
*/
public function __construct(?string $apiKey)
{
$this->apiKey = $apiKey;
}
public function doSomething()
{
// Free plan
if (null === $this->apiKey) {
// ...
}
}
}
```
That's an example that comes to my mind but there can be many others.
This can also help in using null coalesce operators in constructors instead of checking if a string equals `""` (which is very PHP4 style).
Of course it can be used in conjunction with other types, i.e. `%env(float:nullable:SOME_OPTIONAL_FLOAT_ENV_VAR)%`.
What do you think?
Commits
-------
3a604ac392
Nullable environment variable processor
This commit is contained in:
commit
12a01a26c9
@ -6,6 +6,7 @@ CHANGELOG
|
||||
|
||||
* added `%env(trim:...)%` processor to trim a string value
|
||||
* added `%env(default:...)%` processor to fallback to a default value
|
||||
* added `%env(nullable:...)%` processor to allow empty variables to be processed as null values
|
||||
* added support for deprecating aliases
|
||||
|
||||
4.2.0
|
||||
|
@ -41,6 +41,7 @@ class EnvVarProcessor implements EnvVarProcessorInterface
|
||||
'int' => 'int',
|
||||
'json' => 'array',
|
||||
'key' => 'bool|int|float|string|array',
|
||||
'nullable' => 'bool|int|float|string|array',
|
||||
'resolve' => 'string',
|
||||
'default' => 'bool|int|float|string|array',
|
||||
'string' => 'string',
|
||||
@ -195,6 +196,10 @@ class EnvVarProcessor implements EnvVarProcessorInterface
|
||||
return str_getcsv($env);
|
||||
}
|
||||
|
||||
if ('nullable' === $prefix) {
|
||||
return '' === $env ? null : $env;
|
||||
}
|
||||
|
||||
if ('trim' === $prefix) {
|
||||
return trim($env);
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ class RegisterEnvVarProcessorsPassTest extends TestCase
|
||||
'int' => ['int'],
|
||||
'json' => ['array'],
|
||||
'key' => ['bool', 'int', 'float', 'string', 'array'],
|
||||
'nullable' => ['bool', 'int', 'float', 'string', 'array'],
|
||||
'resolve' => ['string'],
|
||||
'default' => ['bool', 'int', 'float', 'string', 'array'],
|
||||
'string' => ['string'],
|
||||
|
@ -433,4 +433,29 @@ class EnvVarProcessorTest extends TestCase
|
||||
];
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider validNullables
|
||||
*/
|
||||
public function testGetEnvNullable($value, $processed)
|
||||
{
|
||||
$processor = new EnvVarProcessor(new Container());
|
||||
$result = $processor->getEnv('nullable', 'foo', function ($name) use ($value) {
|
||||
$this->assertSame('foo', $name);
|
||||
|
||||
return $value;
|
||||
});
|
||||
$this->assertSame($processed, $result);
|
||||
}
|
||||
|
||||
public function validNullables()
|
||||
{
|
||||
return [
|
||||
['hello', 'hello'],
|
||||
['', null],
|
||||
['null', 'null'],
|
||||
['Null', 'Null'],
|
||||
['NULL', 'NULL'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user