Конфигурация Symfony

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

Конфигурация Symfony

Файлы конфигурации

Приложения Symfony сконфигурированы с файлами, хранящимися в каталоге config/, который по умолчанию имеет следующую структуру:

1
2
3
4
5
6
your-project/
├─ config/
│  ├─ packages/
│  ├─ bundles.php
│  ├─ routes.yaml
│  └─ services.yaml
  • Файл routes.yaml определяет конфигурацию маршрутизации;
  • Файл services.yaml конфигурирует сервисы сервис-контейнера;
  • Файл bundles.php включает/выключает пакеты в вашем приложении;
  • Каталог config/packages/ хранит конфигурацию каждого пакета, установленного в вашем приложении.

Пакеты (также называемые "bundles" в Symfony и "plugins/modules" в других проектах) добавляют готовые к использованию функции к вашим проектам.

При использовании Symfony Flex , который в приложениях Symfony включен по умолчанию, пакеты обновляют файл bundles.php и создают новые файлы в config/packages/ автоматически во время установки. К примеру, это файл по умолчанию, созданный пакетом "API Platform":

1
2
3
4
# config/packages/api_platform.yaml
api_platform:
    mapping:
        paths: ['%kernel.project_dir%/src/Entity']

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

Tip

Чтобы узнать все о доступных опциях конфигурации, посмотрите справочник конфигурации Symfony или выполните команду config:dump-reference.

Форматы конфигурации

В отличие от других фреймворков, Symfony не заставляет вас использовать конкретный формат для конфигурации приложения. Symfony позволяет вам выбирать между YAML, XML и PHP, и по всей документации Symfony, все примеры конфигурации будут показаны в этих трех форматах.

Между форматами нет практической разницы. На самом деле, Symfony транформирует и кэширует их все в PHP перед запуском приложения, так что между ними даже нет разницы в производиельности.

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

  • YAML: простой, чистый и читаемый, но не все IDE поддерживают автозаполнение и валидацию для него. Узнайте о синтаксисе YAML ;
  • XML: автозаполняется/валидируется большинством IDE и нативно анализируется PHP, но иногда генерирует конфигурацию, которая считается слишком перегруженным. Изучите синтаксис XML;
  • PHP: очень мощний и позволяет вам создавать динамическую конфигурацию с массивами или ConfigBuilder .

Note

По умолчанию Symfony загружает файлы конфигурации, заданные в форматах YAML и PHP. Если вы определяете конфигурацию в формате XML, обновите метод configureContainer() и/или метод configureRoutes() в файле src/Kernel.php, чтобы добавить поддержку расширения файла .xml.

Импортирование файлов конфигурации

Symfony загружает файлы конфигурации используя компонент Config, который предоставляет продвинутые функции, такие как импорт других файлов конфигурации, даже если они используют другой формат:

1
2
3
4
5
6
7
8
9
10
11
12
13
# config/services.yaml
imports:
    - { resource: 'legacy_config.php' }

    # глобальные выражения также поддерживают загрузку нескольких файлов
    - { resource: '/etc/myapp/*.yaml' }

    # ignore_errors: not_found тихо удаляет ошибки в случае если загруженный файл не существует
    - { resource: 'my_config_file.xml', ignore_errors: not_found }
    # ignore_errors: true тихо удаляет все ошибки (включая неверный код и не найдено)
    - { resource: 'my_other_config_file.xml', ignore_errors: true }

# ...

Параметры конфигурации

Иногда одино и то же значение конфигурации используется в нескольких файлах конфигурации. Вместо его повторения, вы можете определить его как "параметр", что является чем-то вроде повторно используемого значения конфигурации. По соглашению, параметры определяются под ключом parameters в файле config/services.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# config/services.yaml
parameters:
    # имя параметра - произвольная строка (рекомендуется префикс 'app.'
    # для лучшей дифференциации ваших параметров от параметров Symfony).
    app.admin_email: 'something@example.com'

    # булевы параметры
    app.enable_v2_protocol: true

    # параметры массива/коллекции
    app.supported_locales: ['en', 'es', 'fr']

    # параметры бинарного содержания (зашифруйте его с помощью base64_encode())
    app.some_parameter: !!binary VGhpcyBpcyBhIEJlbGwgY2hhciAH

    # PHP-константы в качестве значений параметра
    app.some_constant: !php/const GLOBAL_CONSTANT
    app.another_constant: !php/const App\Entity\BlogPost::MAX_ITEMS

    # Случай исчисления в качестве значений параметра
    app.some_enum: !php/enum App\Enum\PostState::Published

