Jede Applikation benötigt eine Setup-Routine, so auch das GP-Blog. Diese wird die benötigte Datenbankstruktur mit Hilfe der DatabaseSchema-Komponente einrichten und Konfigurationsinformationen vom Benutzer abfragen und speichern, wobei die ConsoleTools-Komponente unterstützt.
18 Setup
Zur Abstraktion des Aufbaus von Queries, wie in Kapitel 6, »Datenbankanbindung«, gezeigt, und dem persistenten Speichern von Objekten aus Kapitel 7, »ORM mit PersistantObject«, kommt die DatabaseSchema-Komponente. Ihre Stärke ist es, das Schema einer Datenbank, also die Tabellenstruktur, abstrakt zu speichern und in einer beliebigen, im Rahmen der im Paket verfügbaren Backend-Handler, anderen Datenbank wiederherzustellen. In den Beispielen dieses Kapitels wird zunächst ein einfaches Konsolenprogramm entwickelt, das das Datenbankschema der GP-Blog-Anwendung ausliest und in einem XML-Format speichert. Anschließend folgt das eigentliche Setup-Programm, das unter anderem das gespeicherte Schema zurück in die Datenbank schreibt. Dies macht das Schema portabel zwischen verschiedenen Datenbanksystemen und erleichtert das spätere Einpflegen von Änderungen am Schema.
Die ConsoleTools-Komponente wird dabei zur Unterstützung verwendet, um eine interaktive Anwendung auf der Konsole zu schreiben. PHP macht Ihnen die Arbeit auf der Konsole nicht einfach, wenn man HTML als Gegenstück betrachtet. Die ConsoleTools-Komponente versucht hier Abhilfe zu schaffen, indem sie Klassen zur Ausgabeformatierung von Texten, zur Verarbeitung von Optionen und Argumenten sowie ein rudimentäres Dialogsystem zur Interaktion mit dem Benutzer anbietet. Hinzu kommen die Darstellung von Tabellen auf der Konsole sowie Fortschritts- und Aktivitätsanzeigen.
18.1 Architektur 

Bevor Sie konkrete Beispiele sehen, soll an dieser Stelle die Architektur der beiden verwendeten Komponenten kurz vorgestellt werden. Wir versuchen uns dabei auf das Wesentliche zu beschränken. Denn insbesondere die Möglichkeiten der ConsoleTools-Komponente verleiten geradezu dazu, sie alle vorstellen zu wollen, was aber den Rahmen dieses Buches sprengen würde. Daher wird insbesondere bei dieser Komponente die Erläuterung der Architektur durch ein einfaches Beispiel ersetzt.
18.1.1 DatabaseSchema 

