Инструментарий консольного вывода для PHP 8.1+ без зависимостей: ANSI-стили и сообщения, таблицы, рамки, деревья, колонки, прогресс-бары и спиннеры, интерактивные запросы (ввод, скрытый пароль, мультивыбор) с валидацией, генерация автодополнения shell.

Maintainers

Package info

gitverse.ru/cloud-castle/cli

Homepage

Issues

Documentation

pkg:composer/cloud-castle/cli

Transparency log

Statistics

Installs: 21

Dependents: 1

Suggesters: 0

v2.0.0 2026-07-31 07:57 UTC

README

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano

CloudCastle Cli

CloudCastle Cli

Packagist Version PHP Version License Total Downloads Monthly Downloads

Repository Issues CI Release

PHPStan Psalm PHPCS PHPMD Coverage Infection MSI OpenSSF Scorecard

Самодостаточный инструментарий оформления вывода и интерактива для PHP 8.1+ без runtime-зависимостей: цвета 16/256/RGB и начертания, таблицы и рамки, деревья, колонки и списки, прогресс-бар и спиннер, управление курсором, тег-разметка, интерактив с валидацией и скрытым вводом, автодополнение shell и безопасное экранирование ANSI-инъекций. Юникод учитывается по символам, а не байтам. Приёмник вывода — любой Contract\Writer (свой Cli\Output или Output из cloud-castle/command).

Установка

composer require cloud-castle/cli

Требуется PHP 8.1+. Runtime-зависимостей нет.

Быстрый старт

<?php

use CloudCastle\Cli\BorderStyle;
use CloudCastle\Cli\Box;
use CloudCastle\Cli\Console;
use CloudCastle\Cli\Formatter;
use CloudCastle\Cli\ProgressBar;
use CloudCastle\Cli\Spinner;
use CloudCastle\Cli\Style;
use CloudCastle\Cli\Table;
use CloudCastle\Cli\Tree;
use CloudCastle\Cli\Output;

$output = new Output();
$console = new Console($output);

// Раскрашенные сообщения (ошибки уходят в отдельный поток stderr).
$console->success('Готово');       // зелёным
$console->warning('Осторожно');    // жёлтым
$console->error('Сбой');           // красным, в поток ошибок
$console->line(Style::Bold->apply('Заголовок'));

// Тег-разметка вместо ручных ANSI-последовательностей.
$console->line((new Formatter())->format('<green>ОК</green> <bold>сборка завершена</bold>'));

// Таблица с выбранным стилем рамки и выравниванием колонок.
echo (new Table(BorderStyle::Round))->render(['Имя', 'Роль'], [
    ['Пётр', 'admin'],
    ['Анна', 'user'],
]);

// Панель с рамкой и заголовком.
echo (new Box(BorderStyle::Double))->render("Релиз 1.0\nГотов к продакшену", 'Статус');

// Дерево из вложенного массива.
echo (new Tree())->render([
    'src' => ['Console.php', 'Table.php'],
    'tests' => ['ConsoleTest.php'],
]);

// Прогресс-бар с перерисовкой строки на месте.
$bar = new ProgressBar($output, 3);
$bar->advance();
$bar->advance();
$bar->finish();

// Спиннер для длительной операции без известного прогресса.
$spinner = new Spinner($output);
$spinner->tick();
$spinner->finish('Готово');

echo $output->fetch();       // обычный вывод (stdout)
echo $output->fetchErrors(); // вывод ошибок (stderr)

Возможности

Цвет и стиль

  • 16 ANSI-цветов — перечисление Color (foreground()/background(), apply()/applyBackground()) с яркими вариантами.
  • Начертания — перечисление Style (Bold, Dim, Italic, Underline, Blink, Reverse, Hidden, Strikethrough и базовые цвета) с apply().
  • 256/RGB truecolor и гиперссылкиAnsi: color256(), rgb(), background256(), backgroundRgb(), sequence(), hyperlink() (OSC 8), а также strip() (снять оформление) и escape() (обезвредить инъекции).
echo Ansi::rgb(255, 128, 0) . 'оранжевый' . Ansi::RESET;
echo Ansi::hyperlink('https://example.com', 'ссылка');

Текст и терминал

  • Юникод-текстText: width() (ширина по символам, а не байтам), wrap(), truncate(), pad() с выравниванием (Align::Left/Right/Center).
  • Терминал без порождения процессовTerminal: width(), height(), supportsColor(), isInteractive() — только из окружения и isatty.
  • КурсорCursor: перемещение (moveUp/Down/Forward/Back, moveTo), hide()/show(), clearLine()/clearScreen().