# ...

Caution

При использовании XML-конфигурации, значения между тегами <parameter> не обрезаются. Это означает, что значение следующего параметра будет '\n something@example.com\n':

1
2
3
<parameter key="app.admin_email">
    something@example.com
</parameter>

Если вы хотите обрезать значение параметра, используйте атрибут trim.
При его использовании значение следующего параметра будет something@example.com:

1
2
3
<parameter key="app.admin_email" trim="true">
    something@example.com
</parameter>

Когда он будет определен, вы можете сослаться на значение этого парамтера из любого другого файла конфигурации, используя специальный синтаксис: оберните имя параметра в два % (например, %app.admin_email%):

1
2
3
4
5
6
# config/packages/some_package.yaml
some_package:
    # любая строка, окруженная двумя %, заменяется этим значением параметра
    email_address: '%app.admin_email%'

    # ...

Note

Если какое-то значение параметра включает в себя символ %, вам нужно экранировать его, добавив еще один %, чтобы Symfony не восприняел его в качестве ссылки на имя параметра:

1
2
3
4
# config/services.yaml
parameters:
    # Parsed as 'https://symfony.com/?foo=%s&amp;bar=%d'
    url_pattern: 'https://symfony.com/?foo=%%s&amp;bar=%%d'

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

Note

В связи с тем, как разрешаются параметры, вы не можете использовать их для построения путей в импорте динамически. Это означает, что что-то вроде этого работать не будет:

1
2
3
# config/services.yaml
imports:
    - { resource: '%kernel.project_dir%/somefile.yaml' }

Параметры конфигурации очень распространены в приложениях Symfony. Некоторые пакет даже определяют свои собственные параметры (например, при установке пакета переводов, в файл config/services.yaml добавляется новый параметр locale).

Tip

По соглашени, параметры, чьи имена начинаются с точки . (например, .mailer.transport), доступны только во время компиляции контейнера. Они полезны при работе с Передачами компилятора для объявления некоторых временных параметров, которые не будут доступны в приложении позднее.

See also

Позже в этой статье вы можете прочесть как получать параметры конфигурации в контроллерах и сервисах .

Окружения конфигурации

У вас есть только одно приложение, но понимаете вы это или нет, вам нужно, чтобы оно вело себя по-разному при разных обстоятельствах:

  • Во время разработки, вам нужно вести логи всего и иметь хорошие инструменты отладки;
  • После запуска в производство, вам нужно, чтобы то же приложение было оптимизировано для скорости и вело лог только для ошибок.

Файлы, хранящиеся в config/packages/ используются Symfony для конфигурации сервисов приложения. Другими словами, вы можете изменить поведение приложения, изменив то, какие файлы конфигурации загружаются. В этом заключается идея окружений конфигурации Symfony.

Типичное приложение Symfony начинается с трех окружений:
dev для локальной разработки prod для производственных серверов * test для автоматизированных тестов. При запуске приложения Symfony загружает

При запуске приложения Symfony загружает файлы конфигурации в таком порядке (последние файлы могут переопределять значения, установленные в предыдущих):

  1. Файлы в config/packages/*.<extension>;
  2. Файлы в config/packages/<environment-name>/*.<extension>;
  3. config/services.<extension>;
  4. config/services_<environment-name>.<extension>.

Возьмём пакет framework, установленный по умолчанию, в качестве примера:

  • Вначале загружается config/packages/framework.yaml во всех окружениях и конфигурирует фреймворк с некоторыми опциями;
  • В окружении prod не будет установлено ничего дополнительного, так как нет файла config/packages/prod/framework.yaml;
  • В окружении dev, также нет файла ( config/packages/dev/framework.yaml не существует).
  • В окружении test, файл config/packages/test/framework.yaml загружается для переопределения некоторых из настроек, ранее сконфигурированных в config/packages/framework.yaml.

В реальности, каждое окружение отличается от других совсем немного. Это означает, что все окружения имеют общую базу конфигурации, которая помещает файлы напрямую в каталог config/packages/.

Tip

Вы также можете определять опции для разных окружений в одном файле конфигурации, используя специальное ключевое слово when:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# config/packages/webpack_encore.yaml
webpack_encore:
    # ...
    output_path: '%kernel.project_dir%/public/build'
    strict_mode: true
    cache: false

# кеш включен только в окружении "prod"
when@prod:
    webpack_encore:
        cache: true

# отключить строгий режим только в окружении "test"
when@test:
    webpack_encore:
        strict_mode: false

# синтаксис YAML позволяет повторно использовать содержание, используя "якори" (&some_name) и "псевдонимы" (*some_name).
# В этом примере, конфигурация 'test' использует точно такую же конфигурацию, как в 'prod'
when@prod: &webpack_prod
    webpack_encore:
        # ...
when@test: *webpack_prod

See also

См. также метод configureContainer() класса Kernel, чтобы узнать все о порядке загрузки файлов конфигурации.

Выбор активного окружения

Приложения Symfony имеют файл под названием .env, который находится в корневом каталоге проекта. Этот файл используется для определения значения переменных окружения и детально разъясняется далее в этой статье.

Откройте файл .env file (а лучше файл .env.local, если вы его создавали) и отредактируйте зачение переменной APP_ENV, чтобы изменить окружение, в котором работает приложение. Например, запустите приложение в производстве:

1
2
# .env (или .env.local)
APP_ENV=prod

Это значение используется как для веб-команд, так и для консольных. Однако, вы можете переопределить его для команд, установив значение APP_ENV до их запуска:

1
2
3
4
5
# Используйте окружение, определенное в файле .env
$ php bin/console command_name

# Игнорируйте файл .env file и выполните эту команду в производстве
$ APP_ENV=prod php bin/console command_name

Создание нового окружения

Трех окружений по умолчанию предоставляемых Symfony достаточно для большоинства проектов, но вы также можете определить собственные окружения. Например, вот как вы можете определить окружение staging, где клиент может тестировать проект до его запуска в производство:

  1. Создайте каталог конфигурации с тем же именем, что и у окружения (в этом случае, config/packages/staging/);
  2. Добавьте необходимые файлы конфигурации в config/packages/staging/, чтобы определить поведение нового окружения. Symfony загружает файлы config/packages/*.yaml первыми, поэтому вам нужно сконфигурировать только разницу в этих файлах;
  3. Выберите окружение staging, используя вариант окружения APP_ENV, как объяснялось в предыдущем разделе.

Tip

Окружения часто похожи друг на друга, поэтому вы можете использовать символьные ссылки между каталогами config/packages/<environment-name>/, чтобы повторно использовать одну и ту же конфигурацию.

Вместо создания новых окружений, вы можете использовать переменные окружения, как объясняется в следующем разделе. Таким образом, вы можете использовать одно приложение и окружение (например, prod), но изменять его поведение, благодаря конфигурации, основанной на переменных окружения (например, запускать приложение в разных сценариях: постановка, обеспечение качества, проверка клиентов и т.д.).

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

Использование переменных окружения (или сокращенно "env vars") - это распространенная практика для:

  • Конфигурации опций, зависящих от места выполнения приложения (например, учетные данные базы данных

обычно отличаются в окружении производства и на вашей локальной машине); * Конфигурация опций, которые могут динамически изменяться в окружении производства (например. обновить значение просроченного ключа API без необходимости переразвертывания всего приложения).

В остальных случаях рекомендуется продолжать использовать параметры конфигурации .

Вы можете ссолаться на переменные окружения используя специальный синтаксис %env(ENV_VAR_NAME)%. Значения этих опций разрешаются во время выполнения (только единожды за запрос, чтобы не повлиять на производительность).

Этот пример показывает, как вы можете сконфигурировать соединение БД, используя переменную окружения:

1
2
3
4
5
6
# config/packages/doctrine.yaml
doctrine:
    dbal:
        # по соглашению имена переменных окружений всегда используют верхний регистр
        url: '%env(resolve:DATABASE_URL)%'
    # ...

Note

К вашим переменным окружения также можно получить доступ через супер-глобальные PHP $_ENV и $_SERVER (оба эквивалентны):

1
2
$databaseUrl = $_ENV['DATABASE_URL']; // mysql://db_user:db_password@127.0.0.1:3306/db_name
$env = $_SERVER['APP_ENV']; // prod

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

See also

Значения переменных окружения могут быть только строками, но Symfony включает некоторые процессоры env var, чтобы трансформировать их содержание (например, превратить значение строки в целое число).

Чтобы определить значение любой переменной окружения, у вас есть несколько вариантов:

  • Добавить значение к файлу .env ;
  • Зашифровать значение как секрет ;
  • Установить значение как реальную переменную окружения в вашей оболочке или веб-сервере.

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

1
2
3
4
5
6
# config/packages/framework.yaml
parameters:
    # если значение переменной окружения SECRET нигде не определено, Symfony использует это значение
    env(SECRET): 'some_secret'

# ...

Tip

Некоторые хосты - как SymfonyCloud - предлагают простые в производстве утилиты для работы с env var

Note

Некоторые функции конфигурации не совместимы с переменными окружения. Например, опрределение некоторых параметров контейнера с условиями, основанными на существовании другой опции конфигурации. При использовании переменной окружения, опция конфигурации существует всегда, так как её значение будет null, если связанная переменная окружения не определена.

Danger

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

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

Конфигурация переменных окружения в файлах .env

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

Файл .env читается и анализируется при каждом запросе и его переменные окружения добавляются к PHP-переменным $_ENV & $_SERVER. Все существующие переменные окружения никогда не переопределяются значениями, определенными в .env, поэтому вы можете их комбинировать.

Например, чтобы определить переменные окружения DATABASE_URL, показанные ранее в этой статье, вы можете добавить:

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

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

В дополнение к вашим собственным переменным окружения, этот файл .env также содержит переменные окружения, определенные сторонними пакетами, установленными в вашем приложении (они автоматически добавляются Symfony Flex при установке пакетов).

Tip

Так как файл .env читается и анализируется по каждому запросу, вам не нужно очищать кеш Symfony или перезапускать PHP-контейнер, если вы используете Docker.

Синтаксис файла .env

Добавляйте комментарии с префиксом #:

1
2
3
# database credentials
DB_USER=root
DB_PASS=pass # это секретный пароль

Используйте переменные окружения в значениях, добавляя к ним префикс $:

1
2
DB_USER=root
DB_PASS=${DB_USER}pass # добавьте пользователя в качестве префикса пароля

Caution

Порядок важен, когда некоторые из переменных окружения зависят от значения других переменных окружения. В примере выше, DB_PASS должен быть определен после DB_USER. Более того, если вы определите несколько файлов .env и первым поставите DB_PASS, его значение будет зависеть от значения DB_USER, определенного в других файлах, вместо значения, определенного в этом файле.

Определите значение по умолчанию в случае, если переменная окружения не установлена:

1
2
DB_USER=
DB_PASS=${DB_USER:-root}pass # приводит к DB_PASS=rootpass

Встройте команды через $() (не поддерживается в Windows):

1
START_TIME=$(date)

Caution

Использование $() может не работать в зависимости от вашей оболочки.

Tip

Так как файл .env - обычный скрипт оболочки, вы можете source его в ваших собственных скриптах оболочки:

1
$ source .env

Переопределение значений окружения через .env.local

Если вам нужно переопределить значение окружения (например, на другое значение на вашей локальной машине), вы можете сделать то в файле .env.local:

1
2
# .env.local
DATABASE_URL="mysql://root:@127.0.0.1:3306/my_database_name"

Этот файл должен быть проигнорирован git и не должен быть отправлен в ваше хранилище. Несколько других файлов .env доступня для установки переменных окружения только в правильных ситуациях:

  • .env: определяет значения по умолчанию для переменных окружения, которые нужны приложению;
  • .env.local: переопределяет значения по умолчанию для всех окружений, но только на машине, содержащей этот файл. Этот файл не должен быть отправлен в хранилище, и он игнорируется в окружении test (так как тесты должны производить одинаковые результаты для всех);
  • .env.<environment> (напиример, .env.test): пеоепределяет переменные окружения только для одного окружения, но для всех машин (эти файлы отправляются);
  • .env.<environment>.local (напиример, .env.test.local): опрелеяет переменные окружения, относящиеся к конкретной машине, пеоеопределяя их только для одного окружения. Похоже на .env.local, но переопределения применяются только к одному окружению.

Настоящие переменные окружения всегда выигрывают у тех, которые созданы любым файлом .env. Обратите внимание, что это поведение зависит от конфигурации
variables_order,
которая должна содержать E для раскрытия суперглобального значения $_ENV. Это конфигурация по умолчанию в PHP.

Файлы .env и .env.<environment> не должны быть отправлены в хранилище, так как они одинаковы для всех разработчиков и машин. Однако, файлы env, заканчивающиеся на .local (.env.local и .env.<environment>.local) не должны быть отправлены, так как их будете использовать только вы. На самом деле, файл .gitignore, который поставляется с Symfony, предотвращает их от отправки.

Переопределение переменных окружения, определенных системой

Если вам нужно переопределить переменную окружения, определенную системой, используйте параметр
overrideExistingVars параметр, определенный в методах loadEnv(), bootEnv(), и populate() :

1
2
3
4
5
6
use Symfony\Component\Dotenv\Dotenv;

$dotenv = new Dotenv();
$dotenv->loadEnv(__DIR__.'/.env', overrideExistingVars: true);

// ...

Это переопределит переменные окружения, определенные системой, но не будет
переопределять переменные окружения, определенные в файлах .env.

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

В производстве, файлы .env также анализируются и загружаются по каждому запросу. Поэтому самый простой способ определить переменные окружения - развернуть файл .env.local на вашем производственном сервере(ах) с вашими значениями производства.

Для улучшения производительности, вы можете по желанию выполнить команду dump-env (доступна в Symfony Flex 1.2 и позже):

1
2
# анализирует ВСЕ файлы .env и сбрасывает их финальные значения в .env.local.php
$ composer dump-env prod

Если у вас не установлен Composer в производстве, вы можете использовать команду
dotenv:dump вместо этого (доступно в Symfony Flex 1.2 или более поздней версии). По умолчанию команда не зарегистрирована, поэтому вы должны зарегистрировать сначала в ваших сервисах:

1
2
3
# config/services.yaml
services:
    Symfony\Component\Dotenv\Command\DotenvDumpCommand: ~

Затем, выполните команду:

1
2
# анализирует ВСЕ файлы .env и скидывает их финальные значения в .env.local.php
$ APP_ENV=prod APP_DEBUG=0 php bin/console dotenv:dump

После выполнения этой команды, Symfony загрузит файл .env.local.php, чтобы получить пременные окружения и не будет тратить время, анализируя файлы .env.

Tip

Обновите свои инструменты развертывания/рабочего процесса, чтобы выполнять команду dump-env после каждого рвазвертывания, чтобы улучшить производительность приложения.

Хранение переменных окружения в других файлах

По умолчанию переменные окружения хранятся в файле .env, расположенном
в корне вашего проекта. Однако вы можете хранить их в других файлах различными способами.

Если вы используете компонентRuntime, путь dotenv является частью опций, которые вы можете задать в файле composer.json:

1
2
3
4
5
6
7
8
9
{
    // ...
    "extra": {
        // ...
        "runtime": {
            "dotenv_path": "my/custom/path/to/.env"
        }
    }
}

Вы также можете установить переменную окружения SYMFONY_DOTENV_PATH на системном
уровне (например, в конфигурации веб-сервера или в Dockerfile):

1
2
# .env (or .env.local)
SYMFONY_DOTENV_PATH=my/custom/path/to/.env

Наконец, вы можете напрямую вызвать класс Dotenv в вашем
bootstrap.php или любом другом файле вашего приложения:

1
2
3
use Symfony\Component\Dotenv\Dotenv;

(new Dotenv())->bootEnv(dirname(__DIR__).'my/custom/path/to/.env');

Symfony будет искать переменные окружения в этом файле, а также в
локальных и специфических для окружения файлах (например, .*.local и .*.<environment>.local). Читайте как переопределить переменные окружения , чтобы узнать больше об этом.

7.1

Переменная окружения SYMFONY_DOTENV_PATH была представлена в Symfony 7.1.

Шифрование переменных окружения (секреты)

Вместо определения реальной переменной окружения или ее добавления в файл .env, если значение переменной чувствительно (например, ключ API или пароль БД), вы можете зашифровать значение, используя систему управления секретами.

Перечень переменных окружения

Используйте команду debug:dotenv, чтобы понимать, как Symfony анализирует разные файлы .env, чтобы установить значение каждой переменной окружения:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ php bin/console debug:dotenv

Dotenv переменные & файлы
=========================

Просканированные файлы (в порядке снижения приоритета)
------------------------------------------------------

* ⨯ .env.local.php
* ⨯ .env.dev.local
* ✓ .env.dev
* ⨯ .env.local
* ✓ .env

Переменные
----------

------------ ---------- ---------- ------
 Переменная   Значение   .env.dev   .env
------------ ---------- ---------- ------
 FOO          BAR        n/a        BAR
 ALICE        BOB        BOB        bob
------------ ---------- ---------- ------

# искать конкретную переменную, передавая её полное или частичное имя в качестве аргумента
$ php bin/console debug:dotenv foo

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ php bin/console debug:container --env-vars

------------ ----------------- ------------------------------------ -------------
 Name         Default value     Real value                           Usage count
------------ ----------------- ------------------------------------ -------------
 APP_SECRET   n/a               "471a62e2d601a8952deb186e44186cb3"   2
 BAR          n/a               n/a                                  1
 BAZ          n/a               "value"                              0
 FOO          "[1, "2.5", 3]"   n/a                                  1
------------ ----------------- ------------------------------------ -------------

# вы также можете отфильтровать список env vars по имени:
$ php bin/console debug:container --env-vars foo

# выполните эту команду, чтобы показать все детали для конкретного env var:
$ php bin/console debug:container --env-var=FOO

Создание собственной логики загрузки переменных окружения

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

реализует EnvVarLoaderInterface.

Note

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

Допустим, у вас есть JSON-файл с именем env.json, содержащий ваши переменные окружения:

1
2
3
4
5
6
{
    "vars": {
        "APP_ENV": "prod",
        "APP_DEBUG": false
    }
}

Вы можете определить класс, подобный следующему JsonEnvVarLoader, чтобы заполнить
переменные окружения из файла:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace App\DependencyInjection;

use Symfony\Component\DependencyInjection\EnvVarLoaderInterface;

final class JsonEnvVarLoader implements EnvVarLoaderInterface
{
    private const ENV_VARS_FILE = 'env.json';

    public function loadEnvVars(): array
    {
        $fileName = __DIR__.\DIRECTORY_SEPARATOR.self::ENV_VARS_FILE;
        if (!is_file($fileName)) {
            // вызвать исключение или просто проигнорировать этот загрузчик, в зависимости от ваших потребностей
        }

        $content = json_decode(file_get_contents($fileName), true);

        return $content['vars'];
    }
}

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

Tip

Если вы хотите, чтобы переменная окружения имела значение в определенном окружении, но возвращалась к загрузчикам в другом окружении, присвойте пустое значение переменной окружения для окружения, в котором вы хотите использовать загрузчики:

1
2
3
4
5
# .env (или .env.local)
APP_ENV=prod

# .env.prod (или .env.prod.local) - вернется к загрузчикам, которые вы определили
APP_ENV=

Доступ к параметрам конфигурации

Контроллеры и сервисы могут получить доступ ко всем параметрам конфигурации. Это включает в себя как параметры, определенные вами defined by yourself , так и параметры, созданные пакетами. Выполните следующую команду, чтобы увидеть все параметры, существующие в вашем приложении:

1
$ php bin/console debug:container --parameters

В контроллерах, расщиряющихся из AbstractController , используйте хелпер getParameter():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/Controller/UserController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class UserController extends AbstractController
{
    // ...

    public function index(): Response
    {
        $projectDir = $this->getParameter('kernel.project_dir');
        $adminEmail = $this->getParameter('app.admin_email');

        // ...
    }
}

В сервисах и контроллерах, не расширяющихся из AbstractController, внедрите параметры в качестве аргументов их конструкторов. Вы должены внедрить их ясно, потому что автомонтирование сервисов не работает для параметров:

1
2
3
4
5
6
7
8
# config/services.yaml
parameters:
    app.contents_dir: '...'

services:
    App\Service\MessageGenerator:
        arguments:
            $contentsDir: '%app.contents_dir%'

Если вы будете внедрять одни и те же параметры снова и снова, используйте вместо этого опцию services._defaults.bind. Аргументы, определенные в этой опции, внедряются автоматически каждый раз, когда конструктор сервиса или действие контроллера определяет аргумент с точно таким же именем. Например, чтобы внедрять значение параметра kernel.project_dir , каждый раз, когда сервис/контроллер определяет аргумент $projectDir, используйте это:

1
2
3
4
5
6
7
8
9
# config/services.yaml
services:
    _defaults:
        bind:
            # передайте это значение любому аргументу $projectDir для любого сервиса,
            # созданного в этом файле (включая аргументы контроллера)
            $projectDir: '%kernel.project_dir%'

    # ...

See also

Прочтите статью об объединении аргументов по имени и/или типу , чтобы узнать больше об этой мощной функции.

Наконец, если какому-то сервису нужен доступ ко множеству параметров, вместо внедрения каждого из них отдельно, вы можете внедрить все параметры приложения одномоментно добавив подсказки при вводе кода к любому из аргументов конструктора с ContainerBagInterface:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// src/Service/MessageGenerator.php
namespace App\Service;

// ...

use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;

class MessageGenerator
{
    public function __construct(
        private ContainerBagInterface $params,
    ) {
    }

    public function someMethod(): void
    {
        // получите любой параметр контейнера из $this->params, который хранит их все
        $sender = $this->params->get('mailer_sender');
        // ...
    }
}

Использование PHP ConfigBuilders

Написание PHP-конфигурации иногда бывает сложным, потому что у вас получаются большие вложенные массивы, и у вас нет помощи в автозаполнении из вашего любимого IDE. Это можно решить с помощью "ConfigBuilders". Это объекты, которые помогут вам строить эти массивы.

Symfony генерирует классы ConfigBuilder автоматически в каталоге компоновки ядра для всех пакетов, установленных в вашем приложении. По соглашению, они все живут в пространстве имен Symfony\Config:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// config/packages/security.php
use Symfony\Config\SecurityConfig;

return static function (SecurityConfig $security): void {
    $security->firewall('main')
        ->pattern('^/*')
        ->lazy(true)
        ->security(false);

    $security
        ->roleHierarchy('ROLE_ADMIN', ['ROLE_USER'])
        ->roleHierarchy('ROLE_SUPER_ADMIN', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'])
        ->accessControl()
            ->path('^/user')
            ->roles('ROLE_USER');

    $security->accessControl(['path' => '^/admin', 'roles' => 'ROLE_ADMIN']);
};

Note

Только корневые классы в пространстве имен Symfony\Config являются ConfigBuilders. Вложенные конфигурации (например, \Symfony\Config\Framework\CacheConfig) являются обычными PHP-объектами, которые не внедряются автоматически во время их использования в качестве типа аргумента.

Note

Чтобы получить автозаполнение ConfigBuilders в вашем IDE/редакторе, убедитесь, что не исключили каталог, в котором генерируются эти классы (по умолчанию, в var/cache/dev/Symfony/Config/).

Не останавливайтесь!

Поздравляем ! Вы справились с основами Symfony. Далее, узнайте о каждой части Symfony отдельно, cледуя руководствами. Посмотрите:

И все другие темы, связанные с конфигурацией: