---
title: "Console Project"
description: "Symfony Console Integration for the Derafu Kernel"
type: "docs"
category: "doc"
tags: [php]
authors: [Anonymous]
date: "2026-09-09"
last_update: "2026-09-09"
time_minutes: 5
draft: false
unlisted: false
url: "https://www.derafu.dev/docs/core/console"
---

# Symfony Console Integration for the Derafu Kernel

![GitHub last commit](https://img.shields.io/github/last-commit/derafu/console/main)
![CI Workflow](https://github.com/derafu/console/actions/workflows/ci.yml/badge.svg?branch=main&event=push)
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/derafu/console)
![GitHub Issues](https://img.shields.io/github/issues-raw/derafu/console)
![Total Downloads](https://poser.pugx.org/derafu/console/downloads)
![Monthly Downloads](https://poser.pugx.org/derafu/console/d/monthly)

Adds [Symfony Console](https://symfony.com/doc/current/components/console.html) command auto-discovery and execution to any [`Derafu\Kernel\MicroKernel`](https://www.derafu.dev/docs/core/kernel)-based Kernel — no per-command registration, no opinion on whether a project reuses its main Kernel or a dedicated console-only one.

## What This Package Provides

- `Derafu\Console\DependencyInjection\CommandCompilerPass`: collects every service tagged `console.command` into a `console.command_ids` container parameter.
- `Derafu\Console\ConsoleKernelTrait`: adds command auto-discovery and a `run(): int` method to any class extending `Derafu\Kernel\MicroKernel` (or providing an equivalent `getContainer(): ContainerInterface`).
- `Derafu\Console\Kernel`: a ready-to-use console Kernel for projects that do not need to compose console support into an existing Kernel.
- `Derafu\Console\Runtime`: resolves the real process environment (`APP_ENV`/`APP_DEBUG`) before any Kernel exists — see below.

This package does not depend on `derafu/http` or any HTTP-related package. It has no opinion on whether a project reuses its main application Kernel, a dedicated console-only subclass of it, or a fresh one — that decision belongs entirely to each project.

## Installation

```bash
composer require derafu/console
```

## `Runtime`: Resolving `APP_ENV`/`APP_DEBUG` Before the Kernel Exists

A Kernel's own `Derafu\Kernel\Environment::getEnv()` cannot help decide *its own* `$environment`/`$debug` constructor arguments — it's an instance method, and the instance doesn't exist yet. Something has to resolve those two values from the real process environment first.

Reading `$_ENV['APP_ENV']` directly is not reliable: `$_ENV` is only populated when the `variables_order` php.ini directive includes `E`, which is not every PHP installation's default — a stock Homebrew PHP on macOS, for example, ships with `GPCS`, without `E`. `$_SERVER` does carry real process environment variables in the CLI SAPI regardless of that setting, so `Runtime::getApplicationContext()` merges both:

```php
use Derafu\Console\Runtime;

$context = Runtime::getApplicationContext();
// ['APP_ENV' => 'prod', 'APP_DEBUG' => false, ...] — plus whatever else
// was already in $_SERVER/$_ENV.
```

Defaults to `prod`/`false` when neither is set — deliberately the *opposite* of [`derafu/http`'s `Runtime`](https://www.derafu.dev/docs/core/http), whose `dev`/`true` fallback only matters when an HTTP project has no `.env` of its own (`Derafu\Kernel\Environment::loadEnvironmentVariables()` loads one). A console tool installed via Composer and run as `bin/console` has no such file: the values this class resolves *are* the actual default a fresh install runs with, so it has to be the safe one — a stack trace should never be exposed unless `APP_DEBUG` is explicitly set.

`Runtime::run()` resolves the context, builds the Kernel through a factory, and runs it — this is the actual recommended `bin/console` entry point, not `getApplicationContext()` used by hand:

```php
// bin/console
use Derafu\Console\Kernel;
use Derafu\Console\Runtime;

require dirname(__DIR__) . '/vendor/autoload.php';

exit(Runtime::run(fn (array $context): Kernel => new Kernel(
    $context['APP_ENV'],
    (bool) $context['APP_DEBUG'],
)));
```

## Usage

### A Project With No Other Kernel (Simplest Case)

`Kernel` reads `services.yaml` from the environment's configuration directory. Any service in it whose class extends `Symfony\Component\Console\Command\Command` is discovered automatically.

```php
// bin/console
use Derafu\Console\Kernel;
use Derafu\Console\Runtime;

require dirname(__DIR__) . '/vendor/autoload.php';

exit(Runtime::run(fn (array $context): Kernel => new Kernel(
    $context['APP_ENV'],
    (bool) $context['APP_DEBUG'],
)));
```

### A Project That Already Has Its Own Kernel

Use `ConsoleKernelTrait` directly on a dedicated subclass, so the main Kernel is not forced to carry console-specific wiring it may rarely need:

```php
use Derafu\Console\ConsoleKernelTrait;

class ConsoleApplication extends Application // your project's own Kernel.
{
    use ConsoleKernelTrait;

    protected function configure(
        ContainerConfigurator $configurator,
        ContainerBuilder $container
    ): void {
        parent::configure($configurator, $container);
        $this->configureConsole($container);
    }
}
```

```php
// bin/console
use App\ConsoleApplication;
use Derafu\Console\Runtime;

require dirname(__DIR__) . '/vendor/autoload.php';

exit(Runtime::run(fn (array $context): ConsoleApplication => new ConsoleApplication(
    $context['APP_ENV'],
    (bool) $context['APP_DEBUG'],
)));
```

The same applies if the console needs to share the exact same `services.yaml` as, e.g., an HTTP Kernel: extend that Kernel instead of `Derafu\Console\Kernel` and `use ConsoleKernelTrait` the same way — see [Backbone Console](https://www.derafu.dev/docs/core/backbone-console) for a real example of this (`libredte-lib-core-console`'s `ConsoleApplication` extends its own business Kernel, not `Derafu\Console\Kernel`).

### Overriding the Application Built by `run()`

`ConsoleKernelTrait::createConsoleApplication()` builds the underlying `Symfony\Component\Console\Application` — override it to customize the name/version, or to install a `CommandLoaderInterface` (as [Backbone Console](https://www.derafu.dev/docs/core/backbone-console) does):

```php
use Symfony\Component\Console\Application as SymfonyConsoleApplication;
use Symfony\Component\DependencyInjection\ContainerInterface;

class ConsoleApplication extends Application
{
    use ConsoleKernelTrait {
        createConsoleApplication as private buildBaseConsoleApplication;
    }

    protected function createConsoleApplication(
        ContainerInterface $container
    ): SymfonyConsoleApplication {
        $application = $this->buildBaseConsoleApplication($container);

        // e.g. $application->setCommandLoader(...);

        return $application;
    }
}
```

The alias (`createConsoleApplication as private buildBaseConsoleApplication`) is required to call the trait's own implementation: a trait's methods are mixed directly into the class, not inherited through a parent class, so `parent::createConsoleApplication()` would not resolve.

### Customizing the Application Name and Version

Set these as container parameters (e.g. in `services.yaml`) and they will be picked up automatically:

```yaml
parameters:
    kernel.app_name: 'My CLI'
    kernel.app_version: '1.0.0'
```

## Requirements

PHP 8.5+. Depends on [`derafu/kernel`](https://www.derafu.dev/docs/core/kernel) and `symfony/console`.



---
Last updated on 09/09/2026
#php
