Робота з консоллю

CLI застосунку побудований на Symfony Console. Точка входу — bin/console.php; команди реєструються через DI-контейнер і ConsoleServiceProvider.

Див. також: налаштування → bin/console.php, провайдери для CLI, створення власних команд, БД → консольні команди.

Класи ядра

КласРоль
ConsoleServiceProvider Symfony\Component\Console\Application, реєстрація з config/commands.php
ComponentsServiceProvider Додає команди компонентів у boot()
DisabledCommand Заглушка, якщо команду не вдалося створити з DI

Запуск

З кореня проєкту:

php bin/console.php

# довідка
php bin/console.php list

# довідка по одній команді
php bin/console.php help db:migrate

Bootstrap CLI відрізняється від HTTP: підключається bootstrap/providers/console.php. Детальніше — Setup і розділ провайдери та команди нижче.

Як це влаштовано

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

$rootPath = dirname(__DIR__);
$paths = include $rootPath . '/bootstrap/paths.php';
$app = App::create($rootPath, $paths);
$app->registerServiceProviders([$rootPath . '/bootstrap/providers/console.php']);

$console = $app->getContainer()->get(ConsoleApplication::class);
$console->run();
  1. ConsoleServiceProvider створює Application з іменем/версією з app.name / app.version
  2. Класи з config/commands.php (ConfigKey::COMMANDS) резолвяться з DI і додаються в application
  3. Якщо залежність команди недоступна — реєструється DisabledCommand з поясненням помилки
  4. ComponentsServiceProvider::boot() додає команди з commands() кожного компонента
// config/commands.php (фрагмент)
return [
    'commands' => [
        DbMigrateCommand::class,
        RouteListCommand::class,
        // ...
    ],
];

Провайдери та залежності команд

Кожна команда — звичайний сервіс Symfony Console: залежності передаються через конструктор і резолвяться з DI-контейнера. Якщо провайдер, який реєструє сервіс, відсутній у bootstrap/providers/console.php, команда не створюється — замість неї з’являється DisabledCommand.

Команда Залежності (DI) Потрібні провайдери
db:migrate, db:rollback Migrator, MigrationRegistry DatabaseServiceProvider (boot() — Capsule)
migration:list CapsuleManager, ConfigInterface ConfigServiceProvider, DatabaseServiceProvider
db:seed SeederManager DatabaseServiceProvider
seeders:list SeederRegistry DatabaseServiceProvider
route:list RouterInterface HttpServiceProvider, ConfigServiceProvider (шляхи до routes/*.php)
view:clear PathManager, ConfigInterface ConfigServiceProvider (Twig у CLI не потрібен)
component:list, component:publish-assets ComponentRegistry ComponentsServiceProvider (останнім після ConsoleServiceProvider)

Рекомендований мінімум (bootstrap/providers/console.php):

return [
    ConfigServiceProvider::class,        // конфіг, PathManager
    HttpServiceProvider::class,          // RouterInterface → route:list
    SessionServiceProvider::class,       // якщо команди/сидери торкаються сесії
    ErrorHandlerServiceProvider::class,
    LogServiceProvider::class,
    DatabaseServiceProvider::class,      // db:*, migration:list, seeders:list
    ConsoleServiceProvider::class,       // Application + команди з config/commands.php
    DebugLoggerServiceProvider::class,
    ComponentsServiceProvider::class,    // component:* + команди компонентів
];

ConsoleServiceProvider має бути перед ComponentsServiceProvider: останній у boot() додає команди компонентів у вже створений ConsoleApplication.

Навіщо CLI потребує HttpServiceProvider

На перший погляд HTTP-стек у консолі зайвий — CLI не обробляє запити браузера. Але route:list інжектує RouterInterface, а роутер реєструє HttpServiceProvider: він створює League\Route\Router, підключає RouteStrategy і завантажує файли з config/routes.php (і маршрути компонентів — через ComponentsServiceProvider).

Без HttpServiceProvider контейнер не знає RouterInterfaceRouteListCommand не збирається → у php bin/console.php list ви бачите route:list із червоним попередженням про disabled (як на скріншоті нижче). Повний список маршрутів компонентів додатково потребує ComponentsServiceProvider, який підключає routes.php кожного компонента.

У CLI не викликається App::run() і не відбувається dispatch запиту. Провайдер лише будує той самий граф маршрутів, що й у веб-застосунку, щоб діагностика (route:list, -F для middleware) показувала реальну картину. ServerRequestInterface у CLI — «порожній» PSR-7 з fromGlobals(); для переліку маршрутів цього достатньо.

Twig, Validation, ViewRegistry у консольний bootstrap навмисно не входять — вони не потрібні жодній вбудованій команді. HttpServiceProvider реєструє також ResponseFactory і ViewResponseFactory, але CLI-команди їх не резолвять.

Якщо провайдер не підключено — DisabledCommand

У ConsoleServiceProvider::addConsoleCommands() кожен клас з config/commands.php створюється через $container->get($className). Будь-який Throwable (немає binding, не вдалося autowire, провайдер не зареєстрований) перехоплюється — замість справжньої команди додається DisabledCommand з тим самим ім’ям (COMMAND_NAME з оригінального класу).

У виводі php bin/console.php list такі команди мають опис:

!!! WARNING: This command is disabled (possible missing dependencies).
Run command to see details. !!!

Типова картина при «урізаному» console.php (без HTTP і компонентів):

  • route:list — disabled (немає HttpServiceProvider)
  • component:list, component:publish-assets — disabled (немає ComponentsServiceProvider)
  • db:migrate, db:rollback — disabled (немає або не завершив boot() DatabaseServiceProvider)
  • db:seed, seeders:list, migration:list, view:clear — часто лишаються активними, бо їхні залежності простіші або не потребують повного HTTP-стеку

Щоб побачити точну причину, запустіть disabled-команду:

php bin/console.php route:list

Приклад виводу:

Command Disabled: route:list

 [WARNING] This command cannot be executed because its dependencies are not met.
           Likely a required ServiceProvider is not registered in bootstrap/providers/.

 Original Class   Concept\Core\Console\Commands\RouteListCommand
 Error Detail     ... (текст винятку контейнера, напр. class not found)

Виправлення: додайте відповідний провайдер у bootstrap/providers/console.php (див. таблицю вище) і перезапустіть консоль. Для власних команд — те саме: якщо command потребує DatabaseInterface, без DatabaseServiceProvider вона теж стане disabled.

Команди ядра

Реєстрація в config/commands.php:

КомандаПризначення
db:migrateВиконати міграції
migration:listСписок записів у таблиці migrations (-l — ліміт)
db:rollbackВідкат останнього batch міграцій
db:seedУсі сидери; -c "Fully\Qualified\Class" — один (повний FQCN)
seeders:listСписок зареєстрованих сидерів
route:listТаблиця маршрутів; -F / --full-middleware — FQCN middleware
view:clearОчистити каталог кешу Twig (storage/cache/{view.cache_dir})
component:listСписок увімкнених компонентів (ComponentRegistry)
component:publish-assetsКопіює assets з ComponentInterface::assets() у public/

Приклади

php bin/console.php db:migrate
php bin/console.php migration:list
php bin/console.php db:seed
php bin/console.php db:seed -c "Concept\Components\AuthAdmin\Database\Seeders\UserSeeder"
php bin/console.php seeders:list
php bin/console.php route:list
php bin/console.php route:list -F
php bin/console.php component:list
php bin/console.php view:clear

Команди компонентів

Компонент додає команди в методі commands(). Під час ComponentsServiceProvider::boot() вони резолвяться з контейнера і додаються в той самий ConsoleApplication. У CLI не реєструються view extensions/paths компонентів (лише команди, міграції, сидери, провайдери).

// AuthAdminComponent::commands()
public function commands(): array
{
    return [UserListCommand::class];
}

// php bin/console.php auth:user-list
// php bin/console.php auth:user-list --limit=5

Власні команди додатку — у config/commands.php у секції // Custom Business Commands. Детальніше — Створення команд.

Коди завершення

Команди повертають Command::SUCCESS (0) або Command::FAILURE (1). У скриптах CI перевіряйте exit code після php bin/console.php ....

Оточення та конфіг

CLI використовує той самий .env і ConfigServiceProvider, що й HTTP. APP_ENV визначає оверрайди config/{env}/ і список компонентів (наприклад DebugBar лише в config/dev/components.php).

Для міграцій і сидерів потрібне коректне підключення БД у config/db.php (або через .env).

Консоль — для обслуговування (міграції, кеш, діагностика) і локальної розробки. Довготривалу бізнес-логіку краще виносити в сервіси, а в command лишати тонкий виклик. Якщо команда «disabled» — спочатку перевірте провайдери CLI, а не саму команду.