Kleine CLI-Dispatcher-Library für PHP.
<?php
require __DIR__ . "/vendor/autoload.php";
use Phore\Cli\CliDispatcher;
use Phore\Cli\Annotation\CliParameter;
class App
{
public function greet(
#[CliParameter("name", "Name der Person")]
string $name
): void {
echo "Hallo {$name}!\n";
}
}
CliDispatcher::addClass(App::class);
CliDispatcher::run($argv);Aufruf:
php app.php app greet --name Matthiasexamples/creating-actions.php– Actions mit der statischenCliDispatcher-APIexamples/shared-scopes.php– gemeinsamer Scope, CLI-Optionsname und eigeneCliApplicationexamples/helper-in.php– Eingaben mitPhore\Cli\Input\Inexamples/helper-out.php– formatierte Ausgabe mitPhore\Cli\Output\Outexamples/helper-nc.php– einfache TUI-Helfer mitPhore\Cli\Ncurses\Ncexamples/helper-clipreset.php– Presets mitPhore\Cli\CliPreset
Phore\Cli\CliDispatcher– registriert Command-Gruppen und startet das DispatchingPhore\Cli\Annotation\CliParameter– beschreibt CLI-ParameterPhore\Cli\Input\In– interaktive EingabenPhore\Cli\Output\Out– Text- und Tabellen-AusgabePhore\Cli\CliPreset– lädt Presets auscli_presets.iniPhore\Cli\Ncurses\Nc– einfache terminalbasierte Form-/Tabellen-Helfer
Weitere Übersicht: .ai-usage-info.md
CliApplication verwaltet eine eigene Command-Registry. run() nimmt wie
CliDispatcher::run() ein argv einschließlich Programmname entgegen und
schreibt die Ausgabe direkt auf die Konsole. Dabei wird kein PHP-Output-Buffer
aktiviert oder verändert. Fehler werden als Exceptions an den Aufrufer
weitergegeben. Die bisherigen statischen CliDispatcher-Aufrufe funktionieren
weiterhin ebenfalls mit direkter Konsolenausgabe.
use Phore\Cli\Annotation\CliParameter;
use Phore\Cli\Annotation\CliScope;
use Phore\Cli\CliApplication;
#[CliScope('project')]
class ProjectCreate
{
public function create(
#[CliParameter('template-dir')] string $templateDir
): void {
echo "Template: {$templateDir}";
}
}
#[CliScope('project')]
class ProjectStatus
{
public function status(): void
{
echo 'Ready';
}
}
$app = new CliApplication();
$app->addClass(ProjectCreate::class);
$app->addClass(ProjectStatus::class);
$app->run(['tool', 'project', 'create', '--template-dir=/tmp/basic']);Ergebnis: Template: /tmp/basic. Ohne CliScope bleibt der kleingeschriebene
Klassenname der Gruppenname. Jede Action verwendet den Konstruktor ihrer
eigenen Klasse. Doppelte Action-Namen im selben Scope und widersprüchliche
Typen gleichnamiger Scope-Optionen führen bei der Registrierung zu einem
Fehler. CliParameter benennt nur die CLI-Option um; die Bindung an den
PHP-Parameter erfolgt weiterhin über dessen PHP-Namen.
CliApplication::run($argv) bestimmt den Programmnamen aus dem Basename
von $argv[0]. Ein registrierter CliScope mit genau diesem Namen ist
automatisch die Programmebene; seine Actions sind ohne Wiederholung des
Programnamens erreichbar. Andere Scopes bleiben eigenständige Gruppen.
Beispielsweise kann das Executable tool die folgenden Klassen registrieren:
#[CliScope('tool')]
class GeneralCommands
{
public function init(): void
{
echo 'Initialized';
}
}
#[CliScope('edit')]
class EditCommands
{
public function create(): void
{
echo 'Created';
}
public function resolve(): void
{
echo 'Resolved';
}
}$app = new CliApplication();
$app->addClass(GeneralCommands::class);
$app->addClass(EditCommands::class);
$app->run($argv);Damit sind tool init, tool edit create und tool edit resolve
möglich, ohne den Programmnamen künstlich in $argv einzufügen. Die
Hilfe unter tool -h zeigt die Actions des impliziten Scopes direkt.
Aufrufe mit explizitem Scope wie tool tool init bleiben möglich.
Ein Executable ohne namensgleichen Scope verwendet weiterhin die
bisherigen expliziten Gruppen.
Ein CliScope kann als Pfad angegeben werden. Dadurch lassen sich beliebig
verschachtelte Sub-Commands registrieren. Constructor-Parameter eines Scopes
werden vor dem nächsten Command ausgewertet und stehen damit für alle darunter
liegenden Commands zur Verfügung.
#[CliScope('ai')]
class AiCommands
{
public function __construct(
#[CliParameter('config-file', 'Configuration file')]
private string $configFile = './config.yml'
) {
}
public function status(): void
{
echo $this->configFile;
}
}
#[CliScope(['ai', 'edit'])]
class AiEditCommands
{
public function __construct(
#[CliParameter('model', 'Model name')]
private string $model = 'default'
) {
}
public function run(): void
{
echo $this->model;
}
}Damit sind zum Beispiel diese Aufrufe möglich:
tool ai --config-file ./ai.yml status
tool ai --config-file ./ai.yml edit --model gpt run
tool ai -h
tool ai edit -hDie Help-Ausgabe zeigt vorhandene Sub-Commands mit [COMMAND] und endet mit
einem Hinweis auf -h, über den die detaillierten Optionen der jeweiligen
Ebene angezeigt werden.
CliCommand benötigt nur einen Namen. Sowohl desc als auch longDesc
sind optional und standardmäßig leer; bei fehlender Beschreibung wird kein
Platzhalter in der Help-Ausgabe ausgegeben.
Nach composer install führt composer test die PHPSpec-Specs aus
(vendor/bin/phpspec run).