PHPackages                             fi1a/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. fi1a/console

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

fi1a/console
============

Консольные команды на PHP. Аргументы, опции и форматирование

2.2.2(3y ago)11.6k—0%1MITPHPPHP ^7.3 || ^8

Since Nov 5Pushed 3y ago1 watchersCompare

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

READMEChangelog (10)Dependencies (10)Versions (17)Used By (1)

Консольные команды на PHP. Аргументы, опции и форматирование
============================================================

[](#консольные-команды-на-php-аргументы-опции-и-форматирование)

[![Latest Version](https://camo.githubusercontent.com/3bdaf6baf5f4b2598a0ad31ba4a5fa6103a45b88bd3825c234a496732a2955a3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f666931612f636f6e736f6c653f6c6162656c3d72656c65617365)](https://packagist.org/packages/fi1a/console)[![Software License](https://camo.githubusercontent.com/e58ab239d953bea98f62a90e50b31cafa10e136f15df4357d7b711ae8b24b1f7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f666931612f636f6e736f6c653f7374796c653d666c61742d737175617265)](https://github.com/fi1a/console/blob/master/LICENSE)[![PHP Version](https://camo.githubusercontent.com/41081c41ede80b21f3391c98dd8564d1f212f81476c865fff38edcca2a1b7b27/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f666931612f636f6e736f6c653f7374796c653d666c61742d737175617265)](https://php.net)[![Coverage Status](https://camo.githubusercontent.com/0c967d746eb7f4fe28065a3b94d23faa207cd6f4a968535b20fce0310a87cf89/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f7665726167652d3130302532352d677265656e)](https://camo.githubusercontent.com/0c967d746eb7f4fe28065a3b94d23faa207cd6f4a968535b20fce0310a87cf89/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f7665726167652d3130302532352d677265656e)[![Total Downloads](https://camo.githubusercontent.com/921da40b04c492cfe7afecafe9f0a6a5ba11ed58ae72b3cbd492e5d90aad982f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f666931612f636f6e736f6c652e7376673f7374796c653d666c61742d73717561726526636f6c6f72423d6d656469756d76696f6c6574726564)](https://packagist.org/packages/fi1a/console)[![Support mail](https://camo.githubusercontent.com/116fa0d447870a3a6c6c1f4b296c889707a6e30a69c2b28cbe8d0f6f5c3d4920/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61696c2d737570706f7274253430666931612e72752d627269676874677265656e)](mailto:support@fi1a.ru)

Библиотека PHP для реализации команд и красивого форматирования текста в консоли.

Возможности:

- Команды получают автоматическую поддержку --help для вывода справки;
- Поддержка одной или нескольких команд;
- Возможность валидации (проверки) значений передаваемых в качестве аргументов и опций в команду;
- Цветовое оформление в консоли;
- Компоненты реализующие таблицы, списки, деревья и т.д.

Установка
---------

[](#установка)

Установить этот пакет можно как зависимость, используя Composer.

```
composer require fi1a/console
```

Dependency injection
--------------------

[](#dependency-injection)

Контейнер dependency injection из пакета [fi1a/dependency-injection](https://github.com/fi1a/dependency-injection)

Для интерфейсов, в контейнере dependency injection, доступны следующие определения:

- Fi1a\\Console\\IO\\InputArgumentsInterface;
- Fi1a\\Console\\IO\\FormatterInterface;
- Fi1a\\Console\\IO\\ConsoleOutputInterface;
- Fi1a\\Console\\IO\\InputInterface;
- Fi1a\\Console\\IO\\InteractiveInputInterface;
- Fi1a\\Console\\Component\\GroupComponent\\GroupStyleInterface;
- Fi1a\\Console\\Component\\GroupComponent\\GroupComponentInterface;
- Fi1a\\Console\\Component\\ListComponent\\ListStyleInterface;
- Fi1a\\Console\\Component\\ListComponent\\ListComponentInterface;
- Fi1a\\Console\\Component\\PaginationComponent\\PaginationStyleInterface;
- Fi1a\\Console\\Component\\PaginationComponent\\PaginationComponentInterface;
- Fi1a\\Console\\Component\\PanelComponent\\PanelStyleInterface;
- Fi1a\\Console\\Component\\PanelComponent\\PanelComponentInterface;
- Fi1a\\Console\\Component\\ProgressbarComponent\\ProgressbarStyleInterface;
- Fi1a\\Console\\Component\\ProgressbarComponent\\ProgressbarComponentInterface;
- Fi1a\\Console\\Component\\SpinnerComponent\\SpinnerStyleInterface;
- Fi1a\\Console\\Component\\SpinnerComponent\\SpinnerComponentInterface;
- Fi1a\\Console\\Component\\TableComponent\\TableStyleInterface;
- Fi1a\\Console\\Component\\TableComponent\\TableComponentInterface;
- Fi1a\\Console\\Component\\TreeComponent\\TreeStyleInterface;
- Fi1a\\Console\\Component\\TreeComponent\\TreeComponentInterface;

```
di()->get(Fi1a\Console\IO\ConsoleOutputInterface::class)->writeln('Вывод в консоль');
```

Использование
-------------

[](#использование)

### Команды, аргументы и опции в консоли

[](#команды-аргументы-и-опции-в-консоли)

Класс `Fi1a\Console\App` предоставляет удобный интерфейс для добавления команд и запуска приложения.

#### Команды

[](#команды)

Команда должна реализовывать интерфейс `Fi1a\Console\CommandInterface`. Вот пример простой команды.

```
declare(strict_types=1);

namespace Foo\Bar;

/**
 * Простая команда
 */
class BazCommand extends AbstractCommand
{
    /**
     * @inheritDoc
     */
    public function __construct(DefinitionInterface $definition)
    {
        $definition->addOption('time', 't')
            ->default(false)
            ->description('Вывод времени.')
            ->validation()
            ->allOf()
            ->boolean();

        $definition->addArgument('format')
            ->default('H:i:s')
            ->description('Формат вывода времени.');
    }

    /**
     * @inheritDoc
     */
    public function run(
        InputArgumentsInterface $input,
        ConsoleOutputInterface $output,
        InputInterface $stream,
        DefinitionInterface $definition,
        AppInterface $app
    ): int {
        $output->writeln('Пример команды');

        if ($definition->getOption('time')->getValue()) {
            $output->writeln(
                'Серверное время: {{time}}',
                ['time' => date($definition->getArgument('format')->getValue())]
            );
        }

        return 0;
    }

    /**
     * @inheritDoc
     */
    public function description(): ?string
    {
        return 'Тестовая команда baz.';
    }
}
```

В этом примере добавляется опция `time` и аргумент `format` в конструкторе команды. После запуска команды проверяется передана ли опция `time` и если передана, выводит серверное время с указанным форматом `format`. Если формат не передан, метод `getValue`вернет значение указанное по умолчанию с помощью метода `default`.

[![Запуск команды](images/console-command-run.png)](images/console-command-run.png)

В метод `run` вызываемый при запуске команды в качестве аргументов передается:

- `InputArgumentsInterface $input` - входящие аргументы и опции;
- `ConsoleOutputInterface $output` - вывод в консоль;
- `InputInterface $stream` - потоковый ввод из консоли;
- `DefinitionInterface $definition` - доступ к объявленным аргументам и опциям;
- `AppInterface $app` - объект класса `Fi1a\Console\App`, вызвавший данную команду.

#### Использование опций и аргументов

[](#использование-опций-и-аргументов)

В метод `run` передается объект класса `DefinitionInterface $definition`, который можно использовать для доступа к значениям опций и аргументов.

```
$definition->getOption('time')->getValue();
$definition->getArgument('format')->getValue();
```

- Опции передаются с помощью --name=value полного имени или -s value короткого кода;
- Аргументы передаются как строки, разделенные пробелами.

#### Запуск консольного приложения

[](#запуск-консольного-приложения)

Чтобы использовать приложение, нужно вызвать метод `run`. Метод `run` делает следующее:

- Анализирует параметр $argv для определения команды;
- Валидирует опции и аргументы;
- Осуществляет конфигурацию команды;
- Запускает команду на выполнение.

Запуск одной конкретной команды. Данный код запустит команду `\Foo\Bar\BazCommand` на выполнение:

```
declare(strict_types=1);

use Fi1a\Console\App;

$code = (new App())
    ->run(\Foo\Bar\BazCommand::class);

exit($code);
```

Запуск нескольких команд, указанных в первом аргументе. Если передать в качестве первого аргумента название команды `php foo.php qux`, будет запущена команда `\Foo\Bar\QuxCommand`.

```
declare(strict_types=1);

use Fi1a\Console\App;

$code = (new App())
    ->addCommand('baz', \Foo\Bar\BazCommand::class)
    ->addCommand('qux', \Foo\Bar\QuxCommand::class)
    ->run();

exit($code);
```

#### Список команд

[](#список-команд)

Вызов скрипта, который имеет несколько команд без параметров или только с аргументом info, отобразит список доступных команд. Пример:

`php foo.php` или `php foo.php info`

[![Список команд](images/console-info.png)](images/console-info.png)

Описание команды берется из значения, возвращаемого методом `description`.

#### Отображение справки

[](#отображение-справки)

Если вызвать команду с параметром --help (`php foo.php baz --help`), можно увидеть следующую справку по команде:

[![Отображение справки](images/console-help.png)](images/console-help.png)

Описание команды берется из значения, возвращаемого методом `description`.

#### Отображение ошибок

[](#отображение-ошибок)

Допустим, вы вызываете пример `php foo.php baz -t j`:

```
$definition->addOption('time', 't')
    ->default(false)
    ->description('Вывод времени.')
    ->validation()
    ->allOf()
    ->boolean();

$definition->addArgument('format')
    ->default('H:i:s')
    ->description('Формат вывода времени.');
```

Увидете следующее сообщение об ошибке:

[![Сообщения об ошибках](images/console-errors.png)](images/console-errors.png)

Валидация осуществляется с помощью пакета [fi1a/validation](https://github.com/fi1a/validation). Доступны все правила валидации.

```
$definition->addOption('option1')
    ->validation()
    ->allOf()
    ->required()
    ->min(10)
    ->max(20);

$argument = $definition->addArgument('argument1')
    ->multiple();

$argument->multipleValidation()
    ->allOf()
    ->array()
    ->required()
    ->minCount(2);

$argument->validation()
    ->allOf()
    ->required()
    ->min(10)
    ->max(20);
```

- метод `validation` - правила валидации одного значения;
- метод `multipleValidation` - правила валидации множества значений.

### Оформление

[](#оформление)

#### Цветовые схемы (палитра цветов консоли):

[](#цветовые-схемы-палитра-цветов-консоли)

Доступны три цветовые схемы:

- ANSI (4-bit color);
- Extended (8-bit color);
- TrueColor (16.7 million).

Запустить пример с отображением палитры цветов

```
php examples/examples.php colors
```

[![Пример с отображением палитры цветов](images/console-colors.png)](images/console-colors.png)

#### Вывод в консоль

[](#вывод-в-консоль)

Используя цвета в выводе консоли, вы можете оформить разные типы вывода (ошибки, заголовки, комментарии и т. д.).

##### Использование цветовых стилей

[](#использование-цветовых-стилей)

При выводе можно использовать теги, чтобы раскрасить отображаемый текст.

```
...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $output->writeln('foo');
    $output->writeln('bar');
    $output->writeln('bazqux');
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\IO\ConsoleOutputInterface;

$output = di()->get(ConsoleOutputInterface::class);

$output->writeln('foo');
$output->writeln('bar');
$output->writeln('bazqux');
```

Доступны следующие предопределенные стили:

- error;
- success;
- info;
- comment;
- question;
- notice.

Можно определить свои собственные стили, используя метод `addStyle` класса `Fi1a\Console\IO\Formatter`:

```
use Fi1a\Console\IO\Formatter;
use Fi1a\Console\IO\Style\TrueColor;
use Fi1a\Console\IO\Style\TrueColorStyle;

Formatter::addStyle('error', new TrueColorStyle(TrueColor::WHITE, TrueColor::RED));
```

Любой шестнадцатеричный цвет поддерживается для цветов схемы TrueColor. Кроме того, поддерживаются названные цвета, опредяемых константами интерфейса `Fi1a\Console\IO\Style\ColorInterface` (`ColorInterface::BLACK`, `ColorInterface::RED`, `ColorInterface::GREEN` ...).

Если терминал не поддерживает TrueColor или Extended, используется ближайший ANSI цвет.

Доступны параметры оформления: blink, bold, conceal, reverse, underscore. Вы можете установить цвет, фон и параметры непосредственно внутри тега. Поддерживается вложенность стилей.

```
...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $output->writeln('foo');
    $output->writeln('bar');
    $output->writeln('bazqux');
}

...
```

Запустить пример с отображением форматированного вывода

```
php examples/examples.php output
```

[![Пример форматированного вывода в консоль](images/console-output.png)](images/console-output.png)

#### Потоковый ввод из консоли

[](#потоковый-ввод-из-консоли)

Чтение (ввод) из консоли осуществляется методом `read` объекта класса `InputInterface $stream`.

```
...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $value = $stream->read('y');
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\IO\InputInterface;

$stream = di()->get(InputInterface::class);

$value = $stream->read('y');
```

#### Интерактивный ввод из консоли

[](#интерактивный-ввод-из-консоли)

С помощью класса `Fi1a\Console\IO\InteractiveInput`, можно добавить значения для чтения из консоли и получить последующий доступ к введенным значениям. С помощью метода `addValue` добавляем значение для чтения из консоли. Также как для аргументов и опций, доступны валидаторы значений из пакета [fi1a/validation](https://github.com/fi1a/validation)

```
use Fi1a\Console\IO\InteractiveInput;

...

/**
 * @inheritDoc
 * @psalm-suppress PossiblyFalseReference
 * @psalm-suppress MixedMethodCall
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $output->writeln(['', 'Интерактивный ввод', '']);

    $interactive = new InteractiveInput($output, $stream);

    $interactive->addValue('foo')
        ->description('Введите количество от 1 до 10')
        ->validation()
        ->allOf()
        ->min(1)
        ->max(10);

    $bar = $interactive->addValue('bar')
        ->description('Введите строки длиной от 2-х символов')
        ->multiple();

    $bar->multipleValidation()
        ->allOf()
        ->minCount(1)
        ->required();

    $bar->validation()
        ->allOf()
        ->minLength(2);

    $interactive->addValue('baz')
        ->description('Согласны (y/n)')
        ->validation()
        ->allOf()
        ->boolean();

    $interactive->read();

    // Доступ к введенным значениям
    $output->writeln((string) $interactive->getValue('foo')->getValue());
    $output->writeln((string) count((array) $interactive->getValue('bar')->getValue()));
    $output->writeln((string) $interactive->getValue('baz')->getValue());

    return 0;
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\IO\ConsoleOutputInterface;
use Fi1a\Console\IO\InteractiveInputInterface;

$output  = di()->get(ConsoleOutputInterface::class);
$interactive = di()->get(InteractiveInputInterface::class);

$output->writeln(['', 'Интерактивный ввод', '']);

$interactive->addValue('foo')
    ->description('Введите количество от 1 до 10')
    ->validation()
    ->allOf()
    ->min(1)
    ->max(10);

$bar = $interactive->addValue('bar')
    ->description('Введите строки длиной от 2-х символов')
    ->multiple();

$bar->multipleValidation()
    ->allOf()
    ->minCount(1)
    ->required();

$bar->validation()
    ->allOf()
    ->minLength(2);

$interactive->addValue('baz')
    ->description('Согласны (y/n)')
    ->validation()
    ->allOf()
    ->boolean();

$interactive->read();

// Доступ к введенным значениям
$output->writeln((string) $interactive->getValue('foo')->getValue());
$output->writeln((string) count((array) $interactive->getValue('bar')->getValue()));
$output->writeln((string) $interactive->getValue('baz')->getValue());
```

Запустить пример с интерактивным вводом

```
php examples/examples.php interactive
```

[![Интерактивный ввод](images/console-interactive.png)](images/console-interactive.png)

### Компоненты

[](#компоненты)

#### Компонент панели

[](#компонент-панели)

Чтобы нарисовать границу вокруг текста или задать выравнивание, используйте `Fi1a\Console\Component\PanelComponent\PanelComponent`. Компонент панели может быть вложен друг в друга.

```
use Fi1a\Console\Component\PanelComponent\PanelComponent;
use Fi1a\Console\Component\PanelComponent\PanelStyle;
use Fi1a\Console\Component\PanelComponent\PanelStyleInterface;
use Fi1a\Console\IO\Style\ColorInterface;

...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $panelStyle = new PanelStyle();

    $panelStyle->setWidth(40)
        ->setPadding(1)
        ->setBorder('heavy')
        ->setBackgroundColor(ColorInterface::YELLOW)
        ->setBorderColor(ColorInterface::RED)
        ->setColor(ColorInterface::BLACK)
        ->setAlign(PanelStyleInterface::ALIGN_CENTER);

    $panel = new PanelComponent(
        $output,
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
        . 'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
        $panelStyle
    );

    $panel->display();

    return 0;
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\Component\PanelComponent\PanelComponentInterface;
use Fi1a\Console\Component\PanelComponent\PanelStyleInterface;
use Fi1a\Console\IO\Style\ColorInterface;

$panel = di()->get(PanelComponentInterface::class);
$panelStyle = $panel->getStyle();

$panelStyle->setWidth(40)
    ->setPadding(1)
    ->setBorder('heavy')
    ->setBackgroundColor(ColorInterface::YELLOW)
    ->setBorderColor(ColorInterface::RED)
    ->setColor(ColorInterface::BLACK)
    ->setAlign(PanelStyleInterface::ALIGN_CENTER);

$panel->setText('Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
    . 'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.');

$panel->display();
```

Запустить пример с отображением панелей

```
php examples/examples.php panel
```

[![Панели](images/console-panel.png)](images/console-panel.png)

Вы можете изменить стиль границы панели, задав одно из следующих значений:

- ascii;
- double;
- heavy;
- horizontals;
- rounded.

Запустить пример со стилями границ панели

```
php examples/examples.php panel-borders
```

[![Стили границ панели](images/console-panel-borders.png)](images/console-panel-borders.png)

Можно определить свои собственные стили границ, используя метод `add` класса `Fi1a\Console\Component\PanelComponent\BorderRegistry`. Класс стиля границ должен реализовать интерфейс `Fi1a\Console\Component\PanelComponent\BorderInterface`:

```
use Fi1a\Console\Component\PanelComponent\AsciiBorder;
use Fi1a\Console\Component\PanelComponent\BorderRegistry;

BorderRegistry::add(
    'ascii',
    new AsciiBorder()
);
```

#### Компонент группы

[](#компонент-группы)

Чтобы панели были одной высоты и располагались на одной линии, можно использовать компонент группы.

```
use Fi1a\Console\Component\GroupComponent\GroupComponent;
use Fi1a\Console\Component\GroupComponent\GroupStyle;
use Fi1a\Console\Component\PanelComponent\PanelComponent;
use Fi1a\Console\Component\PanelComponent\PanelStyle;

...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $groupStyle = new GroupStyle(40);
    $groupStyle->setPanelSpacing(2);
    $group = new GroupComponent($output, $groupStyle);

    $panelStyle = new PanelStyle();
    $panelStyle->setBorder('heavy')
        ->setPadding(1);

    $panel1 = new PanelComponent(
        $output,
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
        . 'sed do eiusmod tempor incididunt ut '
        . 'labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris '
        . 'nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit '
        . 'in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat '
        . 'non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
        $panelStyle
    );
    $panel2 = new PanelComponent(
        $output,
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
        . 'sed do eiusmod tempor incididunt ut '
        . 'labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris '
        . 'nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit '
        . 'in voluptate velit esse cillum dolore eu fugiat nulla pariatur.',
        $panelStyle
    );
    $panel3 = new PanelComponent(
        $output,
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
        . 'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
        $panelStyle
    );

    $group->addPanel($panel1);
    $group->addPanel($panel2);
    $group->addPanel($panel3);

    $group->display();

    return 0;
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\Component\GroupComponent\GroupComponentInterface;
use Fi1a\Console\Component\PanelComponent\PanelComponentInterface;
use Fi1a\Console\Component\PanelComponent\PanelStyleInterface;

$group = di()->get(GroupComponentInterface::class);

$group->getStyle()->setPanelSpacing(2);

$panelStyle = di()->get(PanelStyleInterface::class);
$panelStyle->setBorder('heavy')
    ->setPadding(1);

$panel1 = di()->get(PanelComponentInterface::class);

$panel1->setStyle($panelStyle);
$panel1->setText('Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
    . 'sed do eiusmod tempor incididunt ut '
    . 'labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris '
    . 'nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit '
    . 'in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat '
    . 'non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.');

$panel2 = di()->get(PanelComponentInterface::class);

$panel2->setStyle($panelStyle);
$panel2->setText('Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
    . 'sed do eiusmod tempor incididunt ut '
    . 'labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris '
    . 'nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit '
    . 'in voluptate velit esse cillum dolore eu fugiat nulla pariatur.');

$panel3 = di()->get(PanelComponentInterface::class);

$panel3->setStyle($panelStyle);
$panel3->setText('Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
    . 'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.');

$group->addPanel($panel1);
$group->addPanel($panel2);
$group->addPanel($panel3);

$group->display();
```

Запустить пример с группой панелей

```
php examples/examples.php group
```

[![Группа панелей](images/console-group.png)](images/console-group.png)

#### Компонент списка

[](#компонент-списка)

Для отображения списка служит компонент `Fi1a\Console\Component\ListComponent\ListComponent`. Поддерживаются вложенные списки.

```
use Fi1a\Console\Component\ListComponent\ListComponent;
use Fi1a\Console\Component\ListComponent\ListStyle;
use Fi1a\Console\Component\ListComponent\ListStyleInterface;
use Fi1a\Console\IO\Style\ColorInterface;

...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $listStyle = new ListStyle();
    $listStyle->setType('upper-alpha')
        ->setMarkerColor(ColorInterface::GREEN);

    $subListStyle = new ListStyle();
    $subListStyle->setType('lower-alpha')
        ->setMarkerColor(ColorInterface::RED)
        ->setPosition(ListStyleInterface::POSITION_OUTSIDE);

    $subList = new ListComponent($output, $subListStyle);

    $subList->addItem('Lorem ipsum dolor sit amet');
    $subList->addItem('Consectetur adipiscing elit');

    $list = new ListComponent($output, $listStyle);

    $list->addItem('Lorem ipsum dolor sit amet');
    $list->addItem('Consectetur adipiscing elit');
    $list->addItem($subList);
    $list->addItem('Sed do eiusmod tempor incididunt');
    $list->addItem('Duis aute irure dolor in reprehenderit');
    $list->addItem('Reprehenderit in voluptate velit');

    $list->display();

    return 0;
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\Component\ListComponent\ListComponentInterface;
use Fi1a\Console\Component\ListComponent\ListStyleInterface;
use Fi1a\Console\IO\Style\ColorInterface;

$subList = di()->get(ListComponentInterface::class);

$subList->getStyle()
    ->setType('lower-alpha')
    ->setMarkerColor(ColorInterface::RED)
    ->setPosition(ListStyleInterface::POSITION_OUTSIDE);

$subList->addItem('Lorem ipsum dolor sit amet');
$subList->addItem('Consectetur adipiscing elit');

$list = di()->get(ListComponentInterface::class);

$list->getStyle()
    ->setType('upper-alpha')
    ->setMarkerColor(ColorInterface::GREEN);

$list->addItem('Lorem ipsum dolor sit amet');
$list->addItem('Consectetur adipiscing elit');
$list->addItem($subList);
$list->addItem('Sed do eiusmod tempor incididunt');
$list->addItem('Duis aute irure dolor in reprehenderit');
$list->addItem('Reprehenderit in voluptate velit');

$list->display();
```

Задать тип маркера можно с помощью метода `setType` класса стиля списка `Fi1a\Console\Component\ListComponent\ListStyle`.

Доступны следующие типы маркеров:

- upper-alpha - алфавитный список заглавных букв (A, B, C, D, E, …);
- square - в качестве маркера выступает квадрат;
- lower-alpha - алфавитный список (a, b, c, d, e, …);
- decimal-leading-zero - порядковый номер с лидирующим нулем (01, 02, 03, 04, 05, …);
- decimal - порядковый номер (1, 2, 3, 4, 5, …);
- circle - в качестве маркера выступает незакрашенный кружок;
- disc - в качестве маркера элементов списка выступает закрашенный кружок.

Запустить пример со списками

```
php examples/examples.php list
```

[![Списки в консоли php](images/console-list.png)](images/console-list.png)

Можно определить свои собственные типы маркеров списков, используя метод `add` класса `Fi1a\Console\Component\ListComponent\ListTypeRegistry`. Класс типа маркера списка должен реализовать интерфейс `Fi1a\Console\Component\ListComponent\ListTypeInterface`:

```
use Fi1a\Console\Component\ListComponent\ListTypeRegistry;
use Fi1a\Console\Component\ListComponent\UpperAlphaListType;

ListTypeRegistry::add('upper-alpha', new UpperAlphaListType());
```

#### Компонент постраничной навигации

[](#компонент-постраничной-навигации)

Если вам необходимо разбить вывод на страницы, можно воспользоваться компонентом постраничной навигации.

Пример:

```
use Fi1a\Console\Component\PaginationComponent\PaginationComponent;
use Fi1a\Console\Component\PaginationComponent\PaginationStyle;
use Fi1a\Console\Component\TableComponent\TableComponent;
use Fi1a\Console\Component\TableComponent\TableStyle;

...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $data = [
        ['Смартфон', '1000', '2', '2000'],
        ['Шкаф', '500', '1', '500'],
        ['Электробритва', '300', '5', '1500'],
        ['Станок', '200', '1', '200'],
        ['Диван', '1200', '1', '1200'],
        ['Кровать', '100', '2', '200'],
        ['Кресло', '300', '3', '900'],
        ['Шифанер', '150', '1', '150'],
        ['Стул', '50', '4', '200'],
        ['Стол', '100', '1', '100'],
    ];

    $tableStyle = new TableStyle();
    $table = new TableComponent($output, $tableStyle);
    $table->setHeaders(['Товар', 'Стоимость', 'Количество', 'Итоговая сумма']);
    $paginationStyle = new PaginationStyle();

    $pagination = new PaginationComponent($output, $stream, $paginationStyle);
    $pagination->setCount((int) ceil(count($data) / 3));
    $page = 1;
    do {
        $rows = array_slice($data, ($page - 1) * 3, 3);
        $table->setRows($rows);
        $table->display();
        $pagination->display();
        $page = $pagination->getCurrent();
    } while ($pagination->isValid());

    $output->writeln('');

    return 0;
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\Component\PaginationComponent\PaginationComponentInterface;
use Fi1a\Console\Component\TableComponent\TableComponentInterface;
use Fi1a\Console\IO\ConsoleOutputInterface;

$data = [
    ['Смартфон', '1000', '2', '2000'],
    ['Шкаф', '500', '1', '500'],
    ['Электробритва', '300', '5', '1500'],
    ['Станок', '200', '1', '200'],
    ['Диван', '1200', '1', '1200'],
    ['Кровать', '100', '2', '200'],
    ['Кресло', '300', '3', '900'],
    ['Шифанер', '150', '1', '150'],
    ['Стул', '50', '4', '200'],
    ['Стол', '100', '1', '100'],
];

$output = di()->get(ConsoleOutputInterface::class);

$table = di()->get(TableComponentInterface::class);
$table->setHeaders(['Товар', 'Стоимость', 'Количество', 'Итоговая сумма']);

$pagination = di()->get(PaginationComponentInterface::class);
$pagination->setCount((int) ceil(count($data) / 3));
$page = 1;
do {
    $rows = array_slice($data, ($page - 1) * 3, 3);
    $table->setRows($rows);
    $table->display();
    $pagination->display();
    $page = $pagination->getCurrent();
} while ($pagination->isValid());

$output->writeln('');
```

Запустить пример c постраничной навигацией

```
php examples/examples.php pagination
```

[![Постраничная навигация](images/console-pagination.png)](images/console-pagination.png)

#### Компонент Progressbar

[](#компонент-progressbar)

При выполнении длительных команд, полезно отображать информацию о ходе выполнения.

Чтобы отобразить сведения о ходе выполнения, используйте `Fi1a\Console\Component\ProgressbarComponent\ProgressbarComponent`:

```
use Fi1a\Console\Component\ProgressbarComponent\ProgressbarComponent;
use Fi1a\Console\Component\ProgressbarComponent\ProgressbarStyle;

...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $progressbarStyle = new ProgressbarStyle();
    $progressbarStyle->setTemplateByName('full');
    $progressbar = new ProgressbarComponent($output, $progressbarStyle);

    $progressbar->start(10);
    do {
        $progressbar->increment();
        $progressbar->display();
        sleep(1);
    } while($progressbar->getProgress() < $progressbar->getMaxSteps());
    $progressbar->finish();
    $output->writeln(['', '']);

    return 0;
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\Component\ProgressbarComponent\ProgressbarComponentInterface;
use Fi1a\Console\IO\ConsoleOutputInterface;

$output = di()->get(ConsoleOutputInterface::class);

$progressbar = di()->get(ProgressbarComponentInterface::class);

$progressbar->getStyle()
    ->setTemplateByName('full');

$progressbar->start(10);
do {
    $progressbar->increment();
    $progressbar->display();
    sleep(1);
} while($progressbar->getProgress() < $progressbar->getMaxSteps());
$progressbar->finish();
$output->writeln(['', '']);
```

Используя метод `setTemplateByName`, можно задать один из предустановленных шаблонов:

- short (`[{{bar}}]`);
- normal (`{{current}}/{{max}} [{{bar}}] {{percent|sprintf("3s")}}%{{if(title)}} {{title}}{{endif}}`);
- time (`[{{bar}}] {{elapsed|sprintf("10s")}} / {{remaining|sprintf("-10s")}}{{if(title)}} {{title}}{{endif}}`);
- memory (`[{{bar}}] {{memory|memory}}{{if(title)}} {{title}}{{endif}}`);
- full (`{{current}}/{{max}} [{{bar}}] {{percent|sprintf("3s")}}% {{elapsed|sprintf("10s")}} / {{remaining|sprintf("-10s")}} {{memory|memory}}{{if(title)}} {{title}}{{endif}}`).

Вы можете добавить свой шаблон, используя метод `add` класса `Fi1a\Console\Component\ProgressbarComponent\ProgressbarTemplateRegistry`:

```
use Fi1a\Console\Component\ProgressbarComponent\ProgressbarTemplateRegistry;

ProgressbarTemplateRegistry::add(
    'normal',
    '{{current}}/{{max}} [{{bar}}] {{percent|sprintf("3s")}}%{{if(title)}} {{title}}{{endif}}'
);
```

Запустить пример c progressbar'ом

```
php examples/examples.php progressbar
```

[![Progressbar](images/console-progressbar.png)](images/console-progressbar.png)

#### Компонент Spinner

[](#компонент-spinner)

Возможности:

- заголовок во время вращения;
- поддержка шаблона (`{{if(title)}}{{title}} {{endif}}{{spinner}} `);
- имеет метод `clear`;
- различный внешний вид и возможность добавить свой spinner.

Внешний вид spinner'а:

- dots;
- line;
- growVertical;
- growHorizontal;
- bar.

Вы можете добавить свой spinner, используя метод `add` класса `Fi1a\Console\Component\SpinnerComponent\SpinnerRegistry`. Добавляемый spinner должен реализовать интерфейс `Fi1a\Console\Component\SpinnerComponent\SpinnerInterface`:

```
use Fi1a\Console\Component\SpinnerComponent\DotsSpinner;
use Fi1a\Console\Component\SpinnerComponent\SpinnerRegistry;

SpinnerRegistry::add('dots', new DotsSpinner());
```

Пример:

```
use Fi1a\Console\Component\SpinnerComponent\SpinnerComponent;
use Fi1a\Console\Component\SpinnerComponent\SpinnerStyle;

...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $spinnerStyle = new SpinnerStyle();
    $spinnerStyle->setTemplate('{{if(title)}}{{title}} {{endif}}{{spinner}} ');

    $spinner = new SpinnerComponent($output, $spinnerStyle);

    $index = 0;
    do {
        if ($index % 1000000 === 0) {
            $title = $spinner->getTitle();
            if ($title) {
                $spinner->clear();
                $output->writeln($title);
            }
            $spinner->setTitle('In progress (' . $index . ')');
        }

        $spinner->display();
        $index++;
    } while ($index < 10000000);
    $output->writeln('');

    return 0;
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\Component\SpinnerComponent\SpinnerComponentInterface;
use Fi1a\Console\IO\ConsoleOutputInterface;

$output = di()->get(ConsoleOutputInterface::class);

$spinner = di()->get(SpinnerComponentInterface::class);

$spinner->getStyle()
    ->setTemplate('{{if(title)}}{{title}} {{endif}}{{spinner}} ');

$index = 0;
do {
    if ($index % 1000000 === 0) {
        $title = $spinner->getTitle();
        if ($title) {
            $spinner->clear();
            $output->writeln($title);
        }
        $spinner->setTitle('In progress (' . $index . ')');
    }

    $spinner->display();
    $index++;
} while ($index < 10000000);
$output->writeln('');
```

Запустить пример

```
php examples/examples.php spinner
```

[![Spinner](images/console-spinner.png)](images/console-spinner.png)

#### Компонент таблицы

[](#компонент-таблицы)

Класс `Fi1a\Console\Component\TableComponent\TableComponent` предназначен для вывода табличных данных на терминал.

Чтобы отобразить таблицу, создайте объект `Fi1a\Console\Component\TableComponent\TableComponent`, добавьте заголовоки с помощью `setHeaders` и строки с помощью `setRows`, а затем выведите на консоль методом `display`:

```
use Fi1a\Console\Component\TableComponent\TableComponent;
use Fi1a\Console\Component\TableComponent\TableStyle;

...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $headers = ['Товар', 'Стоимость', 'Количество', 'Итоговая сумма'];
    $rows = [
        ['Смартфон', '1000', '2', '2000'],
        ['Шкаф', '500', '1', '500'],
    ];

    $tableStyle = new TableStyle();
    $tableStyle->setBorder('ascii')
        ->setWidth(50);

    $table = new TableComponent($output, $tableStyle);
    $table->setHeaders($headers);
    $table->setRows($rows);

    $table->display();

    return 0;
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\Component\TableComponent\TableComponentInterface;

$headers = ['Товар', 'Стоимость', 'Количество', 'Итоговая сумма'];
$rows = [
    ['Смартфон', '1000', '2', '2000'],
    ['Шкаф', '500', '1', '500'],
];

$table = di()->get(TableComponentInterface::class);

$table->getStyle()
    ->setBorder('ascii')
    ->setWidth(50);

$table->setHeaders($headers);
$table->setRows($rows);

$table->display();
```

Если ширина таблицы не задана, то ширина колонок рассчитывается исходя из содержимого ячеек.

Свойства ячейки:

- value - значение;
- colspan - кол-во столбцов ячейки;
- style - стиль `Fi1a\Console\Component\TableComponent\TableCellStyleInterface`.

```
use Fi1a\Console\Component\TableComponent\TableCell;
use Fi1a\Console\Component\TableComponent\TableCellStyle;
use Fi1a\Console\Component\TableComponent\TableCellStyleInterface;

$style = new TableCellStyle();
$style->setAlign(TableCellStyleInterface::ALIGN_CENTER)

$cell = new TableCell([
    'value' => 'foo',
    'colspan' => 2,
    'style' => $style,
]);
```

Вы можете установить стиль границы таблицы, задав одно из следующих значений c помощью метода `setBorder` объекта стиля `Fi1a\Console\Component\TableComponent\TableStyle`:

- none;
- ascii;
- ascii\_compact;
- double;
- double\_compact;
- heavy;
- heavy\_compact;
- horizontals;
- rounded;
- rounded\_compact.

Запустить пример

```
php examples/examples.php table
```

[![Таблицы в консоли](images/console-table.png)](images/console-table.png)

Можно определить свои собственные стили границ, используя метод `add` класса `Fi1a\Console\Component\TableComponent\BorderRegistry`. Класс стиля границ должен реализовать интерфейс `Fi1a\Console\Component\TableComponent\BorderInterface`:

```
use Fi1a\Console\Component\TableComponent\BorderRegistry;

BorderRegistry::add('none', new NoneBorder());
```

#### Компонент отображения дерева

[](#компонент-отображения-дерева)

Класс `Fi1a\Console\Component\TreeComponent\TreeComponent` может генерировать древовидное представление в терминале. Дерево — отличный способ представления содержимого файловой системы или любых других иерархических данных.

```
use Fi1a\Console\Component\TreeComponent\TreeComponent;
use Fi1a\Console\Component\TreeComponent\TreeStyle;

...

/**
 * @inheritDoc
 */
public function run(
    InputArgumentsInterface $input,
    ConsoleOutputInterface $output,
    InputInterface $stream,
    DefinitionInterface $definition,
    AppInterface $app
): int {
    $style = new TreeStyle();
    $style->setWidth(20)
        ->setLine('heavy');

    $tree = new TreeComponent($output);

    $node1 = $tree->addNode('Lorem ipsum dolor', $style);
    $node1->addNode('Ex ea commodo consequat', $style);
    $node2 = $tree->addNode('Consectetur adipiscing elit', $style);
    $node3 = $node2->addNode('Ex ea commodo consequat', $style);
    $node2->addNode('Sunt in culpa qui officia', $style);
    $node3->addNode('Ut aliquip ex ea commodo');
    $node3->addNode('Sunt in culpa qui officia');
    $tree->addNode('Ut enim ad minim veniam', $style);

    $tree->display();

    return 0;
}

...
```

Пример с использованием контейнера:

```
use Fi1a\Console\Component\TreeComponent\TreeComponentInterface;
use Fi1a\Console\Component\TreeComponent\TreeStyleInterface;

$style = di()->get(TreeStyleInterface::class);

$style->setWidth(20)
    ->setLine('heavy');

$tree = di()->get(TreeComponentInterface::class);
$tree->setStyle($style);

$node1 = $tree->addNode('Lorem ipsum dolor', $style);
$node1->addNode('Ex ea commodo consequat', $style);
$node2 = $tree->addNode('Consectetur adipiscing elit', $style);
$node3 = $node2->addNode('Ex ea commodo consequat', $style);
$node2->addNode('Sunt in culpa qui officia', $style);
$node3->addNode('Ut aliquip ex ea commodo');
$node3->addNode('Sunt in culpa qui officia');
$tree->addNode('Ut enim ad minim veniam', $style);

$tree->display();
```

Вы можете установить стиль линии, задав одно из следующих значений c помощью метода `setLine` объекта стиля `Fi1a\Console\Component\TreeComponent\TreeStyle`:

- normal;
- double;
- heavy;
- ascii.

Запустить пример

```
php examples/examples.php tree
```

[![Дерево в консоли](images/console-tree.png)](images/console-tree.png)

Можно определить свои собственные стили линий, используя метод `add` класса `Fi1a\Console\Component\TreeComponent\LineRegistry`. Класс стиля линии должен реализовать интерфейс `Fi1a\Console\Component\TreeComponent\LineInterface`:

```
use Fi1a\Console\Component\TreeComponent\LineRegistry;
use Fi1a\Console\Component\TreeComponent\NormalLine;

LineRegistry::add('normal', new NormalLine());
```

###  Health Score

27

—

LowBetter than 52% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity21

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

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 ~7 days

Total

16

Last Release

1125d ago

Major Versions

1.0.1 → 2.0.x-dev2022-12-04

### Community

Maintainers

![](https://www.gravatar.com/avatar/d4f26c1adaa632741fadf55b1328cbd22ac91282aecfae2027d105df0ddedee4?d=identicon)[fi1a](/maintainers/fi1a)

---

Tags

cliconsolephp

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[nunomaduro/collision

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

4.6k324.1M7.0k](/packages/nunomaduro-collision)[wp-cli/wp-cli

WP-CLI framework

5.1k16.6M256](/packages/wp-cli-wp-cli)[consolidation/annotated-command

Initialize Symfony Console commands from annotated command class methods.

22568.5M16](/packages/consolidation-annotated-command)[chi-teck/drupal-code-generator

Drupal code generator

26946.8M4](/packages/chi-teck-drupal-code-generator)[consolidation/config

Provide configuration services for a commandline tool.

16959.8M14](/packages/consolidation-config)[seld/cli-prompt

Allows you to prompt for user input on the command line, and optionally hide the characters they type

24725.5M14](/packages/seld-cli-prompt)

PHPackages © 2026

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