phpsoftbox / env
Environment variables loader for the PhpSoftBox framework
Requires
- php: ^8.5
- phpsoftbox/collection: ^1.0
- phpsoftbox/filter: ^1.0
- psr/simple-cache: ^3.0
Requires (Dev)
- phpsoftbox/cache: ^1.0
- phpsoftbox/cli-app: ^1.0
- phpsoftbox/cs-fixer: ^1.2.2
- phpunit/phpunit: ^13.3
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-29 11:52:39 UTC
README
Компонент для загрузки переменных окружения из .env файлов с поддержкой интерполяции,
валидации и опционального экспорта в $_ENV/$_SERVER.
Установка
composer require phpsoftbox/env
Быстрый старт
<?php declare(strict_types=1); use PhpSoftBox\Env\Environment; use PhpSoftBox\Env\EnvStorage; $env = Environment::create(__DIR__ . '/config/env') ->setEnvironment(null) // null => APP_ENV процесса, затем из .env, иначе dev ->setPrefix('APP_'); $variables = $env->load(); $dbHost = $variables->get('DB_HOST'); $dbPort = $variables->toInt('DB_PORT', 3306); $debug = $variables->toBool('APP_DEBUG', false); // Типизированный доступ к текущему EnvStorage. $debug = EnvStorage::value('APP_DEBUG')->bool(default: false); $port = EnvStorage::value('DB_PORT')->int(default: 3306);
Расположение и порядок чтения .env
Рекомендуем хранить env-файлы в отдельной папке, например config/env, и передавать её в
Environment::create(). Для каталога читаются только файлы в нём самом (подкаталоги не обходятся):
.env— базовые значения;.env.{env}— значения окружения, перекрывают.env.
Окружение определяется так: значение setEnvironment(), затем APP_ENV процесса ($_ENV, $_SERVER,
getenv()), затем APP_ENV из .env, иначе dev. Поэтому APP_ENV, заданный только в .env, тоже выбирает
файл .env.{env}.
Environment::createFromFile() читает указанный файл как есть, Environment::createFromPaths() — несколько
каталогов/файлов по порядку (последующие перекрывают предыдущие).
Обход подкаталогов включается явно. Скрытые каталоги, vendor и node_modules пропускаются, файлы вложенных
каталогов перекрывают файлы корня:
$env = Environment::create($baseDir . '/config/env') ->setRecursive(true);
Синтаксис .env
# Комментарий APP_NAME=demo # комментарий после значения (перед # нужен пробел) export APP_URL=https://demo.local local SECRET=only-here # не экспортируется в toGlobals()/toPutEnv() SINGLE='без $интерполяции' DOUBLE="строка\nс переводом" MULTI="первая строка вторая строка" KEY=-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----
- Значение в кавычках может занимать несколько строк; текст после закрывающей кавычки игнорируется.
Незакрытая кавычка приводит к
EnvExceptionс указанием файла и строки начала значения. - Escape-последовательности разбираются за один проход, поэтому
"C:\\new"даётC:\new, а"dir\\"корректно закрывается.- в двойных кавычках:
\\→\,\"→",\n,\r,\t→ управляющие символы,\$→$; - в одинарных кавычках:
\\→\,\'→'; - без кавычек: только
\$→$; - неизвестная последовательность (
\q) сохраняется как есть.
- в двойных кавычках:
Интерполяция
В значениях без кавычек и в двойных кавычках подставляются $NAME, ${NAME}, ${NAME:-default} (значение по
умолчанию, если переменная пуста или не задана) и ${NAME:+alt} (alt, если переменная не пуста). Доступны
переменные, объявленные выше в том же или предыдущих файлах, а также переменные процесса (если не выключено
includeGlobals(false)). Неизвестная переменная заменяется пустой строкой.
Ограничения:
- вложенные подстановки не поддерживаются:
${A:-${B}}читается до первой}— значение по умолчанию будет литералом${B, за которым следует}; default/altподставляются как текст, без интерполяции внутри; в двойных кавычках они не могут содержать"(такое выражение не считается подстановкой);- любой
$, за которым идёт имя, считается подстановкой:pa$$wordпревратится вpa$($word— пустая переменная). Для литерального$используйте\$(pa\$\$word) или одинарные кавычки ('pa$$word').
Переменные процесса и кеш
При includeGlobals(true) (по умолчанию) результат load()/safeLoad()/overload() содержит значения из файлов
и переменные процесса из $_ENV/$_SERVER. load() и safeLoad() отдают приоритет переменным процесса,
overload() — значениям из файлов.
Кеш (setCache()) хранит только значения из файлов. Переменные процесса и данные запроса (HTTP_* в $_SERVER)
в кеш и в хранилище env() не копируются, а читаются при каждой загрузке/обращении — поэтому заголовки одного
запроса не видны в следующих, а изменения окружения процесса видны сразу. Обратите внимание: подстановка
переменной процесса в .env (LOG_DIR=${HOME}/logs) выполняется при чтении файла, и результат кешируется.
Префикс
setPrefix('APP_') добавляет префикс только к ключам из env-файлов (DB_HOST → APP_DB_HOST), ключи уже с
префиксом не меняются. Переменные процесса (PATH, HOME, ...) остаются без префикса. При поиске
(get('DB_HOST'), env('DB_HOST')) ключ сначала ищется с префиксом, затем как есть.
Экспорт в глобальные массивы
По умолчанию библиотека не модифицирует $_ENV/$_SERVER. Экспорт выполняется явно:
$variables = $env->load(); $variables->toGlobals();
Валидация
<?php use PhpSoftBox\Env\Environment; use PhpSoftBox\Env\EnvTypeEnum; use PhpSoftBox\Env\Validator\RequiredValidator; use PhpSoftBox\Env\Validator\TypeValidator; $env = Environment::create(__DIR__) ->validate(new RequiredValidator(['DB_HOST', 'DB_NAME'])) ->validate(new TypeValidator([ 'DB_PORT' => EnvTypeEnum::INT, 'DEBUG' => EnvTypeEnum::BOOL, ])); $variables = $env->load();
Хелпер env()
Хелпер env() читает значения из хранилища (значения из файлов) и из переменных процесса ($_ENV, $_SERVER,
getenv()). Хранилище автоматически заполняется при load()/safeLoad()/overload(). После load()/safeLoad()
с globals переменная процесса перекрывает значение из файла; после overload() или с includeGlobals(false)
приоритет у файла, а переменные процесса используются для отсутствующих ключей.
$variables = $env->load(); $dbHost = env('DB_HOST', 'localhost');
env() и EnvStorage::get() продолжают возвращать исходное значение. Для фильтрации и строгого
преобразования используйте EnvStorage::value(), возвращающий EnvValue:
use PhpSoftBox\Env\EnvStorage; use PhpSoftBox\Filter\LowercaseFilter; $environment = EnvStorage::value('APP_ENV', 'dev') ->filtered(new LowercaseFilter()) ->enum(ApplicationEnvironment::class, ApplicationEnvironment::DEV);
Доступны string(), int(), float(), bool(), array(), enum(), filter(), through() и
filtered(). Базовые преобразования делегируются компоненту phpsoftbox/filter.
array() принимает JSON (["a","b"], {"k":"v"}), список в скобках без кавычек ([a, b]), список через запятую
(a, b) и одиночное значение (a → ['a']). Элементы обрезаются, пустые отбрасываются; некорректный JSON-объект
({...}) возвращает значение по умолчанию.