Процессоры переменных окружения

Дата обновления перевода 2023-07-20

Процессоры переменных окружения

Использование переменных окружения для конфигурации приложений Symfony - распространенная практика, чтобы сделать ваши приложения действительно динамическими.

Главная проблема переменных окружения заключается в том, что их значения могут быть только строками, а вашему приложению могут понадобиться другие типы данных (целое число, булево значение и т.д.). Symfony решаует эту проблему с помощью "процессоров переменных окружения", которые преобразуют изначальное содержание заданных переменных окружения. Следующий пример использует процессор целых числе, чтобы преобразовать значение переменной окружения HTTP_PORT в целое число:

1
2
3
4
# config/packages/framework.yaml
framework:
    router:
        http_port: '%env(int:HTTP_PORT)%'

Встроенные процессоры переменных окружения

Symfony предоставляет следующие процессоры переменных окружения:

env(string:FOO)

Превращает FOO в строку:

1
2
3
4
5
# config/packages/framework.yaml
parameters:
    env(SECRET): 'some_secret'
framework:
    secret: '%env(string:SECRET)%'
env(bool:FOO)

Превращает FOO в булево значение (значения true - 'true', 'on', 'yes' и все числа, кроме 0 и 0.0; все остальное - false):

1
2
3
4
5
# config/packages/framework.yaml
parameters:
    env(HTTP_METHOD_OVERRIDE): 'true'
framework:
    http_method_override: '%env(bool:HTTP_METHOD_OVERRIDE)%'

env(not:FOO)

5.3

Процессор переменных окружения not: был представлен в Symfony 5.3.

Превращает FOO в булево значение (так же, как и env(bool:...)), но возвращает ивенртированное значение (неправильные значения возвращаются как true, а правильные - как false):

1
2
3
# config/services.yaml
parameters:
    safe_for_production: '%env(not:APP_DEBUG)%'
env(int:FOO)
Превращает FOO в целое число.
env(float:FOO)
Превращает FOO в плавающее значение.
env(const:FOO)

Находит константное значение, именованное в FOO:

1
2
3
4
5
6
# config/packages/security.yaml
parameters:
    env(HEALTH_CHECK_METHOD): 'Symfony\Component\HttpFoundation\Request::METHOD_HEAD'
security:
    access_control:
        - { path: '^/health-check$', methods: '%env(const:HEALTH_CHECK_METHOD)%' }
env(base64:FOO)
Расшифровывает содержание FOO, которое является зашифрованной base64 строкой.
env(json:FOO)

Расшифровывает содержание FOO, которое является зашифрованной JSON строкой. Возвращает либо масиив, либо null:

1
2
3
4
5
# config/packages/framework.yaml
parameters:
    env(TRUSTED_HOSTS): '["10.0.0.1", "10.0.0.2"]'
framework:
    trusted_hosts: '%env(json:TRUSTED_HOSTS)%'
env(resolve:FOO)

Если содержание FOO включает в себя параметры контейнера container (с синтаксисом %parameter_name%), заменяет параметры их значениями:

1
2
3
4
5
6
7
# config/packages/sentry.yaml
parameters:
    env(HOST): '10.0.0.1'
    sentry_host: '%env(HOST)%'
    env(SENTRY_DSN): 'http://%sentry_host%/project'
sentry:
    dsn: '%env(resolve:SENTRY_DSN)%'
env(csv:FOO)

Расшифровывает содержание FOO, которое является зашифрованной CSV строкой:

1
2
3
4
5
# config/packages/framework.yaml
parameters:
    env(TRUSTED_HOSTS): "10.0.0.1,10.0.0.2"
framework:
   trusted_hosts: '%env(csv:TRUSTED_HOSTS)%'
env(file:FOO)

Возвращает содержание файла, путь которого является значение переменной окружения FOO:

1
2
3
4
5
# config/packages/framework.yaml
parameters:
    env(AUTH_FILE): '../config/auth.json'
google:
    auth: '%env(file:AUTH_FILE)%'
env(require:FOO)

require() PHP-файл, чей путь является значением переменной окружения FOO, и возвращает значение, которое было возвращено оттуда.

1
2
3
4
5
# config/packages/framework.yaml
parameters:
    env(PHP_FILE): '../config/.runtime-evaluated.php'
