Installation:
composer require wp-cli/php-cli-tools
Add to composer.json under require-dev if only needed for testing/scaffolding.
First Use Case: Display a formatted table in a Laravel Artisan command:
use cli\Table;
$table = new Table(['ID', 'Name', 'Status']);
$table->addRow([1, 'User 1', 'Active']);
$table->addRow([2, 'User 2', 'Inactive']);
$table->display();
Where to Look First:
vendor/wp-cli/php-cli-tools/examples/ for ready-to-use snippets.cli\Table, cli\progress\Bar, and cli\out() for daily use.cli\is_tty() for conditional CLI output logic.Replace echo/var_dump with structured output:
use cli\out;
out('Processing...', 'green');
out('Done!', 'bold green');
Use progress bars for long-running tasks (e.g., migrations, imports):
use cli\progress\Bar;
$bar = new Bar('Migrating data', 100);
for ($i = 0; $i < 100; $i++) {
$bar->tick();
// Simulate work
sleep(0.1);
}
Collect user input in CLI tools:
use cli\prompt;
$confirm = prompt('Overwrite existing file?', 'n');
if ($confirm === 'y') {
// Proceed
}
Display query results or logs:
use cli\Table;
$table = new Table(['User ID', 'Email', 'Role']);
foreach ($users as $user) {
$table->addRow([$user->id, $user->email, $user->role]);
}
$table->display();
Visualize directory/file hierarchies:
use cli\Tree;
$tree = new Tree();
$tree->setData(['folder' => ['file1.txt', 'subfolder' => ['file2.txt']]]);
$tree->display();
Extend Laravel’s Command class with CLI tools:
use Illuminate\Console\Command;
use cli\out;
class MyCommand extends Command {
protected $signature = 'my:command {--force}';
public function handle() {
out('Command executed!', 'yellow');
// ...
}
}
Use cli\Table/cli\progress\Bar in PHPUnit tests:
use cli\Table;
use Tests\TestCase;
class TableTest extends TestCase {
public function testTableOutput() {
$table = new Table(['ID', 'Name']);
$table->addRow([1, 'Test']);
$this->expectOutputRegex('/\|\s*1\s*\|\s*Test\s*\|\s*/');
$table->display();
}
}
Build interactive CLI menus (e.g., for admin tools):
use cli\menu;
$choices = ['Option 1', 'Option 2', 'Quit'];
$choice = menu('Select an option:', $choices, 'Option 1');
Handle Windows/Linux differences:
if (cli\is_windows()) {
// Windows-specific logic
}
Add to composer.json for reusable CLI tasks:
"scripts": {
"test": "phpunit && php-cs-fixer fix --dry-run",
"lint": "php-cs-fixer fix"
}
Extend cli\table\Renderer for custom table styles:
class MyRenderer extends \cli\table\Renderer {
public function renderCell($value) {
return '<span style="color: red;">' . parent::renderCell($value) . '</span>';
}
}
Detect piped vs. interactive output:
if (cli\is_tty()) {
out('Interactive mode: ', 'green');
} else {
out('Piped output: ', 'yellow');
}
Run shell commands with error handling:
use cli\run_command;
$result = run_command('git status');
if ($result['success']) {
out($result['output']);
} else {
err('Git error: ' . $result['error']);
}
cli\is_tty() may return false in CI/CD pipelines even when output is to a terminal.$isTty = !defined('CI') && posix_isatty(STDERR);
cli\is_windows() and adjust rendering logic:
if (cli\is_windows()) {
$bar->setInterval(200); // Slower updates for Windows
}
if (!cli\is_tty()) {
cli\Colors::disable();
}
$table->setColumnWidths([10, 30, 'auto']); // Fixed, fixed, auto
$table->setWrap(true);
grapheme_strlen) may not work on older PHP versions.if (!function_exists('grapheme_strlen')) {
require 'vendor/wp-cli/php-cli-tools/src/cli/fallbacks.php';
}
cli\out('Debug: ' . print_r($variable, true), 'red');
out('TTY: ' . (cli\is_tty() ? 'Yes' : 'No'), 'blue');
$table->setHeaders(['ID', 'Name']);
$table->setRows([['1', 'Test']]);
$table->display();
$bar = new Bar('Test', 5);
$bar->setInterval(50); // Faster updates for debugging
Override cli\table\Renderer for custom styles (e.g., Markdown, HTML):
class MarkdownRenderer extends \cli\table\Renderer {
public function renderHeader() { /* ... */ }
public function renderRow() { /* ... */ }
}
Customize cli\ArgumentParser for project-specific CLI flags:
$parser = new \cli\ArgumentParser();
$parser->addOption('verbose', 'v', 'Enable verbose output');
$args = $parser->parse($_SERVER['argv']);
Extend cli\notify\Notifier for new progress indicators (e.g., ASCII art):
class HeartbeatNotifier extends \cli\notify\Notifier {
public function render($msg) { /* ... */ }
}
Override cli\out() globally via autoloading:
// In a service provider
cli\out::setHandler(function ($msg, $color) {
// Custom logic (e.g., log to file)
echo $msg . PHP_EOL;
});
How can I help you explore Laravel packages today?