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

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

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

Використання змінних середовища для конфігурації додатків 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 включає в себе параметри контейнера (з синтаксисом %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 за замовчуванням , це вже зроблено за вас, завдяки автоконфігурації .