Процесори змінних середовища

Дата оновлення перекладу 2024-05-09

Процесори змінних середовища

Використання змінних середовища для конфігурації додатків 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)

Перетворює 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
# config/packages/framework.yaml
parameters:
    env(ALLOWED_LANGUAGES): '["en","de","es"]'
    app_allowed_languages: '%env(json:ALLOWED_LANGUAGES)%'
env(resolve:FOO)

Якщо зміст FOO містить параметри контейнера (з синтаксисом %parameter_name%), заміняє параметри їх значеннями:

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

Дешифрує зміст FOO, який є рядком, зашифрованим у CSV:

1
2
3
4
# config/packages/framework.yaml
parameters:
    env(ALLOWED_LANGUAGES): "en,de,es"
    app_allowed_languages: '%env(csv:ALLOWED_LANGUAGES)%'
env(shuffle:FOO)

Довільно перетасовує значення змінної середовища FOO, які мають бути масивом.

1
2
3
4
5
6
7
# config/packages/framework.yaml
parameters:
    env(REDIS_NODES): "127.0.0.1:6380,127.0.0.1:6381"
services:
    RedisCluster:
        class: RedisCluster
        arguments: [null, "%env(shuffle:csv:REDIS_NODES)%"]
env(file:FOO)

Повертає зміст файлу, чий шлях є значенням змінної середовища FOO:

1
2
3
4
5
# config/packages/framework.yaml
parameters:
    env(AUTH_FILE): '%kernel.project_dir%/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): '%kernel.project_dir%/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): '%kernel.project_dir%/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)%'
    # якщо зміст SECRETS_FILE: {"database_password": "secret"} - повертає "secret"
env(default:fallback_param:BAR)

Вилучає значення параметру fallback_param, коли змінна середовища BAR недоступна:

1
2
3
4
5
# config/services.yaml
parameters:
    # якщо PRIVATE_KEY не є валідним шляхом файлу, повертається зміст raw_key
    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)%'
env(enum:FooEnum:BAR)

Намагається перетворити змінну середовища на реальне значення \BackedEnum. Цей процесор бере повністю кваліфіковане імʼя \BackedEnum в якості аргументу.

1
2
3
4
5
6
# App\Enum\Environment
enum Environment: string
{
    case Development = 'dev';
    case Production = 'prod';
}
1
2
3
# config/services.yaml
parameters:
    typed_env: '%env(enum:App\Enum\Environment:APP_ENV)%'

6.2

Процесор змінної середовища env(enum:...) було представлено в Symfony 6.2.

env(defined:NO_FOO)

Оцінюється як true, якщо змінна середовища існує, а її значення - не '' (порожній рядок) або null; інакше повертає false.

1
2
3
# config/services.yaml
parameters:
    typed_env: '%env(defined:FOO)%'
env(urlencode:FOO)

Шифрує зміст змінної середовища FOO за допомогою функції urlencode.
Це особливо корисно, коли значення FOO несумісне з синтаксисом DSN.

1
2
3
4
# config/packages/framework.yaml
parameters:
    env(DATABASE_URL): 'mysql://db_user:foo@b$r@127.0.0.1:3306/db_name'
    encoded_database_url: '%env(urlencode:DATABASE_URL)%'

7.1

Процесор змінної середовища env(urlencode:...) було представлено в Symfony 7.1.

Також можливо поєднати будь-яку кількість процесорів:

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): string
    {
        $env = $getEnv($name);

        return strtolower($env);
    }

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

Щоб підключити новий процесор у додатку, зареєструйте його як сервіс та тегуйте його тегом container.env_var_processor. Якщо ви використовуєте конфігурацію services.yaml за замовчуванням , це вже зроблено за вас, завдяки автоконфігурації .