Налаштування

Ця сторінка описує bootstrap застосунку: точки входу HTTP і CLI, paths.php та service providers. Якщо ви ще не встановили пакет — спочатку пройдіть Встановлення (Concept Skeleton або composer require php-concept/core). Далі — Конфігурація (config/, .env).

Ядро окремо: мінімальна структура

Після composer require php-concept/core зберуть таку кореневу структуру (шляхи можна змінити в paths.php):

project/
├── public/index.php          # HTTP front controller
├── bin/console.php           # CLI (опційно)
├── bootstrap/
│   ├── app.php
│   ├── paths.php
│   └── providers/
│       ├── app.php           # провайдери для веб-запитів
│       └── console.php       # провайдери для CLI
├── config/                   # PHP-конфіг (обовʼязково для ConfigServiceProvider)
├── routes/                   # якщо маршрути винесені з config
├── storage/                  # logs, cache
└── composer.json

Альтернативні варіанти розкладки каталогів — у Структура каталогів. У skeleton ці файли вже готові; нижче — розбір кожного елемента для власного проєкту.

Загальна схема

HTTP і CLI використовують спільні paths.php та App::create(), але різні точки входу і різні списки провайдерів. У skeleton HTTP йде через bootstrap/app.php, а CLI збирає bootstrap безпосередньо в bin/console.php (без app.php).

registerServiceProviders() лише підключає класи провайдерів до контейнера. Повне завантаження конфігу, маршрутів і сервісів відбувається lazy — при першому зверненні до контейнера в $app->run() (HTTP) або $container->get(ConsoleApplication) (CLI).

HTTP

flowchart TB
    WS["Веб-сервер"]
    IDX["public/index.php"]
    AUTO["vendor/autoload.php"]
    APP_PHP["bootstrap/app.php"]
    PATHS["paths.php"]
    CREATE["App::create()"]
    EARLY["Ранній Whoops + PathManager"]
    REG["registerServiceProviders()"]
    PROV_HTTP["providers/app.php"]
    RUN["App::run()"]
    LAZY["Lazy boot провайдерів"]
    CFG["Config: .env + config/"]
    HTTP_P["Http: PSR-7 Request, Router, routes/web.php"]
    COMP["Components: маршрути модулів, views"]
    DISP["Router::dispatch()"]
    MW["Middleware"]
    STRAT["RouteStrategy: interceptors, autowire"]
    CTRL["Контролер → PSR-7 Response"]
    EMIT["SapiEmitter → клієнт"]

    WS --> IDX --> AUTO --> APP_PHP
    APP_PHP --> PATHS --> CREATE --> EARLY
    APP_PHP --> REG --> PROV_HTTP
    IDX --> RUN
    RUN --> LAZY --> CFG --> HTTP_P --> COMP
    RUN --> DISP --> MW --> STRAT --> CTRL --> EMIT
  1. public/index.php — autoload і підключення bootstrap/app.php.
  2. App::create() — League Container, ReflectionContainer, ранній Whoops, PathManager.
  3. registerServiceProviders — масив класів з bootstrap/providers/app.php.
  4. App::run() — резолв Router і ServerRequest з контейнера; провайдери завантажують конфіг, маршрути, Twig, сесію тощо.
  5. Router::dispatch() — middleware, RouteStrategy, контролер; відповідь відправляє SapiEmitter.

Детальний розбір middleware, route interceptors і autowiring — Життєвий цикл запиту.

CLI

flowchart TB
    BIN["bin/console.php"]
    AUTO["vendor/autoload.php"]
    PATHS["paths.php"]
    CREATE["App::create()"]
    EARLY["Ранній Whoops + PathManager"]
    REG["registerServiceProviders()"]
    PROV_CLI["providers/console.php"]
    GET["container->get(ConsoleApplication)"]
    LAZY["Lazy boot провайдерів"]
    CFG["Config: .env + config/"]
    CON["ConsoleServiceProvider: команди з config"]
    COMP["Components: CLI-команди модулів"]
    RUN["ConsoleApplication::run()"]
    CMD["Symfony Command"]

    BIN --> AUTO --> PATHS --> CREATE --> EARLY
    BIN --> REG --> PROV_CLI
    BIN --> GET --> LAZY --> CFG --> CON --> COMP --> RUN --> CMD
  1. bin/console.php — autoload, paths.php, App::create() (як у HTTP, але без bootstrap/app.php).
  2. providers/console.php — інший набір провайдерів: без Twig/Validation HTTP-стеку, з ConsoleServiceProvider.
  3. get(ConsoleApplication) — lazy boot: конфіг, реєстрація команд ядра та компонентів.
  4. ConsoleApplication::run() — Symfony Console виконує команду (db:migrate, route:list тощо).

ComponentsServiceProvider у CLI не реєструє view paths/contexts — лише команди, migrations, seeders і додаткові провайдери модулів.

public/index.php

Єдина публічна точка входу для веб-сервера (Apache, Nginx, PHP built-in server). Document root віртуального хоста має вказувати на public/.

<?php declare(strict_types=1);

use Concept\Core\App;

require_once __DIR__ . '/../vendor/autoload.php';

/** @var App $app */
$app = require_once __DIR__ . '/../bootstrap/app.php';

$app->run();
  • autoload — Composer PSR-4 (vendor/autoload.php).
  • bootstrap/app.php — створює App, реєструє провайдери для HTTP.
  • run() — обробка PSR-7 запиту, маршрутизація, відповідь.

У public/ також лежать статичні файли (assets/, vendor/bootstrap після publish) — вони віддаються напряму веб-сервером, без PHP.

Каталог bootstrap/

Код ініціалізації застосунку. paths.php спільний для HTTP і CLI; app.php використовується лише веб-точкою входу. CLI дублює кроки App::create() + провайдери безпосередньо в bin/console.php.

bootstrap/
├── app.php              # HTTP: App + провайдери app.php
├── paths.php            # мапа логічних шляхів → каталоги проєкту
└── providers/
    ├── app.php          # провайдери для веб-запитів
    └── console.php      # провайдери для консолі

bootstrap/app.php

<?php declare(strict_types=1);

use Concept\Core\App;

$rootPath = dirname(__DIR__);
/** @var array<string, string> $paths */
$paths = include $rootPath . '/bootstrap/paths.php';
$app = App::create($rootPath, $paths);

$providerFiles = [
    $rootPath . '/bootstrap/providers/app.php',
];
$app->registerServiceProviders($providerFiles);

return $app;
  • $rootPath — абсолютний шлях до кореня проєкту (батьківська папка для bootstrap/).
  • paths.php — повертає масив для PathManager (див. нижче).
  • App::create() — контейнер, ранній error handler, реєстрація PathManager.
  • registerServiceProviders() — кожен файл у списку має повертати масив класів провайдерів.

bootstrap/providers/app.php

Файл повертає масив класів service providers ядра. Кожен провайдер реєструє сервіси в контейнері (router, config, Twig, БД тощо). Порядок у масиві важливий — залежності мають бути раніше за залежні сервіси.

Мінімум для HTTP — конфіг і маршрутизація (потрібні config/app.php, config/routes.php і файл маршрутів):

<?php declare(strict_types=1);

use Concept\Core\Providers\Bootstrap\ConfigServiceProvider;
use Concept\Core\Providers\Http\HttpServiceProvider;

return [
    ConfigServiceProvider::class,
    HttpServiceProvider::class,
];

Для реального застосунку додайте провайдери помилок, сесії, логів, views, валідації, БД, компонентів — як у Concept Skeleton. Щоб підключити власний провайдер — додайте клас у масив або окремий файл у $providerFiles у app.php.

bootstrap/providers/console.php

Скорочений набір для CLI: без Twig/Validation HTTP-стеку, з ConsoleServiceProvider. Використовується з bin/console.php. Приклад із skeleton:

<?php declare(strict_types=1);

use Concept\Core\Providers\Component\ComponentsServiceProvider;
use Concept\Core\Providers\Bootstrap\ConfigServiceProvider;
use Concept\Core\Providers\Console\ConsoleServiceProvider;
use Concept\Core\Providers\Database\DatabaseServiceProvider;
use Concept\Core\Providers\Bootstrap\ErrorHandlerServiceProvider;
use Concept\Core\Providers\Http\HttpServiceProvider;
use Concept\Core\Providers\Logging\LogServiceProvider;
use Concept\Core\Providers\Http\SessionServiceProvider;

return [
    ConfigServiceProvider::class,
    ErrorHandlerServiceProvider::class,
    HttpServiceProvider::class,
    SessionServiceProvider::class,
    LogServiceProvider::class,
    DatabaseServiceProvider::class,
    ConsoleServiceProvider::class,
    ComponentsServiceProvider::class,
];

bootstrap/paths.php

Центральне місце, де ви задаєте фізичну структуру проєкту. Файл повертає асоціативний масив: логічний ключвідносний шлях від кореня проєкту. Ядро звертається до каталогів лише через PathManager::get($key), а не через жорстко прошиті рядки.

Структуру папок можна визначити на свій смак: перейменуйте каталоги, рознесіть код по монорепо або перенесіть логи в var/log — достатньо змінити значення в paths.php, якщо ключі залишаються константами PathName.

Приклад із skeleton (повний набір ключів):

<?php

use Concept\Core\Foundation\PathName;

return [
    PathName::BOOTSTRAP => 'bootstrap',
    PathName::SRC => 'src',
    PathName::CONFIG => 'config',
    PathName::MIGRATIONS => 'database/migrations',
    PathName::SEEDERS => 'database/seeders',
    PathName::PUBLIC => 'public',
    PathName::STORAGE => 'storage',
    PathName::LOGS => 'storage/logs',
    PathName::CACHE => 'storage/cache',
    PathName::RESOURCES => 'resources',
    PathName::LANG => 'resources/lang',
    PathName::VALIDATOR_TRANSLATIONS => 'resources/lang/validator',
    PathName::VIEWS => 'resources/views',
    PathName::ERRORS_FALLBACK_VIEWS => 'resources/views/errors/fallback',
];

Ключі PathName

Константа (ключ масиву) Шлях у skeleton Хто використовує
BOOTSTRAPbootstrapРезерв для bootstrap-ресурсів
SRCsrcКод застосунку (PSR-4)
CONFIGconfigPHP-конфіг, оверрайди config/{env}/
MIGRATIONSdatabase/migrationsМіграції БД
SEEDERSdatabase/seedersСидери
PUBLICpublicDocument root, статика
STORAGEstorageЗаписувані дані застосунку
LOGSstorage/logsMonolog, debug-лог
CACHEstorage/cacheКеш Twig, Valinor тощо
RESOURCESresourcesРесурси, не тільки views
LANGresources/langМовні файли
VALIDATOR_TRANSLATIONSresources/lang/validatorПереклади правил валідації
VIEWSresources/viewsШаблони Twig / Plates
ERRORS_FALLBACK_VIEWSresources/views/errors/fallbackFallback-шаблони помилок (production)

API PathManager

use Concept\Core\Foundation\PathName;

// Абсолютний шлях: /var/www/my-app/config
$pathManager->get(PathName::CONFIG);

// З підшляхом: /var/www/my-app/storage/cache/views
$pathManager->get(PathName::CACHE, 'views');

// Довільний шлях від кореня проєкту
$pathManager->root('custom/dir');

Другий аргумент get() — підкаталог усередині зареєстрованого шляху (наприклад view.cache_dir у конфігу додається до PathName::CACHE).

Власна структура каталогів

Приклад: логи та кеш у var/, код у app/:

use Concept\Core\Foundation\PathName;

return [
    PathName::SRC => 'app',
    PathName::CONFIG => 'etc/config',
    PathName::LOGS => 'var/log',
    PathName::CACHE => 'var/cache',
    PathName::VIEWS => 'app/Resources/views',
    // ... інші ключі за потреби
];

Після зміни шляхів:

  • оновіть composer.jsonautoload.psr-4, якщо змінили PathName::SRC;
  • переконайтеся, що веб-сервер дивиться на актуальний PathName::PUBLIC;
  • у config/migrations.php та view.php шляхи узгоджені з новою структурою.

Додавати нові ключі в PathName у ядрі потрібно лише якщо новий тип шляху використовуватиме саме core; для власного коду достатньо $pathManager->root('my/custom/path').

bin/console.php

Точка входу для CLI (міграції, сидери, route:list, view:clear).

<?php declare(strict_types=1);

use Concept\Core\App;
use Symfony\Component\Console\Application as ConsoleApplication;

require __DIR__ . '/../vendor/autoload.php';

$rootPath = dirname(__DIR__);
$paths = include $rootPath . '/bootstrap/paths.php';
$app = App::create($rootPath, $paths);

$providerFiles = [
    $rootPath . '/bootstrap/providers/console.php',
];
$app->registerServiceProviders($providerFiles);

$container = $app->getContainer();
$console = $container->get(ConsoleApplication::class);

$console->run();

Запуск із кореня проєкту (як у composer.json → script console):

php bin/console.php

Відмінності від HTTP:

  • той самий paths.php і App::create();
  • інший список провайдерів — bootstrap/providers/console.php;
  • замість $app->run() — Symfony Console Application з контейнера.

Чеклист нового проєкту

  1. Встановити пакет — Concept Skeleton або ядро окремо.
  2. Створити структуру з public/index.php, bootstrap/, за потреби bin/console.php.
  3. Налаштувати bootstrap/paths.php під свої каталоги.
  4. Підключити провайдери в bootstrap/providers/app.php та console.php.
  5. Налаштувати веб-сервер на public/, створити .env.
  6. Перейти до Конфігураціїconfig/ та змінні оточення.