PHPackages                             phpdot/console - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. phpdot/console

ActiveLibrary[CLI &amp; Console](/categories/cli)

phpdot/console
==============

CLI application framework wrapping symfony/console. DI integration, command discovery, output helpers.

v2.4.0(today)096MITPHPPHP &gt;=8.4

Since Apr 3Pushed 2mo agoCompare

[ Source](https://github.com/phpdot/console)[ Packagist](https://packagist.org/packages/phpdot/console)[ RSS](/packages/phpdot-console/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (39)Versions (8)Used By (0)

phpdot/console
==============

[](#phpdotconsole)

CLI application framework wrapping symfony/console. DI integration, command discovery, output helpers. Standalone.

Install
-------

[](#install)

```
composer require phpdot/console
```

Architecture
------------

[](#architecture)

 ```
graph TD
    APP[Application] -->|wraps| SA[Symfony Application]
    APP -->|discover| CD[CommandDiscovery]
    APP -->|read/write| CC[CommandCache]
    APP -->|wires| CCL[ContainerCommandLoader]

    CD -->|phpdot/attribute Scanner| FILES[".php files + #[AsCommand]"]
    CD -->|produces| MAP["Command Mapname → class"]
    CC -->|caches| MAP

    CCL -->|implements| CLI[CommandLoaderInterface]
    CCL -->|resolves via| PSR[PSR-11 Container]
    CCL -->|uses| MAP

    SA -->|runs| CMD[Command instances]
    CMD -->|extends| BASE[PHPdot Command]
    BASE -->|extends| SC[Symfony Command]

    style APP fill:#2d3748,color:#fff
    style BASE fill:#2d3748,color:#fff
    style CCL fill:#4a5568,color:#fff
    style CD fill:#4a5568,color:#fff
    style CC fill:#4a5568,color:#fff
    style SA fill:#718096,color:#fff
    style PSR fill:#718096,color:#fff
    style SC fill:#718096,color:#fff
    style MAP fill:#718096,color:#fff
    style FILES fill:#718096,color:#fff
    style CLI fill:#718096,color:#fff
    style CMD fill:#718096,color:#fff
```

      Loading Usage
-----

[](#usage)

### Standalone

[](#standalone)

```
use PHPdot\Console\Application;
use PHPdot\Console\ConsoleConfig;

$app = new Application(new ConsoleConfig(name: 'MyApp', version: '1.0.0'));
$app->add(new GreetCommand());
$app->run();
```

### With discovery

[](#with-discovery)

```
use PHPdot\Console\Application;
use PHPdot\Console\ConsoleConfig;

$app = new Application(
    new ConsoleConfig(
        name: 'MyApp',
        version: '1.0.0',
        cachePath: __DIR__ . '/var/cache/commands.php',
    ),
);

$app->discover([__DIR__ . '/src/Command']);
$app->run();
```

`cachePath` makes `Application` build its own `CommandCache` automatically. Pass an explicit `CommandCache` instance via the third constructor argument when you need a custom one.

### With DI container

[](#with-di-container)

```
use PHPdot\Console\Application;
use PHPdot\Console\ConsoleConfig;

$container = /* any PSR-11 container */;

$app = new Application(
    config: new ConsoleConfig(
        name: 'MyApp',
        version: '1.0.0',
        cachePath: __DIR__ . '/var/cache/commands.php',
    ),
    container: $container,
);

$app->discover([__DIR__ . '/src/Command']);
$app->run();
```

### Auto-binding via phpdot/config

[](#auto-binding-via-phpdotconfig)

`ConsoleConfig` carries `#[Config('console')]`, so `phpdot/config` hydrates it from `config/console.php`:

```
// config/console.php
return [
    'name'      => 'MyApp',
    'version'   => '1.0.0',
    'cachePath' => __DIR__ . '/../var/cache/commands.php',
];
```

A future console provider will resolve the DTO from `Configuration::dto()` and inject it into `Application` automatically. Until then, construct the DTO yourself.

### Modifying discovered commands

[](#modifying-discovered-commands)

Apps frequently want to alias, rename, or relabel commands shipped by other packages — for shortcuts, brand consistency, or collision resolution. Three methods on `Application`:

```
$app->discover([__DIR__ . '/vendor/phpdot']);

// Add an alternate name. Both `container:list` and `c:l` work.
$app->alias('container:list', 'c:l');

// Replace the canonical name. The old name no longer resolves.
$app->rename('legacy:run', 'run');

// Change description / help text without touching the name.
$app->override('container:list', description: 'Show every entry in the live container');
```

Rules:

- `alias()` is additive — never breaks the original name. Throws if the new name is already taken by a different command.
- `rename()` replaces the name. Throws if the new name is already taken.
- `override()` mutates non-name metadata only (description, help). Use `rename()` for the name.
- All three are chainable.

### Defining commands

[](#defining-commands)

```
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use PHPdot\Console\Command;

#[AsCommand(name: 'users:import', description: 'Import users from CSV')]
final class ImportUsersCommand extends Command
{
    public function __construct(
        private readonly UserRepository $users,
    ) {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this->addArgument('file', InputArgument::REQUIRED, 'CSV file path');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $file = $input->getArgument('file');
        $rows = $this->parser->parse($file);

        $this->info($output, "Importing from {$file}...");

        $this->withProgress($output, $rows, function (array $row) {
            $this->users->create($row);
        });

        $this->success($output, 'Import complete.');
        return self::SUCCESS;
    }
}
```

### Output helpers

[](#output-helpers)

```
$this->info($output, 'Processing...');
$this->error($output, 'Something failed');
$this->success($output, 'Done');
$this->warning($output, 'Careful');
$this->comment($output, 'Note');
```

### Table

[](#table)

```
$this->table($output, [
    ['name' => 'Alice', 'email' => 'alice@example.com'],
    ['name' => 'Bob', 'email' => 'bob@example.com'],
]);
// Headers auto-detected from first row keys
```

### Progress

[](#progress)

```
$this->withProgress($output, $items, function (mixed $item) {
    // process each item
});
```

### Interactive input

[](#interactive-input)

```
$name = $this->ask($input, $output, 'What is your name?');
$confirmed = $this->confirm($input, $output, 'Continue?', true);
$color = $this->choice($input, $output, 'Pick a color', ['red', 'blue', 'green']);
$password = $this->secret($input, $output, 'Enter password');
```

### Programmatic execution

[](#programmatic-execution)

```
$exitCode = $app->call('cache:clear');
$exitCode = $app->call('migrate', ['--force' => true]);
```

Discovery
---------

[](#discovery)

`CommandDiscovery` scans directories for classes with `#[AsCommand]` that extend `Symfony\Component\Console\Command\Command`. Class discovery is delegated to [`phpdot/attribute`](https://github.com/phpdot/attribute), which handles tokenization, namespace resolution, and attribute reading.

Skips: interfaces, traits, enums, abstract classes, classes without `#[AsCommand]`, and classes that don't extend Symfony's `Command`.

### Cache format

[](#cache-format)

```
// var/cache/commands.php
return [
    'cache:clear' => 'App\\Command\\CacheClearCommand',
    'users:import' => 'App\\Command\\ImportUsersCommand',
];
```

Requirements
------------

[](#requirements)

- PHP &gt;= 8.3
- symfony/console ^7.0
- psr/container ^2.0
- phpdot/attribute ^1.0

`phpdot/container` is suggested (used to expose `#[Config('console')]` to a phpdot framework boot). Standalone consumers don't need it — the attribute is inert until reflected.

License
-------

[](#license)

MIT

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance92

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~15 days

Total

7

Last Release

0d ago

Major Versions

v1.0.0 → v2.0.02026-04-27

PHP version history (2 changes)v1.0.0PHP &gt;=8.3

v2.2.1PHP &gt;=8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/62e82421bda4b5d6ba9a47ba6d88caca060dcd0d1a2862f351f3a97657385db0?d=identicon)[phpdot](/maintainers/phpdot)

---

Top Contributors

[![phpdot](https://avatars.githubusercontent.com/u/252500?v=4)](https://github.com/phpdot "phpdot (6 commits)")

---

Tags

cliconsolesymfonyPSR-11didiscoverycommand

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/phpdot-console/health.svg)

```
[![Health](https://phpackages.com/badges/phpdot-console/health.svg)](https://phpackages.com/packages/phpdot-console)
```

###  Alternatives

[nunomaduro/collision

Cli error handling for console/command-line PHP applications.

4.7k357.7M11.1k](/packages/nunomaduro-collision)[mnapoli/silly

Silly CLI micro-framework based on Symfony Console

93910.7M143](/packages/mnapoli-silly)[buggregator/trap

A simple and powerful tool for debugging PHP applications.

2702.2M68](/packages/buggregator-trap)[laminas/laminas-cli

Command-line interface for Laminas projects

564.1M72](/packages/laminas-laminas-cli)[testo/testo

A lightweight PHP testing framework.

1959.3k64](/packages/testo-testo)[whatsdiff/whatsdiff

See what's changed in your project's dependencies

771.2k](/packages/whatsdiff-whatsdiff)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
