beecubu / php-foundation-cli
Simple CLI Framework based on PHP Object Foundation.
v1.6.1
2026-03-12 02:16 UTC
Requires
- php: >=7.1.0
- beecubu/php-foundation-helpers: ^v1.10
Suggests
- readline: *
README
Simple CLI framework based on PHP Object Foundation. It provides:
Consoleutilities for colored output, input helpers, progress UI, and simple charts.- A tiny
Application+ViewControllerstack to build CLI screens/flows.
Requirements
- PHP 7.1+
beecubu/php-foundation-helpers(Composer dependency)- Optional:
ext-readlinefor nicer input handling
Installation
composer require beecubu/php-foundation-cli
Quick Start
<?php
use Beecubu\Foundation\Cli\Console;
Console::title('My CLI App');
Console::line('Hello <green>world</green>!');
Colors
Colors are expressed with simple tags:
<red>text</red>, <green>text</green>, <cyan>text</cyan>, <yellow>text</yellow>, <purple>text</purple>
Background tags:
<b_red>text</b_red>, <b_green>text</b_green>, <b_blue>text</b_blue>, ...
Console Helpers
Output
Console::line('A single line');
Console::lines(['Line 1', 'Line 2']);
Console::title("Main Title\nSubtitle");
Console::section("Section Title");
Console::center('Centered text');
Console::separator();
Console::table([
['Name' => 'Ada', 'Age' => 31],
['Name' => 'Linus', 'Age' => 54],
], [
'align' => ['Age' => 'right'],
'headerColor' => 'brown',
'width' => [
'mode' => 'auto',
],
]);
Console::error('Something went wrong', true);
Console::success('All good');
Console::warning('Be careful');
Console::clear();
ASCII Tables
$rows = [
['Name' => 'Ada', 'Role' => 'Engineer', 'Score' => 98.5],
['Name' => 'Linus', 'Role' => 'Architect', 'Score' => 87],
['Name' => 'Grace', 'Role' => 'Scientist', 'Score' => 91.25],
];
Console::table($rows, [
'align' => [
'Name' => 'left',
'Role' => 'left',
'Score' => 'right',
],
'headerColor' => 'brown',
'width' => [
'mode' => 'max',
'size' => 60,
],
'separators' => [
'header' => true,
'rows' => true,
],
]);
Available options:
Console::table($rows, [
'align' => [
'Name' => 'left',
'Role' => 'center',
'Score' => 'right',
],
'headerColor' => 'brown',
'width' => [
'mode' => 'auto', // auto|min|max
'size' => 100, // only used when mode is min or max
],
'separators' => [
'header' => true,
'rows' => true,
],
]);
align: alignment per column. Allowed values areleft,right, andcenter.headerColor: header text color. Uses the same color names supported byConsole::line(). Default iswhite.width.mode:auto: natural table width based on content.min: expands the table up to the given width if there is free space.max: limits the table to the given width and wraps cell content when needed.fixed: forces the table to exactly the given width (expands if smaller, wraps if larger).
width.size: target total table width in characters.separators.header: enables or disables the header separator. Default istrue.separators.rows: enables or disables separators between rows. Default istrue.
Notes:
- Input rows should be associative arrays.
- Column order is discovered from the first time each key appears.
- Missing values in later rows are rendered as empty cells.
- Header alignment follows the alignment configured for each column.
- In
width.mode = max, long cell content is wrapped to multiple lines automatically.
Input
$name = Console::getString('Your name', false);
$age = Console::getIntValue('Age', 1, 120);
$price = Console::getValue('Price', 0, 9999, true, 9.99);
$ok = Console::getYesNo('Continue?');
$date = Console::getDate('Pick a date');
$dateTime = Console::getDateTime('Pick a date and time');
Interactive Menu
Console::menu() shows an interactive menu where the user navigates with the arrow keys and confirms with Enter. Requires a real TTY (does not work with piped input).
$index = Console::menu('Which environment?', [
'Production',
'Staging',
'Local',
]);
With options:
$index = Console::menu('Action:', ['Create', 'Edit', 'Delete'], [
'activeColor' => 'green', // color of the selected option (default: cyan)
'marker' => '→', // marker character (default: ▶)
'default' => 1, // initially selected index (default: 0)
]);
- Returns the zero-based index of the selected option.
- Arrow up/down cycles through options (wraps around).
- The terminal is left in its original state after selection.
- Works on Unix/macOS. Not supported on Windows.
Options
// Returns array with exactly one true
$options = Console::getOption('Choose', 'a', 'b', 'c');
// Returns index (0-based)
$index = Console::getOptionIndex('Choose', 'a', 'b', 'c');
Progress UI
// Progress bar
Console::progressbar(100, true, 'Starting');
Console::progressbar(10, false, 'Working...');
Console::progressbar(90, false, 'Done');
// Spinner (call repeatedly in a loop)
Console::spinner('Loading...', 3);
Console::spinner(false); // clear
Simple Charts
$data = [
['value' => 0.25, 'color' => 'red'],
['value' => 0.35, 'color' => 'green'],
['value' => 0.40, 'color' => 'blue'],
];
Console::printChartPercentageBar($data);
Application + ViewController
This is a small view stack to build multi-screen CLI apps.
<?php
use Beecubu\Foundation\Cli\Application\Application;
use Beecubu\Foundation\Cli\Application\ViewController;
use Beecubu\Foundation\Cli\Console;
class MainView extends ViewController
{
private $done = false;
public function view(): void
{
Console::title('Main View');
$name = Console::getString('Your name', false);
Console::success("Hello $name");
$this->done = true;
}
public function finished(): bool
{
return $this->done;
}
}
new Application(new MainView());
Navigation
Inside any ViewController you can:
$this->application->pushView($anotherView)to open a new view.$this->application->back()to return to the previous view.$this->application->home()to return to the first view.
When a view reports finished() === true, the application will go back automatically (or exit if it was the only view).