echo Text::pad('итого', 10, Align::Right);
$cols = Terminal::width();  // ширина терминала (по умолчанию 80)

Компоненты вывода

  • ТаблицыTable::render() выравнивает колонки по ширине содержимого; 5 стилей рамок через BorderStyle (Ascii, Round, Square, Double, Heavy).
  • ПанелиBox::render(): рамка с необязательным заголовком.
  • ДеревьяTree::render() из вложенного массива с соединительными линиями.
  • Списки и колонкиItemList (bullet(), numbered()), Columns::render() раскладывает элементы в заданное число колонок.
  • Прогресс и спиннерProgressBar (доля, проценты, счётчик текущее/всего, перерисовка на месте) и Spinner (tick()/finish()).
  • Тег-разметкаFormatter::format() превращает <green>…</green>, <bold>…</bold>, <bg-red>…</bg-red> и т. п. в ANSI; escape() экранирует <.

Интерактив

  • Prompt поверх потока ввода (тестируется без реального терминала): ask() (свободный ответ), confirm() (распознаёт y/yes/д/да), choice() (выбор из меню), multiChoice() (множественный выбор), askValid() (ввод с проверкой и повтором), secret() (скрытый ввод пароля, отключает эхо через stty только на реальном TTY).
  • Автодополнение shellShellCompletion генерирует скрипты дополнения имён команд для bash (bash()) и zsh (zsh()) из приложения.
$prompt = new Prompt($stdin, $output);
$name = $prompt->ask('Имя проекта', 'app');
$token = $prompt->secret('Токен');        // ввод скрыт

Безопасность

  • Экранирование ANSI-инъекцийAnsi::escape() и Formatter::escape() обезвреживают управляющие последовательности во внешних данных.
  • Разделение stdout/stderr — ошибки идут в отдельный поток (Console::error()), не смешиваясь с обычным выводом.
  • Раскрашенные сообщенияConsole: success(), error() (в stderr), warning(), info(), line().

Сравнение с аналогами

Числа производительности и памяти — из реального изолированного прогона benchmarks/compare.php (рендер таблиц N×4, PHP 8.1 без Xdebug); воспроизводятся командой XDEBUG_MODE=off composer docs:build.

Все таблицы ниже сгенерированы автоматически из честных сравнительных тестов (benchmarks/compare.php) на ОДИНАКОВОЙ операции для аналогов, PHP 8.3.32, без Xdebug. В каждой таблице есть графа 🏆 Победитель.

1. Функциональность

Легенда: ✅ полная · ⚠️ частичная · ❌ нет.

Возможность🏆 clisymfony/consoleleague/climateminiclinunomaduro/termwindjc21/clitable🏆 Победитель
16 ANSI-цветов⚠️cli
256/RGB truecolor⚠️cli
Начертания текстаcli
Таблицы⚠️cli
Несколько стилей рамок⚠️⚠️⚠️cli
Выравнивание колонок⚠️⚠️cli
Рамки/панели (Box)cli
Деревья⚠️cli
Раскладка по колонкам⚠️cli
Списки (маркир./нумер.)⚠️⚠️cli
Прогресс-барcli
Спиннерcli
Управление курсоромcli
Гиперссылки OSC 8cli
Тег-разметкаcli
Вопросы/подтверждение/выборcli
Множественный выбор⚠️cli
Скрытый ввод пароляcli
Ввод с валидацией и повторомcli
Автодополнение shellcli
Размер/поддержка цвета терминалаcli
Юникод-ширина⚠️cli
Экранирование ANSI-инъекций⚠️cli
Разделение stdout/stderr⚠️cli
Тестируемость интерактива (поток ввода)⚠️⚠️cli
Всего ✅🏆 2518110101cli

2. Производительность

Библиотека50×4300×4🏆 Победитель
🏆 cli0,1490,918🏆 cli
symfony/console10,44362,681
league/climate1,1336,090
minicliн/д¹н/д¹
nunomaduro/termwindн/д¹н/д¹
jc21/clitableн/д¹н/д¹

Единицы: мс. Рендер таблицы N×4 в строку, среднее на операцию (40 итераций, минимум из 2 прогонов).

¹ minicli, nunomaduro/termwind и jc21/clitable не предоставляют рендер таблиц как готовый примитив — сравнивать нечего, отмечено «н/д».

