11. Config
На кроках 1–10 значення (APP_DEBUG, MySQL, рівень логів, masking)
жили в getenv() і літералах у
ApplicationStackBootstrap — навмисно, щоб було видно джерело правди.
Коли параметрів стає багато, Bootstrap перетворюється на «конфіг-файл на PHP».
Крок 11 виносить значення у config/ і
.env; шляхи ($rootPath . 'storage/…') лишаються
до кроку 12 (PathManager).
Що додається
config/*.php— п'ять файлів під contact-app (лише те, що вже використовує Stack)ConfigBootstrap+ConfigServiceProviderConfigKey+AppConfig— ключі і готові масиви для StackApplicationRuntimeBootstrap— timezone з config.env.example— для локального/Docker override
composer.json
ConfigServiceProvider живе в extension-config.
Stack не підтягує його транзитивно — додаток реєструє config сам,
коли з’являється config/.
{
"require": {
"php": "^8.4",
"php-concept/core-2": "^1.0",
"php-concept/stack": "^1.0",
"php-concept/extension-config": "^1.0",
"php-concept/extension-json": "^1.0"
}
}
config/
Extension завантажує усю директорію і мерджить файли.
У рецепті — мінімальний набір; у великому додатку з’являться інші домени
(session, view, events…).
app.php— name, version, timezone, debugdb.php— connection, migrations table, seeders, query loglog.php— Monolog channel/level/filevalidator.php— diagnostic validation log (крок 9)masking.php— patterns і key_patterns (крок 8)
.env: APP_DEBUG=1 → app.debug,
APP_ENV=dev → підвантаження config/dev/ (overlay;
у рецепті такої директорії поки немає — ключ лишається для майбутнього),
DB_HOST=concept_recipes_db → db.host.
Extension мапить перший сегмент імені змінної (до _)
на корінь ключа: тому DB_*, а не MYSQL_*
(останнє дало б mysql.host, не db.host).
Файл .env обов’язковий — змінні лише в
docker-compose environment: Config не підхопить.
ConfigKey + AppConfig
ConfigKey — константи ключів (glue додатку).
AppConfig — лише складні масиви для builder-ів
(dbConnection(), masking, seeders), щоб не дублювати десятки рядків у Bootstrap.
Скаляри (debug, рівень логу) читаємо напряму:
$config->getBool(ConfigKey::APP_DEBUG) — без однорядкових обгорток у AppConfig.
$config = ContainerDependency::get($container, ConfigInterface::class);
$app = new AppConfig($config);
$debug = $config->getBool(ConfigKey::APP_DEBUG);
$stack->addDatabase()->setConnection($app->dbConnection());
bootstrap/app.php
$root = dirname(__DIR__);
(new ConfigBootstrap($root))->boot($container);
(new ApplicationStackBootstrap())->boot($container);
(new ApplicationRuntimeBootstrap())->boot($container);
Запуск і перевірка
Тег step-11-config. Поведінка як на кроці 10; змінилось лише джерело значень.
Запуск
git checkout step-11-config
cp .env.example .env # обов’язково: Config читає файл .env
rm -rf storage/cache storage/sessions storage/logs
composer install
cp docker-compose.yml.example docker-compose.yml
docker compose up -d --build
Перевірка
- /contact і /api/stats — як на кроці 10.
- Змініть
config/app.php→debugабоAPP_DEBUGу Compose — Whoops on/off. - Змініть
config/db.php→hostна невірний — очікувана помилка з’єднання (поверніть назад).
Далі — 12. PathManager:
іменовані шляхи замість $rootPath у Bootstrap.