Signatur
Beschreibung
readline_callback_handler_install() richtet das readline-Callback-Interface ein. Im Gegensatz zu readline(), das blockiert bis der Nutzer die Eingabe bestätigt, kehrt diese Funktion sofort zurück. Das eigentliche Lesen der Zeichen übernimmt anschließend readline_callback_read_char(), das typischerweise in einer Event-Schleife aufgerufen wird.
Sobald der Nutzer eine Zeile abschließt (Enter), ruft readline automatisch die angegebene $callback-Funktion auf und übergibt die eingelesene Zeile als Parameter. Das ermöglicht nicht-blockierende CLI-Anwendungen, bei denen neben der Benutzereingabe auch andere Ereignisse (z. B. Timer, Sockets) verarbeitet werden können.
Dieses Interface ist besonders für interaktive CLI-Tools, REPLs oder Daemon-ähnliche Prozesse geeignet, die auf mehrere Eingabequellen gleichzeitig reagieren müssen. Nach Abschluss der Arbeit sollte readline_callback_handler_remove() aufgerufen werden, um das Terminal wieder in den ursprünglichen Zustand zu versetzen.
- Das Callback erhält die eingelesene Zeile als
stringodernull, falls EOF erkannt wurde. - Die Funktion ist nur verfügbar, wenn PHP mit readline-Unterstützung kompiliert wurde (typischerweise nur auf Unix-ähnlichen Systemen).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $prompt Pflicht | string | Der Prompt-Text, der dem Nutzer am Anfang der Eingabezeile angezeigt wird, z. B. '> ' oder 'php> '. |
|
| $callback Pflicht | callable | Eine Callback-Funktion, die aufgerufen wird, sobald der Nutzer eine Zeile abgeschlossen hat. Sie erhält die eingelesene Zeile als string; bei EOF wird null übergeben. Signatur: function(?string $line): void. |
Rückgabewert
true bei Erfolg zurück, false bei einem Fehler (z. B. wenn readline nicht verfügbar ist).Beispiele
Einfache nicht-blockierende REPL-Schleife
<?php
// Callback-Funktion, die bei jeder abgeschlossenen Eingabe aufgerufen wird
$callback = function (?string $line): void {
if ($line === null) {
// EOF (Ctrl+D) empfangen – Schleife beenden
echo PHP_EOL . 'Beende...' . PHP_EOL;
readline_callback_handler_remove();
exit(0);
}
$line = trim($line);
if ($line !== '') {
readline_add_history($line);
echo 'Du hast eingegeben: ' . $line . PHP_EOL;
}
// Neuen Prompt ausgeben (wird automatisch nach Callback erneut gesetzt)
};
// Handler installieren und Prompt ausgeben
readline_callback_handler_install('php> ', $callback);
// Event-Schleife: warten auf lesbare Zeichen von STDIN
while (true) {
$read = [STDIN];
$write = null;
$except = null;
// Blockiert, bis Zeichen auf STDIN verfügbar sind
if (stream_select($read, $write, $except, null) > 0) {
readline_callback_read_char();
}
}
Paralleles Lesen von STDIN und einem Socket
<?php
// Simuliertes Beispiel: Benutzereingabe und eine weitere Eingabequelle überwachen
$running = true;
readline_callback_handler_install('cmd> ', function (?string $line) use (&$running): void {
if ($line === null || strtolower(trim($line)) === 'exit') {
$running = false;
readline_callback_handler_remove();
return;
}
echo 'Kommando empfangen: ' . trim($line) . PHP_EOL;
readline_add_history($line);
});
// Fake-Socket durch eine Pipe simulieren (hier vereinfacht)
// Im echten Einsatz würde hier z. B. stream_socket_client() stehen
$streams = [STDIN];
while ($running) {
$read = $streams;
$write = null;
$except = null;
$ready = stream_select($read, $write, $except, 0, 200000); // 200 ms Timeout
if ($ready === false) {
break;
}
if ($ready > 0 && in_array(STDIN, $read, true)) {
readline_callback_read_char();
}
// Hier könnten andere Events (Timer, Netzwerk) verarbeitet werden
}
echo 'Programm beendet.' . PHP_EOL;
// Wichtig · Fallstricke
Plattformverfügbarkeit: readline_callback_handler_install() ist nur auf Systemen verfügbar, auf denen PHP mit GNU-readline- oder libedit-Unterstützung kompiliert wurde. Unter Windows steht diese Funktion in der Regel nicht zur Verfügung.
Terminal-Zustand: Die Funktion versetzt das Terminal in einen speziellen Modus. Wird readline_callback_handler_remove() nicht aufgerufen (z. B. bei unbehandelten Ausnahmen), bleibt das Terminal in diesem Modus und muss manuell zurückgesetzt werden (z. B. mit dem Shell-Befehl reset). Es empfiehlt sich daher, den Handler in einem try/finally-Block zu verwenden.
Mehrfachinstallation: Ein erneuter Aufruf von readline_callback_handler_install() ohne vorheriges readline_callback_handler_remove() überschreibt den bestehenden Handler und kann zu unerwartetem Verhalten führen.