app:
    auth: '%env(require:PHP_FILE)%'
env(trim:FOO)

Усекает содержание переменной окружения FOO, удаляя пробелы в начале и конце строки. Это особенно полезно в комбинации с процессором file, так как он удаляет новые строки в конце файла.

1
2
3
4
5
# config/packages/framework.yaml
parameters:
    env(AUTH_FILE): '../config/auth.json'
google:
    auth: '%env(trim:file:AUTH_FILE)%'
env(key:FOO:BAR)

Извлекает значение, ассоциированные с ключом FOO, из массива, содержание которого хранится в переменной окружения BAR:

1
2
3
4
5
# config/services.yaml
parameters:
    env(SECRETS_FILE): '/opt/application/.secrets.json'
    database_password: '%env(key:database_password:json:file:SECRETS_FILE)%'
    # if SECRETS_FILE contents are: {"database_password": "secret"} it returns "secret"
env(default:fallback_param:BAR)

Извлекает значение параметра fallback_param, когда переменная окружения BAR недоступна:

1
2
3
4
5
# config/services.yaml
parameters:
    # if PRIVATE_KEY is not a valid file path, the content of raw_key is returned
    private_key: '%env(default:raw_key:file:PRIVATE_KEY)%'
    raw_key: '%env(PRIVATE_KEY)%'

Когда опущен резерный параметр (например, env(default::API_KEY)), возвращается значение null.

env(url:FOO)

Анализирует абсолютный URL и возвращает его содержание в виде ассоциированного массива.

1
2
# .env
MONGODB_URL="mongodb://db_user:db_password@127.0.0.1:27017/db_name"
1
2
3
4
5
6
7
8
9
10
11
# config/packages/mongodb.yaml
mongo_db_bundle:
    clients:
        default:
            hosts:
                - { host: '%env(string:key:host:url:MONGODB_URL)%', port: '%env(int:key:port:url:MONGODB_URL)%' }
            username: '%env(string:key:user:url:MONGODB_URL)%'
            password: '%env(string:key:pass:url:MONGODB_URL)%'
    connections:
        default:
            database_name: '%env(key:path:url:MONGODB_URL)%'

Caution

Для того, чтобы облегчить извлечение источника из URL, начальный / усекается из компонента path.

env(query_string:FOO)

Анализирует часть строки запроса заданного URL, и возвращает его компоненты в виде ассоциированного массива.

1
2
# .env
MONGODB_URL="mongodb://db_user:db_password@127.0.0.1:27017/db_name?timeout=3000"
1
2
3
4
5
6
# config/packages/mongodb.yaml
mongo_db_bundle:
    clients:
        default:
            # ...
            connectTimeoutMS: '%env(int:key:timeout:query_string:MONGODB_URL)%'

Также возможно комбинировать любое количество процессоров:

1
2
3
4
5
6
7
8
9
# config/packages/framework.yaml
parameters:
    env(AUTH_FILE): "%kernel.project_dir%/config/auth.json"
google:
    # 1. получает значение переменной окружения AUTH_FILE
    # 2. заменяет значения любого параметра конфигурации, чтобы получить путь конфигурации
    # 3. получает содержание файла, хранящегося по этому пути
    # 4. JSON-расшифровывает содержание файла и возвращает его
    auth: '%env(json:file:resolve:AUTH_FILE)%'

Пользовательские процессоры переменных окружения

Также возможно добавлять собственные процессоры для переменных окружения. Для начала, создайте класс, реализующий EnvVarProcessorInterface:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use Symfony\Component\DependencyInjection\EnvVarProcessorInterface;

class LowercasingEnvVarProcessor implements EnvVarProcessorInterface
{
    public function getEnv(string $prefix, string $name, \Closure $getEnv)
    {
        $env = $getEnv($name);

        return strtolower($env);
    }

    public static function getProvidedTypes()
    {
        return [
            'lowercase' => 'string',
        ];
    }
}

Чтобы включить новый процессор в приложении, зарегистрируйте его в качестве сервиса, и тегируйте тегом container.env_var_processor. Если вы используете конфигурацию services.yaml по умолчанию , это уже сделано за вас, благодаря автоконфигурации .