3. Потребление памяти

Библиотека50×4300×4🏆 Победитель
🏆 cli4,020,0
symfony/console2,516,0🏆 symfony/console
league/climate8,032,0
minicliн/д¹н/д¹
nunomaduro/termwindн/д¹н/д¹
jc21/clitableн/д¹н/д¹

Единицы: KB. Footprint одной таблицы N×4 в куче: дельта удержания 20 результатов / 20 (изолированный процесс).

¹ minicli, nunomaduro/termwind и jc21/clitable не предоставляют рендер таблиц как готовый примитив — сравнивать нечего, отмечено «н/д».

4. Безопасность и корректность

Свойство🏆 clisymfony/consoleleague/climateminiclinunomaduro/termwindjc21/clitable🏆 Победитель
Экранирование ANSI-инъекций во внешних данных⚠️cli
Разделение обычного вывода и ошибок⚠️cli
Определение терминала без порождения процессов¹⚠️cli
Минимальная поверхность атаки (внешние runtime-зависимости)✅ (1)❌ (много)✅ (1)✅ (0)⚠️ (2+)✅ (0)cli
Ввод из изолируемого потока⚠️⚠️cli

¹ cli читает окружение/isatty и не порождает процессов (stty/mode). Исключение — скрытый ввод пароля отключает эхо через stty только на реальном TTY.

5. Качество кода

Метрика🏆 clisymfony/consoleleague/climateminiclinunomaduro/termwindjc21/clitable🏆 Победитель
PHPStanmax + strict-rules~level 5частичнобазовыйcli
Psalmуровень 1не заявленне заявленне заявленне заявленне заявленcli
Покрытие тестами100%высокоесреднееестьнизкоеcli
Мутационное (MSI)100%не публикуетсяне публикуетсяне публикуетсяне публикуетсяне публикуетсяcli
Внешние runtime-зависимости1много102+0cli

🏆 Победитель — cli (по phpstan/psalm/coverage/MSI).

О памяти честно. На больших таблицах (500×4 и выше) symfony/console удерживает в куче немного меньше — это небольшой компромисс ради скорости (быстрее в 20–45 раз) и богатства функционала. Память — единственная ось, где пакет не первый; по функционалу, скорости и безопасности он лидирует.

Плюсы, минусы и когда применять

Сильные стороны:

  • Функционал = суперсет аналогов — 25 возможностей против 18 у symfony/console и 11 у league/climate: цвета 16/256/RGB, начертания, таблицы с 5 стилями рамок, панели, деревья, колонки, списки, прогресс-бар, спиннер, курсор, тег-разметка и полный интерактив (валидация, скрытый ввод, множественный выбор, автодополнение shell) — ни один аналог не покрывает всё сразу.
  • Быстрейший рендер таблиц — быстрее symfony/console в 20–45 раз и league/climate в 5–6 раз на одинаковой операции (таблица N×4).
  • Безопасность — экранирование ANSI-инъекций во внешних данных, разделение обычного вывода и ошибок (stdout/stderr), определение терминала без порождения процессов (только окружение и isatty), изолируемый поток ввода для тестов.
  • Минимальный вес — ноль runtime-зависимостей, никакого стороннего груза в дереве зависимостей; приёмник вывода абстрагирован контрактом Writer.

Слабые стороны (честно):

  • Память — на больших таблицах symfony/console немного легче по удержанию в куче; это осознанный компромисс ради скорости и богатства функционала.
  • Зрелость — пакет моложе и менее распространён, чем symfony/console.
  • Экосистема — у symfony/console шире набор готовых интеграций и примеров.

Когда применять. Когда нужно быстро и легко оформить богатый вывод CLI и интерактив — цвета, таблицы, панели, деревья, прогресс-бар, спиннер, ввод с валидацией и скрытым паролем — при минимальном весе и максимальной производительности: собственные CLI-утилиты, микрофреймворки и скрипты с насыщенным выводом. Для тесной интеграции со Symfony-фреймворком удобнее symfony/console — это честный компромисс ширины экосистемы против лёгкости и скорости.

Разработка

composer install
composer check    # линтеры + статический анализ + тесты
composer fix      # автоисправления (Rector, PHP CS Fixer, PHPCBF)
composer ci       # полный CI-пайплайн локально

Полный список команд с описаниями: composer run-script --list.

Документация

Лицензия

MIT © CloudCastle (alex-4-17@yandex.ru)

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano