tereta / console
Building console (CLI) applications on PHP 8.2+ with PSR-3 output and a PSR-11 dependency container.
Requires
- php: >=8.2
- psr/container: ^2.0
- psr/log: ^3.0
Requires (Dev)
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.0
- squizlabs/php_codesniffer: ^3.10
This package is not auto-updated.
Last update: 2026-08-16 20:48:23 UTC
README
π English | Π ΡΡΡΠΊΠΈΠΉ | Π£ΠΊΡΠ°ΡΠ½ΡΡΠΊΠ°
Building console (CLI) applications on PHP 8.2+ with PSR-3 output and a PSR-11 dependency container.
Requirements
PHP 8.2+, psr/container ^2.0, psr/log ^3.0.
Installation
composer require tereta/console
Quick start
The entry point is the Tereta\Console\Runtime class - it registers commands and passes $argv for execution:
#!/usr/bin/env php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use Tereta\Console\Runtime;
use Tereta\Console\Commands\Listing;
(new Runtime())
->register(Listing::class)
->execute($argv);
The first argument is the command identifier, the rest is passed to the command.
With no arguments the built-in commands:listing runs - a table of the registered commands:
php bin/console
php bin/console commands:listing
Runtime::register, Runtime::registerList - register commands, Runtime::execute - runs a command processing the $argv attributes.
Command
Commands are built on the Tereta\Console\Interfaces\Command interface: the constructor takes the context, execute() takes the arguments and the PSR-3 output.
The identifier and the description are declared with class attributes:
use Psr\Log\LoggerInterface;
use Tereta\Console\Attributes\Description as DescriptionAttribute;
use Tereta\Console\Attributes\Identifier as IdentifierAttribute;
use Tereta\Console\Contexts\Runtime as RuntimeContext;
use Tereta\Console\Interfaces\Command;
#[IdentifierAttribute('cache:clean')]
#[DescriptionAttribute('Clears the application cache')]
class Clean implements Command
{
public function __construct(private RuntimeContext $context)
{
}
public function execute(array $argv, LoggerInterface $output): void
{
$output->info('Cache is cleaned.');
}
}
Without the Tereta\Console\Attributes\Identifier attribute the identifier is built from the last two namespace segments of the class implementing the Tereta\Console\Interfaces\Command interface:
The Tereta\Console\Attributes\Description attribute declares the command description, when it is omitted the command listing shows No description available.
Context and dependencies
Tereta\Console\Contexts\Runtime - the context holds:
- the command container
Tereta\Console\Containers\Command, constructor attribute ($commands). - the factory
Tereta\Console\Factories\Command, constructor attribute ($factory), - the output service
Tereta\Console\Services\Output, constructor attribute ($output), and the formatting serviceTereta\Console\Services\Format, constructor attribute ($format) - the pool
Tereta\Console\Containers\Pool, constructor attribute$pool- a PSR-11 container for non-standardised configurations, such as databases or anything else that can be described at the environment initialisation level.
For example, a configured ORM or PDO can be put into the pool during bootstrap like this:
$runtime = new Runtime();
$runtime->context->pool->set('orm', $orm);
And taken out inside a command:
$orm = $this->context->pool->get('orm');
Output and formatting
Tereta\Console\Services\Output - a PSR-3 logger implementation:
the emergency, critical, error, warning, alert levels are logged to stderr, while the regular notice, info, debug messages go to stdout.
Tereta\Console\Services\Format - the output formatting service, a tool for formatting tables, boxes and colours;
the width is configured from the terminal when the instance is created, or can be set manually:
$format = $this->context->format;
$format->setWidth($format::getTerminalWidth());
$output->info($format->table($rows));
$output->info($format::box('Done', $format::FONT_GREEN));
The Tereta\Console\Services\Format functions that depend on the output width:
$format->setWidth(int $width): static
$format->getWidth(): int
$format->decoration(string $message, string $color = self::FONT_GREEN): string
$format->table(array $rows, array $titles = [], string $font = ''): string
setWidth- sets the output width in characters,getWidth- returns the current one,Format::DEFAULT_WIDTH(80) by default.decoration- a banner with the logo, the message is split into at most three lines of 52 characters; below a width of 95 characters it returns just the coloured message.table- a table in a pseudographic frame,$titlesoverrides the column headers by the array keys,$fontstyles the whole table; when the table does not fit the width,simpleTableis called; the frame is drawn with unicode only whenLANG/LC_ALLcontainsutf, otherwise+,-,|.
Static functions, not affected by the output width:
Format::getTerminalWidth(): int
Format::simpleTable(array $rows, array $titles, string $font = ''): string
Format::box(string $text, ?string $font = null): string
Format::info(string $message, bool $bold = false): string
Format::warning(string $message, bool $bold = false): string
Format::error(string $message, bool $bold = false): string
Format::bold(string $message): string
Format::splitLines(string $string, int $length): array
getTerminalWidth- the terminal width viatput cols,0when there is noTERMor notpututility.simpleTable- the same table without a frame, columns separated by two spaces, the last column is not padded.box- text in a frame, multiline text is aligned to the longest line.info,warning,error- a coloured message (green, yellow, red) with a line break,$boldadditionally makes it bold.bold- makes the text bold without a line break.splitLines- splits the text into lines of the given length at word boundaries.
Constants: Format::DEFAULT_WIDTH - the default width, Format::FONT_* - ANSI sequences for colour
(FONT_RED, FONT_BRIGHT_GREEN), background (FONT_BACKGROUND_BLUE), style (FONT_BOLD, FONT_UNDERLINE)
and reset (FONT_RESET, FONT_RESET_ALL, FONT_RESET_COLOR, FONT_RESET_BOLD).
License and author
Tereta Alexander tereta.alexander@gmail.com Web: https://tereta.dev Copyright Β©2008-2026 Tereta Alexander License https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
www.ββββββββββββββββββββββββ βββββββββββββββββ ββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββ
βββ ββββββ ββββββββββββββ βββ ββββββββ
βββ ββββββ ββββββββββββββ βββ ββββββββ
βββ βββββββββββ βββββββββββ βββ βββ βββ
βββ βββββββββββ βββββββββββ βββ βββ βββ
.dev