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:
Fabien Potencier 2019-02-13 08:12:17 +01:00
commit 12a01a26c9
4 changed files with 32 additions and 0 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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'],

View File

@ -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'],
];
}
}