Как устанавливать внешние параметры в сервис-контейнере

Как устанавливать внешние параметры в сервис-контейнере

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

Переменные окружения

Вы можете ссылаться на переменные окружения, используя специальные параметры, названные в честь тех переменных, которые вы хотите использовать, окружённые env(). Их настоящие значения будут разрешены во время прогона (единожды на запрос), чтобы сброшенные контейнеры могли быть вновь динамически сконфигурированы даже после компиляции.

Например, при установке рецепта doctrine, конфигурация DB помещается в переменную окружения DATABASE_URL:

1
2
# .env
DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name"

На эту переменную ссылаются в конфигурации сервис-контейнера, используя %env(DATABASE_URL)%:

  • YAML
  • XML
  • PHP
1
2
3
4
5
# config/packages/doctrine.yaml
doctrine:
    dbal:
        url: '%env(DATABASE_URL)%'
    # ...

Вы также можете давать параметрам env() значение по умолчанию: значение по умолчанию будет использовано каждый раз, когда не найдена соответствующая переменная окружения:

  • YAML
  • XML
  • PHP
1
2
3
# config/services.yaml
parameters:
    env(DATABASE_HOST): localhost

Конфигурация переменных окружения в производстве

Во время разработки, вы будете использовать файл .env, чтобы сконфигурировать ваши переменные окружения. На вашем сервере производства рекомендуется конфигурировать переменные на уровне веб-сервера. Если вы используете Apache или Nginx, то вы можете использовать, к примеру, следующее:

  • Apache
  • Nginx
1
2
3
4
5
<VirtualHost *:80>
    # ...

    SetEnv DATABASE_URL "mysql://db_user:db_password@127.0.0.1:3306/db_name"
</VirtualHost>

Caution

Имейте в виду, что сброс содержания переменных $_SERVER и $_ENV или вывод содержания phpinfo() отобразит значения переменных окружения, обнажая чувствительную информацию вроде сертификатов DB.

Значения переменных окружения также отображаются в веб-интерфейсе Symfony профайлера. На практике это не должно быть проблемой, потому что веб-профайлер никогда не должен быть включён в production.

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

3.4

Процессоры переменных окружения появились в Symfony 3.4.

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

  • YAML
  • XML
  • PHP
1
2
3
4
# config/packages/framework.yaml
framework:
    router:
        http_port: env(int:HTTP_PORT)

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

env(string:FOO)

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

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

Преобразует FOO в булево значение:

  • YAML
  • XML
  • PHP
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(int:FOO)
Преобразует FOO в целочисленное значение.
env(float:FOO)
Преобразует FOO в дробное число.
env(const:FOO)

Находит значение константы определённой в FOO:

  • YAML
  • XML
  • PHP
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:

  • YAML
  • XML
  • PHP
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 значением конфигурационного параметра с этим значением:

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

Декодирует содержимое FOO, которое является CSV-закодированной строкой:

1
2
3
4
parameters:
    env(TRUSTED_HOSTS): "10.0.0.1, 10.0.0.2"
framework:
   trusted_hosts: '%env(csv:TRUSTED_HOSTS)%'

4.1

Процессор csv появился в Symfony 4.1.

env(file:FOO)

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

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

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

1
2
3
4
5
6
7
8
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
19
20
21
22
23
class LowercasingEnvVarProcessor implements EnvVarProcessorInterface
{
    private $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public function getEnv($prefix, $name, \Closure $getEnv)
    {
        $env = $getEnv($name);

        return strtolower($env);
    }

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

Константы

Контейнер также имеет поддержку для установки PHP-констант в качестве параметров. См. Введение в параметры, чтобы узнать больше деталей.

Смешанная конфигурация

Вы можете смешивать любые форматы конфигурации на свой вкус (YAML, XML и PHP) в config/packages/. Импорт PHP-файла даёт вам возможность добавлять всё, что нужно, в контейнер. Например, вы можете создать файл drupal.php, в котором вы установите URL базы данных, основанный на конфигурации DB Drupal:

1
2
3
4
5
6
7
// config/packages/drupal.php

// импортировать конфигурацию Drupal
include_once('/path/to/drupal/sites/default/settings.php');

// установить параметр app.database_url
$container->setParameter('app.database_url', $db_url);