Der Name dieser Komponente ist sprichwörtlich Programm, denn bei ihr dreht sich alles um Datenbankschemata. Im Sinne von relationalen Datenbanken beschreibt ein Datenbankschema die Menge der Relationen. Genauer bedeutet dies die Abbildung der Tabellenstruktur, denn mit Relationen sind keineswegs die Beziehungen zwischen den Daten, sondern die Tabellenstruktur gemeint. [http://en.wikipedia.org/wiki/Relational_model]
| Das Datenbankschema |
|
Unter dem Schema einer Datenbank versteht man gemeinhin ihre Tabellenstruktur, wenn auch die mathematisch korrekte Definition [http://cvs.php.net/viewcvs.cgi/pear/MDB2_Schema/docs/xml_schema_documentation.html?view=co] leicht davon abweicht. Die DatabaseSchema-Komponente erlaubt Ihnen, das Schema einer Datenbank in abstrakter Form in einer Datei abzuspeichern und in einer beliebigen anderen Datenbank wiederherzustellen. |
|
Zur Speicherung werden von der Komponente DatabaseSchema zwei Formate unterstützt. Zum einen kann die Komponente Schemata im XML-Format2 der PEAR-Komponente MDB2 [http://pear.php.net/package/mdb2]speichern, was eine gute Interoperabilität der Komponenten garantiert. Zum anderen ist es möglich, die Informationen als PHP-Array zu speichern, sodass dieses lediglich inkludiert werden muss, was einen sehr schnellen Zugriff auf die Daten gewährleistet. |
Die DatabaseSchema-Komponente stellt eine Klassensammlung bereit, die es Ihnen ermöglicht, das Schema einer Datenbank auszulesen, es in verschiedenen Formaten abzuspeichern, von dort wieder zu lesen und anschließend in eine Datenbank zu schreiben.
Schemata
Die Hauptklasse des DatabaseSchema-Pakets heißt ezcDbSchema. Ihre Instanzen stellen das Schema einer Datenbank als Objektbaum dar. Wie dieser Baum intern aufgebaut ist, ist für die Verwendung nicht relevant. Das Schema repräsentiert die Tabellen einer Datenbank in abstrakter Form, um Unterschiede zwischen relationalen Datenbankmanagementsystemen auszugleichen. Ähnlich wie bereits bei der Database-Komponente gesehen, bringt ein solcher Abstraktionsschritt immer auch Einschränkungen mit sich.
Im Falle von DatabaseSchema bedeutet dies grundsätzlich, dass spezielle Datentypen einiger Datenbanksysteme, wie Aufzählungstypen oder Ähnliche, nicht unterstützt werden. Lediglich die abstrakten Datentypen integer, boolean, float, decimal, timestamp, time, date, text, blob und clob werden unterstützt, für die jeder Datenbank-Handler eine entsprechende Übersetzung kennt.
Weiterhin kennt ezcDbSchema nur eingeschränkte Indexmethoden. Nur das reine Setzen eines Index auf einer Menge von Feldern wird unterstützt, wodurch diesen lediglich eine Einzigartigkeit oder eine Primärschlüsseleigenschaft zugewiesen werden kann.
Die ezcDbSchema-Klasse stellt eine Vielzahl von Methoden bereit. Unter anderem einige zur Manipulation ihrer internen Datenstruktur wie createNewField(), createNewIndex(), createNewIndexField() und createNewTable(). Auf diese Methoden werden wir nicht weiter eingehen. Interessanter sind für Sie an dieser Stelle die statischen Methoden zur Erzeugung von Schemaobjekten.
Die statische Methode createFromFile() erwartet als Parameter das Format, in dem das zu ladende Schema vorliegt, und den Dateinamen der zu ladenden Schemadatei.
Analog zu createFromFile() arbeitet die Methode createFromDb(), die allerdings nur einen Parameter erwartet: Eine Instanz von ezcDbHandler, der Datenbankverbindungsklasse aus der Database-Komponente. Anhand dieser kann die Methode feststellen, um welche Datenbank es sich handelt und den entsprechenden Handler instanziieren, der dann die Leseoperation übernimmt.
Parallel zu diesen beiden Methoden existieren writeToFile() und writeToDb(), die analoge Parameter erhalten. Nicht ganz so interessant, aber vielleicht irgendwann einmal hilfreich für Sie ist die Methode convertToDDL(). Sie bekommt eine Datenbankverbindung übergeben und gibt ein Array mit SQL-Befehlen zurück, die das Schema in der gegebenen Datenbank erzeugen.
Schema-Diff
Neben der Darstellung der Datenbankstruktur können Sie auch den Unterschied zwischen zwei Ständen eines Schemas darstellen. Dazu dient die Klasse ezcDbSchemaDiff.
Damit wird es Ihnen möglich, den Unterschied zwischen zwei Datenbankstrukturen zu erfassen, weiterzugeben und an anderer Stelle anzuwenden. Ähnlich funktioniert das GNU-Programm diff, das den Unterschied zwischen zwei Dateien ausgeben kann. Speichert man diese Ausgabe und transportiert sie woanders hin, so kann dort mittels patch auf einer der Dateien und dem gespeicherten Unterschied die andere Datei wiederhergestellt werden.
Ähnlich wie Instanzen von ezcDbSchema können Schemaunterschiede ebenfalls aus Dateien gelesen und in diese geschrieben werden. Hierzu dienen createFromFile() bzw. writeToFile(). Allerdings können sie nicht aus ihnen gelesen werden. Die Signaturen der Methoden entsprechen denen der Schema-Klasse. Die Methode zum Schreiben in die Datenbank trägt den Namen applyToDb(), um klarzustellen, dass es sich um eine Änderung der aktuellen Struktur einer Datenbank handelt.
Ein Diff zweier Schemata erzeugen Sie mit Hilfe der Klasse ezcDbSchemaComparator, die eine einzige statische Methode bereitstellt: compareSchemas(). Das erste ihr übergebene Schema stellt den älteren Stand, das zweite den neueren dar. Als Rückgabe erhalten Sie ein ezcDbSchemaDiff-Objekt, das Sie speichern oder direkt anwenden können. Auch das Differenzobjekt stellt eine convertToDDL()-Methode bereit, ganz so wie Schemaobjekte dies tun.
18.1.2 Die ConsoleTools-Komponente 

Diese Komponente ist eine der vielschichtigsten und stellt eine Menge größtenteils unabhängiger Klassen zur Verfügung, die verschiedenste Aufgaben übernehmen können. Zentral ist die Klasse ezcConsoleOutput sowie deren zugehörige Klassen, ohne die kaum ein Shell-Programm auf Basis von eZ Components zu finden sein wird. Sie erlaubt es unter anderem, formatierten Text auszugeben, automatische Zeilenumbrüche einfließen zu lassen und Ausgaben an die Standardfehlerausgabe zu senden.
Daneben bietet die Komponente eine Klasse zur Behandlung von Ein- und Ausgaben des Benutzers via Optionen und Argumenten an. Unter Optionen versteht die Komponente dabei alle Parameter für ein Programm, die mit der Zeichenfolge -- oder – starten. Argumente sind entsprechend alle weiteren Parameter, die nach den Optionen folgen. ezcConsoleInput erlaubt es, Optionen und Argumente zu konfigurieren, parst diese und generiert auf Wunsch automatisch passende Hilfetexte, die bei fehlenden Parametern sowie auf Wunsch des Benutzers angezeigt werden können.
Weiterhin gibt es die Klasse ezcConsoleTable, die auf ezcConsoleOutput basiert und zur Erzeugung und Ausgabe von ASCII-Tabellen auf der Konsole dient. Die Klasse ermöglicht es Ihnen, in einer Array-artigen Struktur eine Tabelle mit Daten zu füllen, mit Hilfe von Attributen zu formatieren und auszugeben.
Das Paket stellt drei Klassen zur Darstellung des Fortschritts in der Applikation bereit: ezcConsoleProgressbar erzeugt einen Fortschrittsbalken, wie Sie ihn aus GUI-Programmen kennen. Der Fortschrittsmonitor ezcConsoleProgressMonitor ermöglicht es Ihnen, einen Fortschritt zu signalisieren und bei jedem Schritt Statusinformationen auszugeben. Hierbei müssen Sie aber auf den Balken verzichten. Schließlich erlaubt ezcConsoleStatusbar es Ihnen, eine große Zahl von Fortschrittsindikatoren darzustellen. Dabei ist im Unterschied zu den beiden anderen Klassen unbedeutend, wie groß der Fortschritt ist.
Die neueste Erweiterung der Sammelkomponente für Konsolenaufgaben ist ein einfaches Dialogsystem. Es erlaubt Ihnen, im Verlauf einer Applikation mit dem Benutzer zu interagieren, indem Sie Fragen- und Menü-Dialoge darstellen lassen und die Anwendung solange blockieren, bis eine Antwort eintrifft.
Alle soeben angesprochenen Bereiche der Komponente sollen im Folgenden anhand eines Beispiels gezeigt werden, sofern sie später nicht im GP-Blog erscheinen. In diesem Fall erläutern wir die Architektur der Klasse detailliert, damit Sie später im Beispielcode die Vorgänge genauer verstehen.
Ausgaben
Die Klasse ezcConsoleOutput kümmert sich um Ausgaben, indem sie Methoden wie outputText() und outputLine() bereitstellt. Beide erwarten den darzustellenden Text als Parameter sowie den optionalen Namen eines zu verwendenden Formats und ein mögliches $verbosityLevel. Die Methode outputLine() fügt der Textausgabe ein zum jeweiligen System passendes Zeichen zur Anzeige eines Zeilenumbruchs an.
Geben Sie diesen beiden Methoden keinen Formatnamen mit auf den Weg, so wird automatisch das Format default benutzt, das standardmäßig keinerlei Formatierungen auf den Text anwendet.
Ein Hinweis: Die meisten in den folgenden Zeilen vorgestellten Formatierungen haben auf Windows-Systemen keinen Effekt. Die Klasse erkennt Windows-Systeme automatisch und schaltet Formatierungen, die auf diesem System nicht unterstützt werden, ab.
Formatierungen sind benannte Sets von Stilattributen, die auf einen Ausgabetext angewendet werden können. Neben der Wahl von Vordergrund- und Hintergrundfarbe kann der Text fett, kursiv und blinkend angezeigt werden. Zusätzlich wird das Ausgabeziel als Formatierungseinstellung gespeichert, das im Normalfall die Standardausgabe ist, gelegentlich aber auch die Standardfehlerausgabe.
Formatierungen können auf einfache Weise erzeugt werden: Objekte von ezcConsoleOutput haben ein Attribut namens $formats, das für die Verwaltung von Formaten zuständig ist. Rufen Sie auf diesem Objekt ein Attribut mit einem beliebigen Namen auf, so erzeugen Sie damit automatisch eine neue Formatdefinition unter diesem Namen. Bei dieser Definition handelt es sich um ein Objekt der Klasse ezcConsoleOutputFormat, die die Verwaltung der eigentlichen Formatierung übernimmt. Das automatische Erzeugen neuer Objekte erfolgt mit einem Mechanismus ähnlich den Virtual Properties.
Instanzen von ezcConsoleOutputFormat haben verschiedene Attribute, um Text zu formatieren. Alle sind mit einem sinnvollen Standardwert belegt, der den Einstellungen des Formats default entspricht. Die Attribute $color und $bgcolor bestimmen Vordergrund- bzw. Hintergrundfarbe des Textes über den Namen der Farbe. Welche Namen gültig sind, können Sie der Tabelle in der Onlinedokumentation [http://ezcomponents.org/docs/api/latest/ConsoleTools/ezcConsoleOutputFormat.html ] zu dieser Klasse entnehmen. Die Standardeinstellung für beide Attribute ist die Spezialfarbe default, die dem Standardfarbwert der aktuellen Konsole entspricht.
Ein weiteres Attribut ist $style, das ein zu Beginn leeres Array von Styling-Informationen enthält. Hier können Sie eine beliebige Kombination von Stilparametern eintragen, die sich ebenfalls durch einen Namen identifizieren lassen. Möglich sind unter anderem bold für Fettdruck, underlined für Unterstreichung und italic für Kursive. Für eine komplette Liste verweisen wir wieder auf die Onlinedokumentation zur Klasse ezcConsoleOutputFormat.
Die letzte Formateinstellung dieser Klasse ist $target: das Ziel der Ausgabe. Der hier eingetragene Standardwert ezcConsoleOutput::TARGET_OUTPUT sollte Sie in den meisten Fällen zufriedenstellen, denn damit wird Ihr Text zunächst in den PHP-Output-Buffer geschrieben und anschließend an die Standardausgabe weitergeleitet. Alternativ können Sie ezcConsoleOutput::TARGET_STDOUT verwenden, das den Ausgabepuffer umgeht und direkt in die Standardausgabe schreibt, oder analog ezcConsoleOutput::TARGET_STDERR für die Standardfehlerausgabe.
Beispielsweise erzeugt der folgende Aufruf einen Text in fetter Schrift und roter Farbe in der Fehlerausgabe:
$output = new ezcConsoleOutput();
$output->formats->error->color = 'red';
$output->formats->error->style = array( 'bold' );
$output->formats->error->target =
ezcConsoleOutput::TARGET_STDERR;Listing 18.1 Ein einfaches Format erzeugen
Das Format error können Sie von nun an mit den Ausgabemethoden des ezcConsoleOutput-Objekts verwenden. Die Konstanten zur Definition des Ausgabeziels sind lediglich Wrapper um PHP-Stream-Wrapper [http://php.net/stream ] wie php://stdout zum Schreiben in die Standardausgabe unter Umgehung des Ausgabepuffers. Sie können hier also theoretisch jeden beliebigen Stream adressieren, zum Beispiel eine Datei, um Fehlerausgaben zu loggen.
Neben den Ausgabemethoden stellt ezcConsoleOutput noch die Methode formatText() bereit, die einen übergebenen Text mit den benötigten Formatzeichen für das übergebene Format zurückgibt, anstatt ihn auszugeben. Hierbei müssen Sie beachten, dass sich Texte unter Umständen nicht so einfach ineinander schachteln lassen. Hierzu müssen Sie die Blöcke einzeln formatieren und dann zusammensetzen; sie können bereits formatierte Texte nicht einfach ineinander einsetzen.
Nützlich sind die Optionen der ezcConsoleOutput-Klasse, die Sie wie immer im Attribut $options einer Instanz erreichen, die ein Objekt der Klasse ezcConsoleOutputOptions trägt. Bei der Konfiguration des Ausgabeobjekts kommt unter anderem der bereits erwähnte Parameter $verbosityLevel (frei übersetzt: »Maß der Geschwätzigkeit«) der Ausgabemethoden ins Spiel.
Es existiert eine gleichnamige Option, mit deren Hilfe Sie steuern können, wie viele Informationen ausgegeben werden sollen. Das Standard-Verbosity-Level ist 1 für beide, womit alle Ihre Ausgaben beim Benutzer ankommen. Reduzieren Sie den Wert der Option $verbosityLevel auf 0, würde keine der Ausgaben mehr beim Benutzer ankommen. Im Gegenzug werden sie allerdings bei allen Werten größer als 1 ausgegeben. Die Verbosity-Level-Option bestimmt also den maximalen Level, bis zu dem Nachrichten ausgegeben werden. Die weitere Option $autobreak bestimmt, ob und wann ausgegebene Zeilen automatisch umgebrochen werden sollen. Setzen Sie einen Wert von 0, was dem Standardwert entspricht, werden Ihre Texte nicht automatisch umgebrochen, sondern dies geschieht durch die Konsole. Ein sinnvoller Wert kann hier 80 Zeichen sein. Jedoch ist es leider nicht möglich, die tatsächliche Breite der Konsole abzufragen.
Das Formatieren von Texten können Sie mit der booleschen Option $useFormats beeinflussen. Der Standardwert true gibt die Texte, zumindest auf Unix-Systemen, formatiert aus. Setzen Sie false, wird auch hier nicht formatiert.
Damit haben Sie den ersten und bereits einen der komplexesten Teile der Komponente ConsoleTools kennengelernt.
18.1.3 Eingaben 

Unter Eingaben versteht die ConsoleTools-Komponente alles, was dem Programm beim Aufruf übergeben wird, wobei die zuständige Klasse ezcConsoleInput zwischen Optionen und Argumenten unterscheidet. Zusammengenommen bezeichnen wir diese als Parameter des Programms. Optionen sind hierbei solche Parameter, die mittels der Zeichenfolgen – oder -- gekennzeichnet werden. Sie folgen direkt nach dem Namen des Programms auf der Konsole, sind benannt und können optional Werte übernehmen. Im Anschluss an die Optionen folgen die Argumente des Programms, die keinen offiziellen Namen haben und einfach in ihrer Reihenfolge angegeben werden.
Ein typischer Programmaufruf, der damit behandelbar wäre, sähe so aus:
$ setup.php -d 'mysql://gpblog@localhost/gpblog' /my/path/to/blog
Listing 18.2 Typischer Programmaufruf, wie er durch ezcConsoleInput verarbeitet würde
In diesem Beispiel ist setup.php der Name des Programms, das vorangestellte Dollarzeichen $ symbolisiert lediglich die Konsole. Der mit dem Parameter -d übergebene Optionswert ist ein Data-Source-Name für eine MySQL-Datenbank. Der auf den Parameter folgende Pfad ist ein Argument, da eine Option lediglich einen Wert übergeben bekommen kann.
Von den Optionen
Optionen werden mit Hilfe der Klasse ezcConsoleOption definiert, deren Instanzen über die Methode registerOption() einem ezcConsoleInput-Objekt hinzugefügt werden können. Ein Objekt dieser Klasse enthält alle Informationen, die zu einer Option benötigt werden. Diese sind primär der Kurz- und Langname der Option, welche die Aufrufweise bestimmen. Der Kurzname ist beim Aufruf des Programms über einen einfachen Bindestrich verfügbar, der alternative Langname mit zwei Bindestrichen. Per Konvention sollte die kurze Variante nur einen Buchstaben haben und eine sprechende Abkürzung der langen Variante darstellen. Die lange Variante sollte sprechend und deklarativ sein und kann zum besseren Verständnis weitere Bindestriche enthalten. Ein Beispiel wäre der Kurzname -d mit dem Langnamen –data-source-name, wobei im Konstruktor von ezcConsoleOption lediglich d und data-source-name anzugeben wären.
Alle weiteren Einstellungen sind optional und haben sinnvolle Standardwerte. Die Option $type bestimmt den Typ der Option und damit, ob er einen Wert übergeben bekommt. Der Standardwert ist hier ezcConsoleInput::TYPE_NONE, also kein Wert. Möglich sind auch ezcConsoleInput::TYPE_INT für Integer-Werte und ezcConsoleInput::TYPE_STRING für alle anderen Werte. Wenn Sie für eine Option bestimmt haben, dass sie einen Wert erwartet, können Sie zusätzlich die Einstellung $default setzen. Gibt der Benutzer zwar die Option, aber keinen Wert an, so wird dieser Standardwert verwendet.
Der Wert der Einstellung $multiple bestimmt, ob eine Option mehrfach im Aufruf vorkommen kann. Ist dies der Fall, gibt nach der Verarbeitung das Attribut $value ein Array von Werten aus statt eines verarbeiteten Wertes oder false für eine nicht übergebene Option. Wollen Sie eine Option nicht mehr optional gestalten, sondern erzwingen, dass sie gesetzt ist, so markieren Sie sie als $mandatory. Setzen Sie also das Flag auf den Wert true.
Da auch bei nicht optionalen Optionen meist erwünscht ist, dass auf sie verzichtet werden kann, falls die Hilfeoption (meist -h / --help) gesetzt ist, kann man diese explizit mittels $isHelpOption markieren. Ist eine solche Option gesetzt, tritt keine weitere Regel in Kraft. Das Flag $arguments ermöglicht es abzuschalten, dass Ihre Anwendung Argumente akzeptiert, sobald eine bestimmte Option gesetzt ist. Die Standardeinstellung ist hier true, da Argumente immer erlaubt sein sollten.
Haben Sie eine Hilfeoption, so können Sie deren Ausgabe entweder selbst generieren oder sie der ezcConsoleInput-Instanz überlassen. Wollen Sie diesen Vorteil ausnutzen, so setzen Sie für Ihre Optionen auch die Attribute $shorthelp und $longhelp. Beide sollten einen Hilfetext enthalten, wobei $shorthelp eine kurze Erklärung und $longhelp etwas ausführlichere Erläuterungen enthält.
Von den Argumenten
Argumente sind im Gegensatz zu Optionen für den Benutzer nicht durch einen Namen gekennzeichnet, sondern können lediglich durch ihre Reihenfolge bestimmt werden. Aus diesem Grund werden Argumente meist sparsamer eingesetzt als Optionen.
Je nach den Anforderungen stellt ezcConsoleInput zwei verschiedene Wege bereit, Argumente zu behandeln. Die einfache Variante ist ursprünglich der einzige Weg gewesen, bevor im aktuellen Release die neue Variante hinzukam. Konfigurieren Sie Argumente nicht weiter, so stehen nach der Bearbeitung der Optionen alle übergebenen Argumente über die Methode getArguments() bereit. Sie haben allerdings keinen Einfluss darauf, dass ein bestimmtes Argument gesetzt wird, welchen Typ es hat oder dass ein Hilfetext angezeigt wird.
Wollen Sie einen ähnlichen Komfort genießen wie bei Optionen, benötigen Sie eine Instanz von ezcConsoleArguments und müssen diese Ihrer ezcConsoleInput-Instanz im Attribut $argumentsDefinition zuweisen. In dieser Instanz können Sie nun Argumente definieren und mittels getArguments() in deren Reihenfolge erhalten. Sie haben nun Einfluss auf die Argumente, die durch Instanzen von ezcConsoleArgument repräsentiert werden, ähnlich wie ezcConsoleOption.
Registriert werden Argumente im $argumentsDefinition-Objekt mittels Array-Semantik: $in->argumentsDefinition[0] ist das erste Argument. Sie können ebenfalls über Argumente iterieren (foreach) sowie auf registrierte Argumente über deren Namen zugreifen: $in->argumentsDefinition['dsn'].
Argumente haben (optional) einen Namen. Da dieser keine Bedeutung für das Programm besitzt, können Sie einfach ein leeres Argument erzeugen. Lediglich die Reihenfolge ist ausschlaggebend. Allerdings sollten Sie einen Namen vergeben, falls Sie planen, die Hilfegenerierung zu verwenden, denn dort wird wiederum $name verwendet. Alle weiteren optionalen Einstellungen können Sie dem Namen direkt an erster Stelle übergeben.
Wie bei Optionen können Argumente einen Typ haben. Das Attribut $type ist hierfür zuständig, und die gleichen Konstanten auf ezcConsoleInput finden als Werte Verwendung. ezcConsoleInput::TYPE_NONE ist allerdings wenig zweckmäßig, weshalb der Standardwert hier ezcConsoleInput::TYPE_STRING lautet.
Mit Hilfe des Attributs $mandatory können Sie ein Argument als optional einstufen, denn im Fall von Argumenten ist hier true der Standardwert. Argumente müssen pauschal übergeben werden. Markieren Sie ein einzelnes Argument als optional, als $mandatory auf false gesetzt, so werden alle weiteren Argumente in der Reihe ebenfalls als optional angesehen. Der Grund ist einfach: Ist ein Argument optional, so kann es entweder auftauchen oder nicht. Taucht es nicht auf, so kann auch kein weiteres Argument auftauchen, denn sonst wäre dies ja das erste optionale Argument. Haben Sie ein Argument als optional deklariert, können Sie ihm einen Standardwert ($default) mitgeben, der gesetzt wird, falls der Benutzer den Parameter nicht übergibt.
Ebenfalls gravierende Auswirkungen hat das Attribute $multiple, dessen Standardwert false lautet. Setzen Sie dieses Attribut auf true, so akzeptiert das Attribut beliebig viele Werte und alle nachfolgenden Argumente werden ignoriert. Wie bei Optionen ist nach dem Setzen dieses Flags der Wert in $value ein Array anstatt eines skalaren Werts. Dieses kann beliebig viele Werte enthalten. Die Attribute $shorthelp und $longhelp funktionieren analog ihren Entsprechungen bei den Optionen.
Parsen
Haben Sie eine Instanz von ezcConsoleInput bei der Hand und in ihr Optionen und Argumente nach eigenem Wunsch registriert, können diese verarbeitet werden. Dafür steht die Methode process() bereit, bei der Sie beachten sollten, dass sie eine Ausnahme wirft, falls die Anforderungen nicht erfüllt werden.
Zunächst parst sie die auftauchenden Optionen und überprüft deren Regeln, sobald das erste Argument auftaucht. Tritt hierbei ein Fehler auf, wirft die Methode eine Ausnahme. Sind alle Optionen korrekt verarbeitet, werden die Argumente gemäß ihrer Spezifikation analysiert. Ein Fehler erzeugt hier ebenfalls eine Ausnahme, welche eine Fehlermeldung enthält, die Sie dem Benutzer direkt anzeigen können. Sie können ebenso selbst auf den Exception-Typ reagieren.
Auf die Liste der möglichen Fehler von ezcConsoleArgumentMandatoryViolationException für ein nicht angegebenes optionales Argument bis hin zur ezcOptionTypeViolationException, falls der übergebene Wert für eine Option nicht ihrem Typ entspricht, verzichten wir an dieser Stelle.
Tritt kein Fehler bei der Verarbeitung auf, können Sie über die $value-Attribute der einzelnen Parameter, also Argumente und Optionen, auf die vom Benutzer übergebenen Werte zugreifen. Außerdem bietet die Input-Klasse Ihnen alternative Methoden für diesen Zugriff an: getArguments() zum Erhalt aller übergebenen Argumentwerte kennen Sie bereits. Daneben gibt es getOption(), der Sie den Namen (egal ob kurz oder lang) einer Option übergeben und die das entsprechende Optionen-Objekt liefert. Passend dazu existiert getOptions(), mit der Sie ein Array aller registrierten Optionen erhalten. getOptionValues() liefert Ihnen ein Array mit allen Optionswerten, standardmäßig indiziert mit den Kurznamen der Optionen. Übergeben Sie der Methode den booleschen Wert true, so erhalten Sie eine Indexierung nach Langnamen. Die Methode unregisterOption() deregistriert ein Optionen-Objekt wieder am Input-Objekt, sie bildet also das Gegenstück zu registerOption().
Schließlich kann Ihnen eine Instanz der ezcConsoleInput-Klasse automatisch einen passenden Hilfetext generieren und stellt dazu verschiedene Methoden bereit. getSynopsis() erzeugt lediglich den String zur Beschreibung der Eingabe Ihres Programms, also den Programmnamen und die möglichen Parameter. Übergeben Sie dieser Methode ein Array von Optionen-Namen, werden nur diese in der Synopsis berücksichtigt.
Weiter geht die Methode getHelp(). Übergeben Sie ihr keine Optionen, erhalten Sie ein zweidimensionales Array als Ergebnis, das für jede nach Ganzzahlen nummerierte Zeile ein weiteres Array enthält. Dieses enthält im ersten Feld die Namen einer Option und im zweiten Feld den passenden Hilfetext. Diese Informationen können Sie anschließend formatieren und ausgeben. Übergeben Sie als ersten Parameter den booleschen Wert true, so wird der lange Hilfetext der Optionen statt des kurzen verwendet. Der zweite, ebenfalls optionale Parameter der Methode hat die gleiche Wirkung wie der Parameter zu getSynopsis() und erlaubt Ihnen, die dargestellten Optionen einzuschränken.
Wollen Sie diesen Formatierungsaufwand nicht betreiben, können Sie alternativ getHelpTable() verwenden. Dieser Methode übergeben Sie als ersten Parameter eine Instanz von ezcConsoleTable und erhalten sie als Ergebnis zurück. Allerdings gefüllt mit den Hilfeinformationen. Der Tabellenklasse widmen wir uns später in diesem Kapitel noch ausführlicher.
getHelpText() ist die komfortabelste Variante, denn diese Methode gibt Ihnen einen standardisierten Hilfetext, der nur noch ausgegeben werden muss. Als ersten Parameter erwartet die Methode eine kurze Beschreibung des Programms. Diese wird direkt nach der Synopsis im String eingeflochten und kann mittels formatText() aus ezcConsoleOutput formatiert werden. Der zweite, optionale Integer-Parameter bestimmt die Breite des Hilfetextes. Dieser wird automatisch umgebrochen. Die Standardeinstellung beträgt 80 Zeichen. Die beiden letzten Parameter entsprechen den bereits bekannten: Sie dienen zum Umschalten auf lange Hilfetexte und zum Eingrenzen der Optionen. Weiter zeigt getHelpText() alle Argumente mit entsprechenden Hilfeinformationen an. Sie treten außerdem in der Synopsis auf.
18.1.4 Tabellen 

Nachdem Sie nun über Ein- und Ausgabe Bescheid wissen, gehen wir kurz auf Tabellen ein. Dieses Thema werden wird kurz halten, da Tabellen im GP-Blog keine Rolle spielen. Wir zeigen Ihnen zunächst ein Beispiel.
$out = new ezcConsoleOutput();
$out->formats->headline->color = 'blue';
$table = new ezcConsoleTable( $out, 80 );
$table[0][0]->content = 'Some headline';
$table[0][1]->content = 'A second headline';
$table[0][2]->content = 'Finally, a third headline as well';
$table[0]->borderFormat = 'headline';
for ( $i = 0; $i < 3; $i++ )
{
$table[1][$i]->content = (string) mt_rand( 0, 1000 );
}
$table[1]->align = ezcConsoleTable::ALIGN_CENTER;
$table->outputTable();Listing 18.3 Eine einfache Tabelle
In diesem Beispiel wird zunächst die benötigte Instanz von ezcConsoleOutput erzeugt und mit einem Format namens headline ausgestattet. Der Konstruktor einer Tabelle erwartet mindestens ein Ausgabeobjekt sowie die gewünschte Breite der Tabelle in Zeichen. Diese versteht sich standardmäßig als maximale Breite.
Die erste Zeile der Tabelle wird manuell mit ein paar sinnlosen Überschriften gefüllt, die zweite Zeile der Tabelle wird mit zufälligen Integer-Werten zwischen 0 und 1000 gefüllt. Der Cast nach einem String ist an dieser Stelle notwendig, da der Inhalt einer Tabellenzelle (ezcConsoleTableCell->$content) ein String sein muss, mt_rand() aber einen Integer-Wert zurückgibt.
Zwischen den Befüllungen wird auf der ersten Zeile noch das Attribut $borderFormat auf den Wert headline gesetzt. Bei dem zugrunde liegenden Objekt handelt es sich um eine Instanz von ezcConsoleTableRow, das eine ezcConsoleTableCell-Instanz für jede seiner Zellen hat. Für die zweite Zeile wird das $align-Attribut gesetzt und festgelegt, dass die Inhalte zentriert dargestellt werden sollen. Die zweite Zelle der zweiten Zeile bekommt außerdem das $format (Achtung: nicht $borderFormat) headline zugewiesen. Sie sehen also, dass auch Zellen durch ihre Attribute beeinflusst werden können. Das Ergebnis des letzten Aufrufs in diesem Skript sehen Sie nun im Screenshot.
Abbildung 18.1 Tabelle auf der Konsole
18.1.5 Dialoge 

Benutzereingaben via Kommandozeile als Parameter entgegenzunehmen ist möglich, aber manchmal möchte man dem Benutzer mehr Interaktivität bieten und benötigt daher einen Dialog. Seit der aktuellen Version der Komponente ConsoleTools ist auch hierfür eine Hilfe in Form des Interfaces ezcConsoleDialog vorhanden.
Dialog-Basis
Alle Dialog-Klassen müssen dieses Interface implementieren und stellen somit vier Methoden bereit: Die Methode display() veranlasst den Dialog, sich selbst darzustellen und eine Antwort von Benutzer zu empfangen. hasValidResult() beantwortet Ihnen die Frage, ob bei der letzten Darstellung ein annehmbares Resultat vom Benutzer geliefert wurde, auf das Sie mittels getResult() zugreifen können. Hüten Sie sich aber davor, getResult() aufzurufen, wenn kein valides Resultat bereitliegt, denn in diesem Fall wirft die Methode eine ezcConsoleNoValidDialogResultException. Die letzte Methode des Interfaces reset() veranlasst einen Dialog, sein empfangenes Resultat zu vergessen, sodass er erneut verwendet werden kann.
Passend zum Interface ezcConsoleDialog bringt die Komponente ConsoleTools noch die Schnittstellendefinition ezcConsoleDialogValidator mit. Ein Validator übernimmt innerhalb eines Dialogs die Aufgabe, das vom Benutzer übergebene Resultat auf seine Korrektheit hin zu prüfen und nötigenfalls zu reparieren. Für Letzteres ist die Methode fixup() zuständig, die versucht, ein erhaltenes Resultat zu interpretieren und gegebenenfalls heuristisch zu korrigieren. Das Ergebnis der Methode ist das bearbeitete (oder auch nicht bearbeitete) Resultat, das anschließend validiert werden kann. Die eigentliche Prüfung findet dann mit der Methode validate() statt, welche true zurückgibt, wenn das Ergebnis anerkannt wurde, andernfalls false.
Außerdem steht eine Basisklasse mit dem Namen ezcConsoleDialogOptions für Dialogoptionen bereit. Diese Klasse stellt die zwei grundlegenden Optionen bereit, die jeder Dialog unterstützen sollte: $format, um ein Ausgabeformat für ezcConsoleOutput anzugeben, in dem der Dialog formatiert werden soll, sowie $validator, die ein Prüferobjekt erhalten soll zur Validierung des Dialogresultats. Dialogimplementierungen können die Basisklasse durch Erweiterungen und durch weitere Optionen ergänzen.
Fragen
Die Komponente ConsoleTools bringt zwei Implementierungen des Dialog-Interfaces mit, die Ihnen zwei verschiedene Wege bereitstellen, mit dem Benutzer Ihrer Anwendung zu interagieren: ezcConsoleQuestionDialog-Objekte können dem Anwender eine Frage stellen, wohingegen ezcConsoleMenuDialog-Instanzen ein Menü darstellen und den Benutzer einen Menüpunkt auswählen lassen.
Der Fragendialog bringt neben seiner eigenen Optionen-Klasse auch ein eigenes Validator-Interface mit. ezcConsoleQuestionDialogOptions bringt alle denkbaren Einstellungen mit sich, die Sie benötigen, um den Fragendialog zu konfigurieren. Die Option $text ermöglicht Ihnen, den Text der Frage anzugeben. Dabei brauchen Sie potentielle Wahlmöglichkeiten nicht mit in die Frage aufzunehmen; dazu steht ebenfalls eine Option bereit: $showResults. Der Standardwert ist false; auf true gesetzt, veranlasst sie den Fragendialog dazu, dem Anwender die möglichen Eingaben darzustellen.
Menüs
Den Fragendialog in Aktion werden Sie später in diesem Kapitel noch kennenlernen. Allerdings nicht den Menüdialog, weshalb wir diesen hier kurz an einem Beispiel vorstellen wollen.
Auch der Menüdialog bringt eine eigene Optionen-Klasse und eine eigene Prüferbasis mit sich, die aber den soeben kennengelernten Mechanismen des Fragendialogs sehr ähnlich sind.
$output = new ezcConsoleOutput();
$menu = new ezcConsoleMenuDialog( $output );
$menu->options = new ezcConsoleMenuDialogOptions();
$menu->options->text = "Please choose a possibility:\n";
$menu->options->validator = new
ezcConsoleMenuDialogDefaultValidator(
array(
"1" => "Install database",
"2" => "Create directories",
"3" => "Create configuration",
"4" => "Check configuration",
"0" => "Quit",
),
"0"
);
$choice = ezcConsoleDialogViewer::displayDialog( $menu );
while ( $choice != 0 )
{
switch ( $choice )
{
case 1:
$output->outputLine( 'Installing the database...' );
break;
case 2:
$output->outputLine( 'Creating directories...' );
break;
case 3:
$output->outputLine( 'Creating configuration...' );
break;
case 4:
$output->outputLine( 'Checking configuration...' );
break;
}
$menu->reset();
}
$output->outputLine( 'Thanks for using this tool!' );Listing 18.4 Ein Menüdialog
Der Menüdialog benötigt gleich dem Fragendialog eine Instanz von ezcConsoleOutput zur eigenen Darstellung. Des Weiteren hat auch der Menüdialog eine $text-Option, mit deren Hilfe Sie den Aufforderungstext des Menüs beeinflussen können. Für das Menü wird erneut ein Prüferobjekt benötigt, welches neben den Menüeinträgen einen Standardwert per Konstruktor übergeben bekommen kann.
Menüeinträge beschreiben Sie in einem assoziativen Array, das als Schlüssel die Identifizierer der Menüeinträge hat, denen die darzustellenden Texte zugeordnet werden. Die Methode displayDialog() der Helferklasse ezcConsoleDialogViewer nimmt Ihnen die Arbeit ab, den Dialog solange darzustellen, bis eine valide Antwort vom Anwender verfügbar ist. Sie gibt Ihnen lediglich die valide Antwort zurück, mit der Sie dann arbeiten können. Im Falle des Menüdialogs also eine gültige Menüauswahl zwischen 0 und 4.
Das Beispiel benutzt eine gängige Technik im Umgang mit Menüdialogen, diese solange erneut darzustellen, bis der Menüpunkt zum Beenden des Programms gewählt wird – in diesem Fall die 0. Jede nach Auswahl des Benutzers wird vom Menü eine Aktion angestoßen, die ihrerseits ein Untermenü darstellen kann oder (wie in diesem Beispiel) lediglich einen Text ausgibt. Ist die Aktion beendet, wird die Kontrolle zurück an die Menüschleife übergeben, die ihrerseits erneut das Menü darstellt.
Am Ende der Menüschleife wird daher der Menüdialog zurückgesetzt, sodass er die letzte Wahl des Benutzers vergisst und bei einer erneuten Anzeige eine neue Auswahl bereitstellt. Wählt der Anwender schließlich das Ende des Programms aus, terminiert die Schleife und das Programm wird beendet.
In diesem Abschnitt haben Sie die API von eZ Components für Konsolendialoge kennengelernt. Sie haben ausführlich den Aufbau des mitgelieferten Fragendialogs und exemplarisch einen Menüdialog in Aktion gesehen. Den Fragendialog werden Sie etwas später in diesem Kapitel nochmals sehen, da er Verwendung im GP-Blog-Setup finden wird.
18.1.6 Fortschritt 

Die letzte Kategorie an Klassen, die es vorzustellen gilt, sind die Fortschrittsindikatoren. Da keine dieser Klassen im Setup-Programm für das GP-Blog zur Anwendung kommt, begnügen wir uns an dieser Stelle mit einem groben Überblick und einem Beispiel.
Fortschrittsbalken
Die wohl gebräuchlichste Klasse, um Fortschritte bei der Abarbeitung einer längeren Aufgabe dem Benutzer zu präsentieren, ist ezcConsoleProgressbar, der Standardfortschrittsbalken. Eine Instanz dieser Klasse zeigt dem Benutzer eine Art Animation an, um den aktuellen Status der Aktion darzustellen. In der Animation füllt sich ein Balken nach und nach, bis die Aktion zu ihrem Ende kommt und erreicht dann seine volle Füllhöhe.
Die zuständige Klasse der ConsoleTools-Komponente erlaubt Ihnen außerdem, einen Text und den Fortschritt in Prozentwerten sowie in vollen Werten anzuzeigen. Ein Beispiel hierzu:
$output = new ezcConsoleOutput();
$bar = new ezcConsoleProgressbar(
$output,
1000,
array( 'step' => 50 )
);
$bar->options->emptyChar = ' ';
$bar->options->barChar = '-';
$bar->options->progressChar = '>';
$bar->options->formatString =
'Some very long action %act%/%max% completed [%bar%]';
for ( $i = 0; $i < 20; $i++ )
{
$bar->advance();
usleep( mt_rand( 2000, 200000 ) );
}
$bar->finish();
$output->outputLine();Listing 18.5 Einen Fortschrittsbalken darstellen
In diesem Beispiel wird zunächst das obligatorische Ausgabeobjekt erzeugt, das der Fortschrittsbalken benötigt, um sich darzustellen. Anschließend wird das eigentliche Balkenobjekt erstellt, das als Parameter in jedem Fall das Ausgabeobjekt sowie den Wert des maximalen Fortschritts erwartet. Letzteren Wert benötigt das Objekt, um zu bestimmen, wie weit die dargestellte Aktion bereits fortgeschritten ist.
Der letzte Parameter zum Konstruktor von ezcConsoleProgressbar ist ein Array von Optionen, wie Sie es von vielen eZ Components-Klassen bereits kennen. Intern werden die so übergebenen Optionen an ein Objekt der Klasse ezcConsoleProgressbarOptions übergeben, auf das direkt nach der Erzeugung des Balkenobjekts zugegriffen wird.
Die Option $step bestimmt, um welchen Wert der Fortschritt bei jedem Aufruf der Methode advance() steigt. Diese Methode wird vom Programm jedes Mal dann aufgerufen, wenn ein bestimmter Anteil der Aktion ($step) erfüllt ist, sodass der Fortschrittsbalken um diesen Wert weiter gesetzt wird. Im gezeigten Fall beträgt der Maximalwert 1000. Jeder Aufruf von advance() erhöht um 50 ($step), somit sind also 20 Aufrufe notwendig, um den Balken auf 100 % Fortschritt zu setzen.
Abbildung 18.2 Ein Fortschrittsbalken in Aktion
Wie Sie dem Screenshot entnehmen können, bezeichnet die Option $emptyChar dasjenige Zeichen, mit dem der leere Fortschrittsbalken gefüllt wird. In diesem Fall ist es ein Leerzeichen. $barChar konfiguriert das Zeichen, mit dem der Balken gefüllt wird, und $progressChar dasjenige Zeichen, das als Pfeil dient. Der $formatString beschreibt die Gesamtdarstellung des Balkens. Neben dem Platzhalter %bar% für den Balken selbst stehen Ihnen Platzhalter für den aktuellen Wert des Fortschritts (%act%) und für den Maximalwert (%max%) zur Verfügung. Sie können ihre Verteilung innerhalb eines frei gestaltbaren Textes positionieren. Einer Einschränkung unterliegt der Text allerdings doch: Es darf kein Zeilenumbruch in ihm vorkommen, da sonst der Positionssprung nicht korrekt ausgeführt werden kann. Neben den hier gezeigten Platzhaltern steht Ihnen noch %fraction% für den Prozentanteil des aktuellen Fortschritts gegenüber dem maximalen Wert zur Verfügung.
Die eigentliche Darstellung des Balkens haben wir bereits abgehandelt: Die for-Schleife läuft genau 20 Mal, um den Balken auf 100 % Fortschritt zu treiben. In jedem Aufruf wird advance() auf dem Progressbar-Objekt aufgerufen, um den Balken um 50 Fortschrittspunkte zu erhöhen. Im Anschluss wird eine zufällige Zeitspanne lang gewartet, um eine beliebige Aktion zu simulieren und den Balken nicht »weglaufen« zu lassen.
Der abschließende Aufruf von finish() auf dem Balkenobjekt ist optional. Er stellt lediglich sicher, dass der Balken mindestens ein Mal mit 100 % gezeichnet wird. Schätzen Sie den maximalen Fortschritt lediglich und sind Sie bereits vor Erreichen der 100-Prozent-Marke fertig, lässt der Aufruf Ihren Fortschrittsbalken auf 100 % springen und zeigt dem Anwender den korrekten Abschluss der Aktion an.
Fortschrittsmonitor
Der Fortschrittsbalken sieht hübsch aus, lässt aber nur wenig Freiraum für eigene Informationen. Lediglich die bereitgestellten Platzhalter können automatisch aktualisiert werden. Ein eigener Text bleibt statisch, während der Anwender eine schicke Animation präsentiert bekommt. Reicht Ihnen dies nicht und müssen Sie gegebenenfalls weitere Informationen in jedem Schritt bereitstellen, so bringt Sie ezcConsoleProgressMonitor weiter.
Abbildung 18.3 ezcConsoleProgressMonitor in Aktion
Der Screenshot zeigt Ihnen die exemplarische Ausgabe eines Monitors, der 13 Aktionen überwacht, die entweder kurz oder lang sein können. Steht eine kurze Aktion bevor, so gibt der Fortschrittsmonitor dies an und zeigt, wie viel Prozent der durchzuführenden Aktionen nach der aktuellen Aktion abgearbeitet werden müssen. Anschließend wird die Aktion ausgeführt. Leider können wir hier im Buch keine Animationen darstellen, weshalb Sie lediglich den Endzustand nach Abwicklung aller Aktionen sehen.
Der folgende Sourcecode war für die Darstellung des gezeigten Fortschrittmonitors verantwortlich:
$output = new ezcConsoleOutput();
$status = new ezcConsoleProgressMonitor( $output, 13 );
for( $i = 1; $i <= 13; $i++ )
{
$value = mt_rand( 20000, 2000000 );
if ( $value < 1000000 )
{
$status->addEntry(
'SHORT',
"Performing short action #{$i}."
);
}
else
{
$status->addEntry(
'LONG ',
"Performing short action #{$i}."
);
}
usleep( $value );
}
$output->outputLine();Listing 18.6 ezcConsoleProgressMonitor in Aktion
Mit Hilfe des obligatorischen ezcConsoleOutput-Objektes wird eine neue Instanz der Monitor-Klasse erzeugt während der zweite Parameter die Anzahl der Aktionen angibt. Der Fortschritt in der for-Schleife kann mit den zusätzlichen Informationen wie dem Typ der Aktion und einem eigenen Text versehen werden. Die eigentliche, lange oder kurze, Aktion wird durch das Warten mittels usleep() in diesem Beispiel simuliert.
Statusbalken
Der Statusbalken ist die dritte Variante, um den Benutzer über den Fortschritt zu informieren. Er verfolgt einen völlig anderen Ansatz als der eben vorgestellte Fortschrittsmonitor: Statt mehr Informationen zu liefern als ezcConsoleProgressbar, liefert ezcConsoleProgressmonitor weniger Informationen über den aktuellen Ablauf und stellt lediglich einen Indikator bereit, ob die aktuelle Aktion erfolgreich war. Dies ist praktisch, wenn Sie zum einen eine große Menge einzelner Aktionen abarbeiten und für jede Aktion mitteilen wollen, ob sie erfolgreich war. Zum anderen erfordert diese Art, dem Benutzer einen Status über die aktuelle Aktion mitzuteilen, keinen im Voraus bekannten Maximalwert wie bei den anderen Varianten, sondern kann mit beliebig vielen Schritten umgehen.
$output = new ezcConsoleOutput();
$output->formats->success->color = 'green';
$output->formats->failure->color = 'red';
$options = array(
'successChar' => $output->formatText( '+', 'success' ),
'failureChar' => $output->formatText( '-', 'failure' ),
);
$status = new ezcConsoleStatusbar( $output, $options );
for ( $i = 0; $i < 120; $i++ )
{
$nextStatus = (bool) mt_rand( 0,1 );
$status->add( $nextStatus );
usleep( mt_rand( 200, 2000 ) );
}
$output->outputLine();
$output->outputLine(
'Successes: ' . $status->getSuccessCount(),
'success'
);
$output->outputLine(
'Failures: ' . $status->getFailureCount(),
'failure'
);Listing 18.7 Ein Statusbalken in Aktion
Zunächst wird in diesem Beispiel das übliche Ausgabeobjekt erzeugt und diesmal mit zwei Formaten versehen: success und failure. Anschließend wird ein Array mit den beiden Optionen der Statusbalkenklasse erstellt, das ein Zeichen zum Indizieren eines Aktionserfolgs ($successChar) sowie ein Zeichen zur Anzeige eines Fehlers mit dem Schlüssel $failureChar enthält. Beide Indikatoren sind mit dem Ausgabeobjekt entsprechend formatiert worden.
Insgesamt werden in der for-Schleife 120 Statuswerte ausgegeben. Hier exemplarisch zufällig bestimmt, zu denen passend jeweils eine kurze Zeit gewartet wird. Am Ende wird in zwei Zeilen ausgegeben, wie viele Aktionen erfolgreich waren und wie viele fehlerhaft verliefen. Das Statusobjekt führt hierüber eine Statistik. Die Ausgabe nach Abarbeitung aller Statuswerte sehen Sie im folgenden Screenshot.
Abbildung 18.4 ezcConsoleStatusbar in Aktion








Ihre Meinung






