cloud-castle / config
Неизменяемая конфигурация для PHP 8.1+: точечный доступ и типизированное чтение, загрузка JSON/XML/YAML/NEON/INI/.env/.properties безопасными парсерами, профили окружений, подстановки %ключ% и %env()%, проверка по схеме, компиляция в PHP-кэш и маскирование секретов.
Requires
- php: >=8.1
- cloud-castle/env: ^1.1
- cloud-castle/file-system: ^1.1
- cloud-castle/parser-json: ^1.0
- cloud-castle/parser-neon: ^1.0
- cloud-castle/parser-xml: ^1.0
- cloud-castle/parser-yaml: ^1.0
- cloud-castle/validator: ^1.1
- psr/container: ^1.1 || ^2.0
Requires (Dev)
- adbario/php-dot-notation: ^3.3
- deptrac/deptrac: ^3.0 || ^4.0
- dflydev/dot-access-data: ^3.0
- ergebnis/composer-normalize: ^2.45
- friendsofphp/php-cs-fixer: ^3.75
- hassankhan/config: ^3.1
- icanhazstring/composer-unused: ^0.9
- illuminate/config: ^10.0 || ^11.0
- infection/infection: ^0.29 || ^0.33
- php-parallel-lint/php-parallel-lint: ^1.4
- phpmd/phpmd: ^2.15
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^1.12 || ^2.1
- phpstan/phpstan-deprecation-rules: ^1.2 || ^2.0
- phpstan/phpstan-phpunit: ^1.4 || ^2.0
- phpstan/phpstan-strict-rules: ^1.6 || ^2.0
- phpunit/phpunit: ^10.5 || ^11.5
- psalm/plugin-phpunit: ^0.19 || ^0.20
- rector/rector: ^1.2 || ^2.0
- roave/security-advisories: dev-latest
- selective/config: ^1.1
- squizlabs/php_codesniffer: ^3.12 || ^4.0
- symfony/property-access: ^6.4 || ^7.0
- vimeo/psalm: ^6.0
- webmozart/assert: ^1.11
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-14 21:54:30 UTC
README
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano
CloudCastle Config
Неизменяемая конфигурация для PHP 8.1+: точечный доступ (
db.connections.default), типизированное чтение, загрузка из JSON/XML/YAML/NEON/INI/.env/.properties безопасными парсерамиcloud-castle/parser-*, профили окружений, подстановки%ключ%и%env(int:PORT|5432)%, проверка по схеме, компиляция в PHP-кэш и маскирование секретов в логах.
Установка
composer require cloud-castle/config
Требуется PHP 8.1+. Пакет опирается только на инфраструктуру cloud-castle/*,
PSR-интерфейсы и штатные расширения PHP.
Быстрый старт
<?php
use CloudCastle\Config\Config;
use CloudCastle\Config\ConfigBuilder;
use CloudCastle\Config\ConfigLoader;
use CloudCastle\Config\Schema\Schema;
use CloudCastle\Config\Source\DirectoryMode;
// 1. Точечный доступ и типизированное чтение.
$config = new Config([
'app' => ['name' => 'Demo', 'debug' => true],
'db' => ['host' => 'localhost', 'port' => '5432'],
]);
$config->get('db.host'); // 'localhost'
$config->requireInt('db.port'); // 5432 — строка из файла приведена к числу
$config->getBool('app.debug'); // true
// 2. Загрузка из файла или каталога.
$fromFile = ConfigLoader::fromFile('/etc/app/database.yaml');
$fromDirectory = ConfigLoader::fromDirectory('/etc/app/config', DirectoryMode::BranchRecursive);
// 3. Полная сборка: умолчания, каталог, окружение, подстановки, схема и кэш.
$config = ConfigBuilder::create()
->addArray(['app' => ['name' => 'Demo']])
->addDirectory('/etc/app/config')
->forEnvironment('prod') // app.prod.yaml поверх app.yaml
->interpolate() // %app.name%, %env(int:DB_PORT|5432)%
->withSensitive('db.*.password') // секреты не попадут в логи
->validate(Schema::make(['db.port' => 'required|integer']))
->cache('/var/cache/app/config.php') // один require вместо разбора YAML
->build();
Возможности
| Возможность | Страница |
|---|---|
Точечный доступ, require(), экранирование точки | dot-access |
| Типизированное чтение и перечисления | typed-access |
| Неизменяемость и безопасное разделение конфигурации | immutability |
| Слияние источников и стратегии списков | merging |
| Восемь форматов и свои загрузчики | formats |
| Источники: массив, строка, файл, каталог, glob | sources |
| Профили окружений | environments |
Подстановки %ключ% и %env(...)% | interpolation |
| Проверка по схеме | schema |
| Компиляция в PHP-кэш | cache |
| Маскирование секретов | secrets |
Выборки, срезы, diff | selection |
| Сохранение конфигурации в файл | writing |
| Адаптер PSR-11 | psr11 |
Сравнение с аналогами
Все таблицы ниже сгенерированы автоматически из честных сравнительных прогонов (benchmarks/compare.php, benchmarks/quality.php) на одинаковых операциях и
одинаковых правилах анализаторов для всех участников, без Xdebug.
PHP 8.1.34. Участники: cloud-castle/config v1.0.3, adbario/php-dot-notation 3.5.0, dflydev/dot-access-data v3.0.3, hassankhan/config 3.2.0, illuminate/config v10.49.0, selective/config 1.3.0, symfony/property-access v6.4.32.
1. Функциональность
| Возможность | CloudCastle | adbario | dflydev | hassankhan | illuminate | selective | symfony |
|---|---|---|---|---|---|---|---|
| Точечный доступ к значению (db.port) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Значение по умолчанию при отсутствии ключа | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Обязательные ключи с исключением (fail-loud) | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
| Типизированные геттеры (string/int/bool/array) | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
| Чтение перечислений (backed enum) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Изменение значения по точечному ключу | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| Добавление элементов в список конфигурации | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
| Неизменяемость: модификаторы дают новый объект | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
| ArrayAccess, Countable, Iterator, JsonSerializable | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Рекурсивное слияние источников | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| Стратегии слияния списков (replace/append/unique) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Загрузка JSON | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Загрузка XML | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Загрузка YAML | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Загрузка NEON | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Загрузка INI | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Загрузка .env | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Загрузка .properties | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Загрузка PHP-файлов по явному разрешению | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Каталог как источник конфигурации | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Glob-шаблон как источник конфигурации | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Профили окружений (app.prod.yaml поверх app.yaml) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Подстановка ссылок внутри конфигурации (%ключ%) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Подстановка переменных окружения с типами | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Проверка конфигурации по схеме | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Компиляция в PHP-кэш с автоинвалидацией | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Маскирование секретов при экспорте и в дампе | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Выборка по шаблону пути (db.*.host) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Плоское представление и обратная сборка | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Срезы конфигурации (only/except/поддерево) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Сравнение двух конфигураций (diff) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Сохранение конфигурации в файл | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Сериализация в JSON | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Адаптер PSR-11 | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Регистрация собственного формата | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Экранирование точки в имени ключа | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Всего | 🏆 36 | 8 | 6 | 13 | 4 | 5 | 2 |
2. Безопасность и корректность
| Свойство | CloudCastle | adbario | dflydev | hassankhan | illuminate | selective | symfony |
|---|---|---|---|---|---|---|---|
| Разбор источников не выполняет код | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ |
| Защита от XXE при разборе XML | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Отклонение объектов в YAML/NEON | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Ограничение размера файла конфигурации | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Fail-loud на отсутствующем обязательном ключе | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
| Неизменяемость: общий конфиг нельзя мутировать | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
| Исключения не раскрывают значения | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Маскирование секретов в JSON и var_dump | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Проверка конфигурации по схеме до запуска | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Кэш конфигурации с правами 0600 | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Всего | 🏆 10 | 1 | 1 | 0 | 1 | 3 | 1 |
3. Качество кода
замечания анализаторов на 1000 строк кода (меньше — лучше) и доля файлов со строгой типизацией (больше — лучше); ко всем участникам применяются одинаковые правила.
| Метрика | CloudCastle | adbario | dflydev | hassankhan | illuminate | selective | symfony | 🏆 Победитель |
|---|---|---|---|---|---|---|---|---|
| Ошибок синтаксиса на 1000 строк | 0,0 | 0,0 | 0,0 | 0,0 | 0,0 | 0,0 | 0,0 | ничья |
| Нарушений PSR-12 на 1000 строк | 0,0 | 0,0 | 8,1 | 18,4 | 0,0 | 0,0 | 45,3 | ничья |
| Запахов кода на 1000 строк | 0,0 | 11,7 | 4,0 | 14,6 | 0,0 | 3,6 | 20,3 | ничья |
| Ошибок PHPStan (max) на 1000 строк | 0,0 | 48,7 | 30,2 | 119,8 | 114,6 | 32,3 | 66,8 | 🏆 CloudCastle |
| Файлов с устаревшими конструкциями на 1000 строк | 0,0 | 3,4 | 8,1 | 16,5 | 6,4 | 3,6 | 9,9 | 🏆 CloudCastle |
| Известных уязвимостей пакета | 0,0 | 0,0 | 0,0 | 0,0 | 0,0 | 0,0 | 0,0 | ничья |
| Файлов со строгой типизацией, % | 100,0 | 0,0 | 100,0 | 0,0 | 0,0 | 0,0 | 0,0 | ничья |
| Сигнатур с типом возврата, % | 100,0 | 23,3 | 75,0 | 0,0 | 36,4 | 53,3 | 80,5 | 🏆 CloudCastle |
| Побед по метрикам | 🏆 8 | 3 | 3 | 2 | 4 | 3 | 2 |
4. Производительность: создание конфигурации и чтение
обёртка конфигурации + чтение двух вложенных значений, 100 000 раз (минимум из 4).
| Решение | Значение (мс) | 🏆 Победитель |
|---|---|---|
| 🏆 CloudCastle | 69 | лучший результат |
| selective | 76,6 | аналог |
| hassankhan | 85,1 | аналог |
| dflydev | 97,7 | аналог |
| adbario | 122,5 | аналог |
| illuminate | 133,1 | аналог |
| symfony | 270,2 | аналог |
5. Производительность: чтение из готовой конфигурации
чтение двух вложенных значений из готовой обёртки, 200 000 раз (минимум из 4).
| Решение | Значение (мс) | 🏆 Победитель |
|---|---|---|
| 🏆 CloudCastle | 33,5 | лучший результат |
| hassankhan | 39,6 | аналог |
| selective | 142,8 | аналог |
| dflydev | 176,3 | аналог |
| adbario | 215,5 | аналог |
| illuminate | 256 | аналог |
| symfony | 555,9 | аналог |
6. Память: одна конфигурация приложения
память одной конфигурации из 1 000 ветвей — типичный для приложения сценарий (изолированный процесс).
| Решение | Значение (байт) | 🏆 Победитель |
|---|---|---|
| 🏆 symfony | 0 | лучший результат |
| dflydev | 56 | аналог |
| illuminate | 56 | аналог |
| selective | 56 | аналог |
| adbario | 80 | аналог |
| hassankhan | 80 | аналог |
| CloudCastle | 112 | аналог |
7. Память: сто тысяч конфигураций (синтетический предел)
фактическая память при удержании 100 000 обёрток конфигурации (изолированный процесс).
| Решение | Значение (KB) | 🏆 Победитель |
|---|---|---|
| 🏆 symfony | 4 100 | лучший результат |
| selective | 10 606 | аналог |
| illuminate | 10 608 | аналог |
| dflydev | 10 615 | аналог |
| hassankhan | 12 929 | аналог |
| adbario | 12 976 | аналог |
| CloudCastle | 16 156 | аналог |
8. Утечки памяти
рост памяти после 200 000 чтений из одной обёртки (изолированный процесс, после прогрева).
| Решение | Значение (байт) | 🏆 Победитель |
|---|---|---|
| 🏆 CloudCastle | 0 | лучший результат |
| 🏆 adbario | 0 | лучший результат |
| 🏆 dflydev | 0 | лучший результат |
| 🏆 hassankhan | 0 | лучший результат |
| 🏆 illuminate | 0 | лучший результат |
| 🏆 selective | 0 | лучший результат |
| 🏆 symfony | 0 | лучший результат |
Коротко о плюсах и минусах
Сильные стороны:
- Функционал — объединение возможностей аналогов. Точечный доступ, типизированное чтение, неизменяемость, восемь форматов, каталоги и glob, профили окружений, подстановки, схема, кэш, маскирование секретов, выборки и PSR-11 — в одном пакете.
- Скорость. Быстрее всех сравниваемых решений и при создании конфигурации, и при чтении из готовой: разобранные пути кэшируются между экземплярами, а значения — внутри экземпляра, когда он начинает работать как долгоживущий.
- Безопасность. Разбор без выполнения кода, защита от XXE, ограничение размера
файла, fail-loud на отсутствующем ключе, исключения без раскрытия значений,
маскирование секретов в JSON и
var_dump(), кэш с правами0600. - Качество кода. PHPStan max, Psalm errorLevel 1, PHPMD, PHPCS, Rector и Deptrac — без ошибок; покрытие тестами 100%, мутационный MSI 100% (все мутанты убиты).
- Без утечек памяти. Кэши ограничены по размеру: перебор произвольных ключей не приводит к неограниченному росту (подтверждено сравнительным тестом утечек).
Слабые стороны (честно):
- Память на экземпляр. Обёртка занимает 112 байт против 56 у минималистичных dot-контейнеров: это цена кэшей и пометок секретов. На типичное приложение с единственной конфигурацией разница неощутима, но в синтетическом сценарии со 100 000 одновременных обёрток пакет проигрывает — сознательный компромисс ради скорости и функционала.
- Возраст и распространённость. Пакет моложе
illuminate/configиhassankhan/config, у него меньше звёзд и установок, а значит — меньше готовых рецептов в интернете.
Когда применять
- Приложение с несколькими окружениями и разными форматами конфигурации — основной
сценарий: каталог с YAML/JSON/INI, наложение
*.prod.yaml, подстановка секретов из окружения, проверка по схеме на старте и компиляция в кэш для production. - Долгоживущие процессы (RoadRunner, Swoole, воркеры очередей) — неизменяемость исключает случайную мутацию общей конфигурации, а мемоизация окупается на каждом обращении.
- Сервисы, где конфигурация попадает в логи и трассировки (финтех, обработка
персональных данных) — пометьте пути секретов, и они не утекут ни в JSON, ни в
var_dump(), ни в текст исключения. - Конфигурация из недоверенного источника (смонтированный том, ConfigMap, пользовательский профиль) — безопасные парсеры, лимит размера файла и запрет PHP-формата по умолчанию.
- Когда нужен только dot-доступ к массиву в памяти — возьмите
adbario/php-dot-notationилиdflydev/dot-access-data: они меньше по объёму кода и дешевле по памяти. - Приложение на Laravel — там уже есть
illuminate/config, интегрированный с каркасом; этот пакет полезен как отдельный слой в пакетах и модулях вне Laravel.
Разработка
composer install
composer check # линтеры + статический анализ + тесты
composer fix # автоисправления (Rector, PHP CS Fixer, PHPCBF)
composer ci # полный CI-пайплайн локально
composer test:mutation # мутационное тестирование (MSI 100%)
composer docs:sync # пересборка сравнительных таблиц и wiki
Полный список команд с описаниями: composer run-script --list.
Документация
- Возможности по страницам: wiki/docs/ru/Features.md
- Сравнение с аналогами: wiki/docs/ru/Comparison.md
- Справочник API и руководство: https://cloud-castle.gitverse.page/config/
- Wiki проекта: https://gitverse.ru/cloud-castle/config/wiki
- Репозиторий: https://gitverse.ru/cloud-castle/config
- История изменений: CHANGELOG.md
- Переход с 1.x на 2.0: UPGRADING.md
- Как внести вклад: CONTRIBUTING.md
- Кодекс поведения: CODE_OF_CONDUCT.md
- Политика безопасности: SECURITY.md
Лицензия
MIT © CloudCastle (alex-4-17@yandex.ru)
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano