Start · Sprachen · PHP · Referenz · readline_callback_read_char

readline_callback_read_char

Funktion

Liest ein Zeichen von der Standardeingabe und benachrichtigt das readline-Callback-Interface, sobald eine vollständige Eingabezeile erkannt wurde.

seit PHP 5.1.0 Kategorie: io

Signatur

readline_callback_read_char(): void

Beschreibung

readline_callback_read_char() ist Teil des nicht-blockierenden readline-Callback-Interfaces. Sie liest genau ein Zeichen von der Standardeingabe und übergibt es intern an die readline-Bibliothek. Sobald der Benutzer die Eingabe mit der Eingabetaste abschließt, wird die zuvor über readline_callback_handler_install() registrierte Callback-Funktion aufgerufen und erhält die vollständige Eingabezeile als Parameter.

Der entscheidende Vorteil gegenüber der blockierenden Funktion readline() liegt darin, dass readline_callback_read_char() nicht blockiert. Sie liest lediglich das nächste verfügbare Zeichen und kehrt sofort zurück. Damit eignet sie sich besonders für event-getriebene Architekturen, z. B. in Kombination mit stream_select(), um gleichzeitig auf Benutzereingaben und andere I/O-Ereignisse (z. B. Netzwerk-Sockets, Pipes) zu reagieren.

Typischerweise wird diese Funktion in einer Schleife aufgerufen, wobei stream_select() prüft, ob Daten auf STDIN vorliegen. Erst wenn Daten verfügbar sind, wird readline_callback_read_char() aufgerufen, um ein Zeichen zu lesen. So lassen sich interaktive CLI-Anwendungen mit mehreren gleichzeitigen I/O-Quellen realisieren.

Der installierte Callback-Handler sollte nach Abschluss der Interaktion mit readline_callback_handler_remove() wieder entfernt werden, um das Terminal in den ursprünglichen Zustand zurückzuversetzen.

Rückgabewert

Typ
void
Beschreibung
Die Funktion gibt keinen Wert zurück. Das Ergebnis der Eingabe wird über die registrierte Callback-Funktion verarbeitet.

Beispiele

Einfache nicht-blockierende Eingabeschleife mit stream_select

<?php
// Callback-Funktion, die aufgerufen wird, wenn eine Zeile abgeschlossen wurde
function eingabeVerarbeiten(?string $zeile): void
{
    if ($zeile === null) {
        // Benutzer hat CTRL+D gedrückt (EOF)
        echo PHP_EOL . 'Eingabe beendet.' . PHP_EOL;
        readline_callback_handler_remove();
        exit(0);
    }

    echo 'Du hast eingegeben: ' . $zeile . PHP_EOL;

    if (trim($zeile) === 'quit') {
        readline_callback_handler_remove();
        exit(0);
    }
}

// Prompt anzeigen und Callback registrieren
readline_callback_handler_install('Eingabe> ', 'eingabeVerarbeiten');

// Ereignisschleife
while (true) {
    // Prüfen, ob Daten auf STDIN verfügbar sind (Timeout: 1 Sekunde)
    $lesen  = [STDIN];
    $schreiben = null;
    $except    = null;

    $anzahl = stream_select($lesen, $schreiben, $except, 1);

    if ($anzahl > 0) {
        // Zeichen von STDIN lesen und an readline übergeben
        readline_callback_read_char();
    } else {
        // Hier könnten andere Aufgaben erledigt werden (z. B. Netzwerk-I/O)
        // echo '(Warte auf Eingabe...)' . PHP_EOL;
    }
}
Eingabe> Hallo Welt Du hast eingegeben: Hallo Welt Eingabe> quit

Parallele Verarbeitung von STDIN und einer weiteren Stream-Quelle

<?php
// Simulierter zusätzlicher Stream (hier eine Datei, in der Praxis z. B. ein Socket)
$extraStream = fopen('/dev/null', 'r');

function zeilenCallback(?string $zeile): void
{
    if ($zeile === null) {
        readline_callback_handler_remove();
        exit(0);
    }
    readline_add_history($zeile);
    echo 'Verarbeite: ' . htmlspecialchars($zeile, ENT_QUOTES) . PHP_EOL;
}

readline_callback_handler_install('>> ', 'zeilenCallback');

$laeuft = true;
while ($laeuft) {
    $lesen   = [STDIN, $extraStream];
    $schreib = null;
    $ausn    = null;

    $bereit = stream_select($lesen, $schreib, $ausn, 2);

    if ($bereit === false) {
        // Fehler bei stream_select
        break;
    }

    foreach ($lesen as $stream) {
        if ($stream === STDIN) {
            readline_callback_read_char();
        } else {
            // Daten aus dem anderen Stream verarbeiten
            fread($stream, 1024);
        }
    }
}

readline_callback_handler_remove();
fclose($extraStream);
>>

// Wichtig · Fallstricke

Plattformverfügbarkeit: Diese Funktion ist nur verfügbar, wenn PHP mit Unterstützung für die readline-Bibliothek kompiliert wurde (i. d. R. GNU Readline oder libedit). Auf Windows-Systemen steht sie häufig nicht zur Verfügung.

Terminal-Zustand: Beim Aufruf von readline_callback_handler_install() wird das Terminal in den Rohmodus versetzt. Wird readline_callback_handler_remove() vergessen (z. B. bei einem unerwarteten Programmabbruch), bleibt das Terminal in einem unbrauchbaren Zustand. Daher empfiehlt es sich, einen register_shutdown_function()-Handler zu registrieren, der den Callback-Handler zuverlässig entfernt.

Kombinierbarkeit: Die Funktion sollte ausschließlich nach einem erfolgreichen stream_select()-Aufruf verwendet werden, der STDIN als lesebereit meldet. Ein Aufruf ohne verfügbare Daten kann zu unerwartetem Verhalten führen.