Переменные окружения
Встроенная поддержка dotenv с 3-уровневым приоритетом и приведением типов.
Содержание
Обзор
Wirebox имеет встроенный парсер .env — внешние пакеты вроде vlucas/phpdotenv или symfony/dotenv не нужны. Переменные окружения разрешаются с 3-уровневой системой приоритета.
Приоритет разрешения
Переменные разрешаются в порядке приоритета (от высшего к низшему):
| Приоритет | Источник | Описание |
|---|---|---|
| 1 (высший) | .env.local.php |
PHP-файл с массивом. Генерируется composer dump-env. Самый быстрый. |
| 2 | $_ENV / getenv() |
Реальные системные переменные окружения (Docker, CI и т.д.) |
| 3 (низший) | .env |
Парсится встроенным DotEnvParser. Фоллбэк для разработки. |
Все файлы ищутся относительно projectDir, переданного в ContainerBuilder.
Если переменная определена на нескольких уровнях, побеждает источник с высшим приоритетом. Например, системная переменная переопределяет .env, а .env.local.php переопределяет всё.
Файл .env
Создайте файл .env в корне проекта с настройками для разработки:
# Приложение
APP_NAME=Wirebox
APP_DEBUG=true
# База данных
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
# Секреты
SECRET_KEY=dev-secret-key-change-in-production
Поддерживаемый синтаксис
# Комментарии начинаются с #
APP_NAME=Wirebox
# Значения в кавычках (сохраняют пробелы)
GREETING="Hello World"
# Одинарные кавычки (литерал, без интерполяции)
PATTERN='${NOT_INTERPOLATED}'
# Интерполяция переменных (двойные кавычки или без кавычек)
BASE_PATH=/opt
FULL_PATH="${BASE_PATH}/app"
ALSO_WORKS=${BASE_PATH}/app
# Префикс export удаляется
export SECRET_KEY=abc123
# Пустые значения
EMPTY_VALUE=
Правила интерполяции
| Синтаксис | Поведение |
|---|---|
${VAR} в двойных кавычках |
Интерполируется |
${VAR} без кавычек |
Интерполируется |
${VAR} в одинарных кавычках |
Литерал (не интерполируется) |
Использование переменных окружения
Через атрибут #[Param]
Самый простой способ — инъекция прямо в параметры конструктора:
use AsceticSoft\Wirebox\Attribute\Param;
class AppConfig
{
public function __construct(
#[Param('APP_NAME')] private string $appName,
#[Param('APP_DEBUG')] private bool $debug,
#[Param('DB_PORT')] private int $port,
) {
}
}
Приведение типов происходит автоматически по type hint параметра.
Через parameter() билдера
Определение именованных параметров с env-выражениями:
$builder->parameter('db.host', '%env(DB_HOST)%');
$builder->parameter('db.port', '%env(int:DB_PORT)%');
$builder->parameter('app.debug', '%env(bool:APP_DEBUG)%');
Затем получение из контейнера:
$host = $container->getParameter('db.host');
$port = $container->getParameter('db.port'); // int
Приведение типов
В выражениях parameter()
Используйте префикс тип: внутри %env(...)%:
$builder->parameter('port', '%env(int:DB_PORT)%'); // int
$builder->parameter('rate', '%env(float:RATE_LIMIT)%'); // float
$builder->parameter('debug', '%env(bool:APP_DEBUG)%'); // bool
$builder->parameter('host', '%env(DB_HOST)%'); // string (по умолчанию)
| Тип | Выражение | Вход | Выход |
|---|---|---|---|
string |
%env(DB_HOST)% |
"localhost" |
"localhost" |
int |
%env(int:DB_PORT)% |
"5432" |
5432 |
float |
%env(float:RATE)% |
"1.5" |
1.5 |
bool |
%env(bool:DEBUG)% |
"true" |
true |
Правила приведения к bool
| Значение | Результат |
|---|---|
"true", "1", "yes", "on" |
true |
"false", "0", "no", "off", "" |
false |
Через атрибут #[Param]
Приведение типов по PHP type hint:
public function __construct(
#[Param('DB_PORT')] private int $port, // приведение к int
#[Param('RATE')] private float $rate, // приведение к float
#[Param('DEBUG')] private bool $debug, // приведение к bool
#[Param('HOST')] private string $host, // string (без приведения)
)
Встроенные выражения
Env-выражения можно встраивать в строки:
$builder->parameter('dsn', 'mysql:host=%env(DB_HOST)%;port=%env(DB_PORT)%');
// Результат: "mysql:host=localhost;port=5432"
$builder->parameter('redis.url', 'redis://%env(REDIS_HOST)%:%env(REDIS_PORT)%');
// Результат: "redis://127.0.0.1:6379"
Когда env-выражение встроено в строку, результат всегда строка — даже с префиксом приведения типа. Приведение работает только когда выражение — единственное значение параметра.
Продакшен: .env.local.php
Для продакшена избегайте парсинга .env файлов. Сгенерируйте кешированный PHP-массив:
# С помощью плагина Symfony для Composer
composer dump-env prod
Это создаст .env.local.php:
<?php
return [
'APP_NAME' => 'Wirebox',
'APP_DEBUG' => 'false',
'DB_HOST' => 'db.production.internal',
'DB_PORT' => '5432',
];
Поскольку это обычный PHP-массив, накладные расходы на парсинг нулевые — просто подключение файла.
Файл .env.local.php имеет наивысший приоритет. Он переопределяет и системные переменные, и .env. Это делает деплой предсказуемым — что сдампили, то и получите.
Порядок разрешения переменных
Вот как Wirebox разрешает переменную окружения:
Запрос: %env(int:DB_PORT)%
│
▼
.env.local.php существует?
│
┌────┴────┐
Да Нет
│ │
▼ ▼
Вернуть $_ENV / getenv()
значение содержит DB_PORT?
│
┌────┴────┐
Да Нет
│ │
▼ ▼
Вернуть Парсить .env
значение содержит DB_PORT?
│
┌────┴────┐
Да Нет
│ │
▼ ▼
Вернуть Выбросить
значение исключение
Лучшие практики
- Не коммитьте
.envс реальными секретами. Используйте.env.exampleкак шаблон:DB_HOST=localhost DB_PORT=5432 SECRET_KEY=change-me - Используйте
.env.local.phpв продакшене для нулевых накладных расходов:composer dump-env prod - Используйте системные переменные в Docker/CI:
ENV DB_HOST=db.internal ENV DB_PORT=5432 -
Приводите типы на границе — используйте префиксы
int:,float:,bool:для корректных типов с самого начала. - Держите
.envминимальным — только умолчания для разработки. Продакшен-конфигурация должна приходить из окружения или.env.local.php.