Console
The application CLI is built on
Symfony Console.
Entry point — bin/console.php; commands are registered through the DI container and
ConsoleServiceProvider.
See also: Setup → bin/console.php, CLI providers, creating custom commands, Database → console commands.
Core classes
| Class | Role |
|---|---|
ConsoleServiceProvider |
Symfony\Component\Console\Application, registration from config/commands.php |
ComponentsServiceProvider |
Adds component commands in boot() |
DisabledCommand |
Stub when a command cannot be created from DI |
Running
From the project root:
php bin/console.php
# help
php bin/console.php list
# help for one command
php bin/console.php help db:migrate
CLI bootstrap differs from HTTP: it loads
bootstrap/providers/console.php. For details see
Setup and the
providers and commands section below.
How it works
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();
ConsoleServiceProvidercreatesApplicationwith name/version fromapp.name/app.version- Classes from
config/commands.php(ConfigKey::COMMANDS) are resolved from DI and added to the application - If a command dependency is unavailable — a
DisabledCommandis registered with an error explanation ComponentsServiceProvider::boot()adds commands fromComponentInterface::commands()on each active component
// config/commands.php (fragment)
return [
'commands' => [
DbMigrateCommand::class,
RouteListCommand::class,
// ...
],
];
Providers and command dependencies
Each command is a regular Symfony Console service: dependencies are passed through the constructor and
resolved from the DI container. If the provider that registers a service is missing from
bootstrap/providers/console.php, the command is not created — instead a
DisabledCommand appears.
| Command | Dependencies (DI) | Required providers |
|---|---|---|
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 (paths to routes/*.php) |
view:clear |
PathManager, ConfigInterface |
ConfigServiceProvider (Twig not required in CLI) |
component:list, component:publish-assets |
ComponentRegistry |
ComponentsServiceProvider (last, after ConsoleServiceProvider) |
Recommended minimum (bootstrap/providers/console.php):
return [
ConfigServiceProvider::class, // config, PathManager
HttpServiceProvider::class, // RouterInterface → route:list
SessionServiceProvider::class, // if commands/seeders touch session
ErrorHandlerServiceProvider::class,
LogServiceProvider::class,
DatabaseServiceProvider::class, // db:*, migration:list, seeders:list
ConsoleServiceProvider::class, // Application + commands from config/commands.php
DebugLoggerServiceProvider::class,
ComponentsServiceProvider::class, // component:* + component commands
];
ConsoleServiceProvider must come before ComponentsServiceProvider:
the latter adds component commands in boot() to an already created ConsoleApplication.
Why CLI needs HttpServiceProvider
At first glance the HTTP stack in the console seems unnecessary — CLI does not handle browser requests. But
route:list injects RouterInterface, and the router is registered by
HttpServiceProvider: it creates League\Route\Router, wires
RouteStrategy, and loads files from config/routes.php (and component routes
— via ComponentsServiceProvider).
Without HttpServiceProvider the container does not know RouterInterface →
RouteListCommand cannot be built → in php bin/console.php list you see
route:list with a red disabled warning (as in the screenshot below).
A full list of component routes additionally requires
ComponentsServiceProvider, which loads each component’s routes.php.
In CLI App::run() is not called and no request is dispatched.
The provider only builds the same route graph as the web application, so diagnostics
(route:list, -F for middleware) show the real picture.
ServerRequestInterface in CLI is an “empty” PSR-7 from fromGlobals();
that is enough for listing routes.
Twig, Validation, and ViewRegistry are intentionally omitted from the console bootstrap — no built-in command needs them.
HttpServiceProvider also registers
ResponseFactory and ViewResponseFactory, but CLI commands do not resolve them.
If a provider is missing — DisabledCommand
In ConsoleServiceProvider::addConsoleCommands() each class from
config/commands.php is created via $container->get($className).
Any Throwable (missing binding, autowire failure, provider not
registered) is caught — instead of the real command a
DisabledCommand is added with the same name (COMMAND_NAME from the original class).
In php bin/console.php list output such commands have the description:
!!! WARNING: This command is disabled (possible missing dependencies).
Run command to see details. !!!
Typical picture with a “trimmed” console.php (without HTTP and components):
route:list— disabled (noHttpServiceProvider)component:list,component:publish-assets— disabled (noComponentsServiceProvider)db:migrate,db:rollback— disabled (missing orboot()not completed forDatabaseServiceProvider)db:seed,seeders:list,migration:list,view:clear— often remain active because their dependencies are simpler or do not need the full HTTP stack
To see the exact reason, run the disabled command:
php bin/console.php route:list
Example output:
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 ... (container exception text, e.g. class not found)
Fix: add the corresponding provider to bootstrap/providers/console.php
(see table above) and restart the console. For custom commands — same rule: if a command
needs DatabaseInterface, without DatabaseServiceProvider it will also become
disabled.
Core commands
Registered in config/commands.php:
| Command | Purpose |
|---|---|
db:migrate | Run migrations |
migration:list | List rows in the migrations table (-l — limit) |
db:rollback | Rollback the last migration batch |
db:seed | All seeders; -c "Fully\Qualified\Class" — one (full FQCN) |
seeders:list | List registered seeders |
route:list | Route table; -F / --full-middleware — middleware FQCN |
view:clear | Clear Twig cache directory (storage/cache/{view.cache_dir}) |
component:list | List enabled components (ComponentRegistry) |
component:publish-assets | Copy assets from ComponentInterface::assets() to public/ |
Examples
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
Component commands
A component adds commands via ComponentInterface::commands().
During ComponentsServiceProvider::boot() they are resolved from the container
and added to the same ConsoleApplication.
CLI does not register component view extensions/paths (only commands, migrations, seeders, providers).
// AuthAdminComponent::commands()
public function commands(): array
{
return [
UserListCommand::class,
];
}
// php bin/console.php user:list
// php bin/console.php user:list --limit=5
Application custom commands go in config/commands.php under
// Custom Business Commands. Details — Creating commands.
Exit codes
Commands return Command::SUCCESS (0) or Command::FAILURE (1).
In CI scripts check the exit code after php bin/console.php ....
Environment and config
CLI uses the same .env and ConfigServiceProvider as HTTP.
APP_ENV drives config/{env}/ overrides and the component list
(for example DebugBar only in config/dev/components.php).
Migrations and seeders require a correct DB connection in
config/db.php (or via .env).
The console is for maintenance (migrations, cache, diagnostics) and local development. Long-running business logic belongs in services; keep the command as a thin call. If a command is “disabled” — first check CLI providers, not the command itself.