Search by

Неизменяемая конфигурация для PHP 8.1+: точечный доступ и типизированное чтение, загрузка JSON/XML/YAML/NEON/INI/.env/.properties безопасными парсерами, профили окружений, подстановки %ключ% и %env()%, проверка по схеме, компиляция в PHP-кэш и маскирование секретов.

v2.0.0 2026-09-14 19:03 UTC

README

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano

CloudCastle Config

CloudCastle Config

Packagist PHP License Downloads Monthly Stars Dependents Suggesters Advisories

Quality Docs Publish Repository Issues Release Wiki Pages

PHPStan Psalm PHPMD PHPCS Coverage Infection MSI Security audit OpenSSF Scorecard

Неизменяемая конфигурация для 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
Источники: массив, строка, файл, каталог, globsources
Профили окруженийenvironments
Подстановки %ключ% и %env(...)%interpolation
Проверка по схемеschema
Компиляция в PHP-кэшcache
Маскирование секретовsecrets
Выборки, срезы, diffselection
Сохранение конфигурации в файлwriting
Адаптер PSR-11psr11

Сравнение с аналогами

Все таблицы ниже сгенерированы автоматически из честных сравнительных прогонов (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. Функциональность

ВозможностьCloudCastleadbariodflydevhassankhanilluminateselectivesymfony
Точечный доступ к значению (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
Регистрация собственного формата
Экранирование точки в имени ключа
Всего🏆 368613452

2. Безопасность и корректность

СвойствоCloudCastleadbariodflydevhassankhanilluminateselectivesymfony
Разбор источников не выполняет код
Защита от XXE при разборе XML
Отклонение объектов в YAML/NEON
Ограничение размера файла конфигурации
Fail-loud на отсутствующем обязательном ключе
Неизменяемость: общий конфиг нельзя мутировать
Исключения не раскрывают значения
Маскирование секретов в JSON и var_dump
Проверка конфигурации по схеме до запуска
Кэш конфигурации с правами 0600
Всего🏆 10110131

3. Качество кода

замечания анализаторов на 1000 строк кода (меньше — лучше) и доля файлов со строгой типизацией (больше — лучше); ко всем участникам применяются одинаковые правила.

МетрикаCloudCastleadbariodflydevhassankhanilluminateselectivesymfony🏆 Победитель
Ошибок синтаксиса на 1000 строк0,00,00,00,00,00,00,0ничья
Нарушений PSR-12 на 1000 строк0,00,08,118,40,00,045,3ничья
Запахов кода на 1000 строк0,011,74,014,60,03,620,3ничья
Ошибок PHPStan (max) на 1000 строк0,048,730,2119,8114,632,366,8🏆 CloudCastle
Файлов с устаревшими конструкциями на 1000 строк0,03,48,116,56,43,69,9🏆 CloudCastle
Известных уязвимостей пакета0,00,00,00,00,00,00,0ничья
Файлов со строгой типизацией, %100,00,0100,00,00,00,00,0ничья
Сигнатур с типом возврата, %100,023,375,00,036,453,380,5🏆 CloudCastle
Побед по метрикам🏆 8332432

4. Производительность: создание конфигурации и чтение

обёртка конфигурации + чтение двух вложенных значений, 100 000 раз (минимум из 4).

РешениеЗначение (мс)🏆 Победитель
🏆 CloudCastle69лучший результат
selective76,6аналог
hassankhan85,1аналог
dflydev97,7аналог
adbario122,5аналог
illuminate133,1аналог
symfony270,2аналог

5. Производительность: чтение из готовой конфигурации

чтение двух вложенных значений из готовой обёртки, 200 000 раз (минимум из 4).

РешениеЗначение (мс)🏆 Победитель
🏆 CloudCastle33,5лучший результат
hassankhan39,6аналог
selective142,8аналог
dflydev176,3аналог
adbario215,5аналог
illuminate256аналог
symfony555,9аналог

6. Память: одна конфигурация приложения

память одной конфигурации из 1 000 ветвей — типичный для приложения сценарий (изолированный процесс).

РешениеЗначение (байт)🏆 Победитель
🏆 symfony0лучший результат
dflydev56аналог
illuminate56аналог
selective56аналог
adbario80аналог
hassankhan80аналог
CloudCastle112аналог

7. Память: сто тысяч конфигураций (синтетический предел)

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

РешениеЗначение (KB)🏆 Победитель
🏆 symfony4 100лучший результат
selective10 606аналог
illuminate10 608аналог
dflydev10 615аналог
hassankhan12 929аналог
adbario12 976аналог
CloudCastle16 156аналог

8. Утечки памяти

рост памяти после 200 000 чтений из одной обёртки (изолированный процесс, после прогрева).

РешениеЗначение (байт)🏆 Победитель
🏆 CloudCastle0лучший результат
🏆 adbario0лучший результат
🏆 dflydev0лучший результат
🏆 hassankhan0лучший результат
🏆 illuminate0лучший результат
🏆 selective0лучший результат
🏆 symfony0лучший результат

Коротко о плюсах и минусах

Сильные стороны:

  • Функционал — объединение возможностей аналогов. Точечный доступ, типизированное чтение, неизменяемость, восемь форматов, каталоги и 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.

Документация

Лицензия

MIT © CloudCastle (alex-4-17@yandex.ru)

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano