Zum Hauptinhalt springen

Einführung

Laravel Prompts ist ein PHP-Paket, mit dem Sie Ihren Kommandozeilen-Anwendungen schöne, benutzerfreundliche interaktive Formulare hinzufügen. Es bietet mit Platzhaltertexten und Validierung ein Erlebnis, das dem eines Browser-Formulars nahekommt. Da Sie die Funktionen direkt im Code eines Artisan-Kommandos aufrufen, formulieren Sie Rückfragen an die Benutzer einfach und intuitiv.
Laravel Prompts unterstützt macOS, Linux und Windows (WSL). In nicht unterstützten Umgebungen greift automatisch ein Fallback.

Installation

Laravel Prompts ist Teil des Laravel-Kerns, eine zusätzliche Installation ist also nicht nötig. In anderen PHP-Projekten installieren Sie es per Composer.
composer require laravel/prompts

Grundlegende Prompt-Funktionen

text – Texteingabe

Mit text() fordern Sie eine Texteingabe an.
use function Laravel\Prompts\text;

$name = text('What is your name?');
Sie können Platzhalter, Standardwerte und Hinweise setzen.
$name = text(
    label: 'What is your name?',
    placeholder: 'E.g. Taylor Otwell',
    default: $user?->name,
    hint: 'This will be displayed on your profile.'
);
Mit required machen Sie die Eingabe verpflichtend – die Fehlermeldung ist anpassbar.
$name = text(
    label: 'What is your name?',
    required: 'Your name is required.'
);
Über eine validate-Closure können Sie zusätzlich validieren. Geben Sie eine Fehlermeldung zurück oder null bei Erfolg.
$name = text(
    label: 'What is your name?',
    validate: fn (string $value) => match (true) {
        strlen($value) < 3 => 'The name must be at least 3 characters.',
        strlen($value) > 255 => 'The name must not exceed 255 characters.',
        default => null
    }
);
Sie können auch Laravel-Validierungsregeln als Array angeben.
$name = text(
    label: 'What is your name?',
    validate: ['name' => 'required|max:255|unique:users']
);

textarea – mehrzeilige Eingabe

Mit textarea() erlauben Sie mehrzeilige Eingaben.
use function Laravel\Prompts\textarea;

$story = textarea('Tell me a story.');

number – Zahleingabe

Mit number() fragen Sie Zahlen ab. Über die Pfeiltasten kann der Wert erhöht bzw. verringert werden.
use function Laravel\Prompts\number;

$copies = number(
    label: 'How many copies would you like?',
    default: 1,
    validate: ['copies' => 'required|integer|min:1|max:100']
);

password – Passwort-Eingabe

password() funktioniert wie eine Texteingabe, das Eingegebene wird jedoch nicht angezeigt.
use function Laravel\Prompts\password;

$password = password('What is your password?');
$password = password(
    label: 'What is your password?',
    placeholder: 'password',
    hint: 'Minimum 8 characters.',
    validate: fn (string $value) => strlen($value) < 8
        ? 'The password must be at least 8 characters.'
        : null
);

confirm – Ja/Nein

Mit confirm() erhalten Sie eine binäre Bestätigung. Rückgabewert: true oder false.
use function Laravel\Prompts\confirm;

$confirmed = confirm('Do you accept the terms?');
Standardwert und Beschriftungen sind anpassbar.
$confirmed = confirm(
    label: 'Do you accept the terms?',
    default: false,
    yes: 'I accept',
    no: 'I decline',
    hint: 'The terms must be accepted to continue.'
);

select – Auswahlliste

Mit select() wählt der Benutzer aus einer Liste einen Eintrag.
use function Laravel\Prompts\select;

$role = select(
    label: 'What role should the user have?',
    options: ['Member', 'Contributor', 'Owner'],
    default: 'Owner'
);
Mit einem assoziativen Array wird nicht das Label, sondern der Schlüssel zurückgegeben.
$role = select(
    label: 'What role should the user have?',
    options: [
        'member'      => 'Member',
        'contributor' => 'Contributor',
        'owner'       => 'Owner',
    ],
    default: 'owner'
);
Über scroll legen Sie fest, wie viele Optionen vor dem Scrollen angezeigt werden (Standard: 5).
$role = select(
    label: 'Which category would you like to assign?',
    options: Category::pluck('name', 'id'),
    scroll: 10
);

multiselect – Mehrfachauswahl

Mit multiselect() können mehrere Optionen gleichzeitig ausgewählt werden.
use function Laravel\Prompts\multiselect;

$permissions = multiselect(
    label: 'What permissions should be assigned?',
    options: ['Read', 'Create', 'Update', 'Delete']
);
Mit required machen Sie mindestens eine Auswahl zur Pflicht.
$permissions = multiselect(
    label: 'What permissions should be assigned?',
    options: ['Read', 'Create', 'Update', 'Delete'],
    required: 'At least one permission must be selected.'
);

suggest – Eingabe mit Autocomplete

suggest() bietet Vorschläge, erlaubt aber auch freie Eingaben.
use function Laravel\Prompts\suggest;

$name = suggest(
    label: 'What is your name?',
    options: ['Taylor', 'Dayle']
);
Mit einer Closure filtern Sie die Vorschläge dynamisch nach der Eingabe.
$name = suggest(
    label: 'What is your name?',
    options: fn (string $value) => collect(['Taylor', 'Tobi', 'Dries'])
        ->filter(fn ($name) => str_starts_with($name, $value))
        ->values()
        ->all()
);

search – dynamische Suche

search() aktualisiert die Vorschläge bei jeder Eingabe. Das von der Closure zurückgegebene Array bildet die Optionen.
use function Laravel\Prompts\search;

$userId = search(
    label: 'Search for the user that should receive the mail',
    options: fn (string $value) => strlen($value) > 0
        ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()
        : []
);

multisearch – dynamische Mehrfachauswahl

multisearch() erlaubt Mehrfachauswahl mit dynamischer Suche.
use function Laravel\Prompts\multisearch;

$userIds = multisearch(
    label: 'Search for the users that should receive the mail',
    options: fn (string $value) => strlen($value) > 0
        ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()
        : []
);

pause – Pause

Mit pause() fordern Sie den Benutzer auf, Enter zu drücken, und halten den Ablauf an.
use function Laravel\Prompts\pause;

pause('Press ENTER to continue.');

autocomplete – Inline-Vervollständigung

autocomplete() zeigt Vorschläge als Ghost-Text inline an. Anders als bei suggest() erscheinen passende Vorschläge während der Eingabe als Ghost-Text und können mit Tab oder der Pfeil-rechts-Taste übernommen werden.
use function Laravel\Prompts\autocomplete;

$name = autocomplete(
    label: 'What is your name?',
    options: ['Taylor', 'Dayle', 'Jess', 'Nuno', 'Tim']
);
Platzhalter, Standardwert und Hinweis sind konfigurierbar.
$name = autocomplete(
    label: 'What is your name?',
    options: ['Taylor', 'Dayle', 'Jess', 'Nuno', 'Tim'],
    placeholder: 'E.g. Taylor',
    default: $user?->name,
    hint: 'Use Tab to accept, up/down to cycle.'
);
Auch dynamische Vorschläge per Closure sind möglich.
$file = autocomplete(
    label: 'Which file?',
    options: fn (string $value) => collect($files)
        ->filter(fn ($file) => str_starts_with(strtolower($file), strtolower($value)))
        ->values()
        ->all(),
);

Validierung

Bei allen Prompt-Funktionen können Sie über das Argument validate eine Validierung hinterlegen.
$name = text(
    label: 'What is your name?',
    validate: fn (string $value) => match (true) {
        strlen($value) < 3  => 'The name must be at least 3 characters.',
        strlen($value) > 255 => 'The name must not exceed 255 characters.',
        default => null
    }
);
Gibt die Closure einen String zurück, wird er als Fehler angezeigt und die Eingabe erneut angefordert. Bei null gilt die Validierung als erfolgreich. Auch Laravel-Validierungsregeln lassen sich als Array angeben.
$name = text(
    label: 'What is your name?',
    validate: ['name' => 'required|max:255|unique:users']
);
Um Eingaben vor der Validierung zu transformieren, verwenden Sie transform.
$name = text(
    label: 'What is your name?',
    transform: fn (string $value) => trim($value),
    validate: fn (string $value) => match (true) {
        strlen($value) === 0 => 'The name must not be empty.',
        default => null
    }
);

Formulare

Mit form() fassen Sie mehrere Prompts zusammen und können den gesamten Ablauf vor dem Abschluss abbrechen.
use function Laravel\Prompts\form;

$responses = form()
    ->text('What is your name?', required: true, name: 'name')
    ->password('What is your password?', validate: ['password' => 'min:8'], name: 'password')
    ->confirm('Do you accept the terms?')
    ->submit();

$name     = $responses['name'];
$password = $responses['password'];
$confirmed = $responses[2];

Informationsausgaben

Für stilisierte Textausgaben gibt es eigene Funktionen.
use function Laravel\Prompts\info;
use function Laravel\Prompts\warning;
use function Laravel\Prompts\error;
use function Laravel\Prompts\alert;
use function Laravel\Prompts\note;

note('Prepare for launch.');
info('User created successfully.');
warning('This action cannot be undone.');
error('Something went wrong.');
alert('Critical failure detected!');

Callouts

callout() zeigt Label und Inhalt in einem Rahmen an. Ideal, um Deploy-Zusammenfassungen, Fehlerdetails oder Statusaktualisierungen hervorzuheben.
use function Laravel\Prompts\callout;

callout(
    label: 'Environment Configured',
    content: 'Your application is running in production mode with 4 workers.',
);
Setzen Sie type auf 'warning' oder 'error', um den visuellen Stil zu ändern.
callout(
    label: 'Deprecation Notice',
    content: 'The `--prefer-stable` flag will be removed in v4.0.',
    type: 'warning',
);

callout(
    label: 'Database Connection Failed',
    content: 'Could not connect to MySQL on 127.0.0.1:3306.',
    type: 'error',
);
Über info fügen Sie eine Fußzeile hinzu – praktisch für IDs oder Zeitstempel.
callout(
    label: 'Deployment Summary',
    content: 'Your application was deployed to production.',
    info: 'deploy-id: d4f8a2c',
);

Reichhaltiger Inhalt

Übergeben Sie statt eines Strings ein Array, entsteht ein strukturiertes Callout. Die Klasse Element liefert Factory-Methoden für Überschriften, Aufzählungen, nummerierte Listen, Key-Value-Listen und Links.
use Laravel\Prompts\Elements\Element;
use function Laravel\Prompts\callout;

callout('Deployment Summary', [
    'Your application was deployed to production at 2024-03-15 14:32 UTC.',
    Element::heading('What Changed'),
    Element::bulletedList([
        'Migrated 3 pending database migrations',
        'Cleared and rebuilt route cache',
        'Restarted 4 queue workers',
    ]),
    Element::heading('Next Steps'),
    Element::numberedList([
        'Verify the health check endpoint at /up',
        'Monitor error rates for the next 15 minutes',
        'Confirm background jobs are processing',
    ]),
]);
Mit Element::keyValueList zeigen Sie beschriftete Datenpaare an.
callout('Database Connection Failed', [
    'Could not connect to the database server.',
    Element::keyValueList([
        'Host'     => '127.0.0.1',
        'Port'     => '3306',
        'Database' => 'forge',
        'Status'   => 'Connection refused',
    ]),
], type: 'error');
Element::link erzeugt in Terminals mit OSC-8-Unterstützung klickbare Hyperlinks. Übergeben Sie nur die URL oder URL und Label.
callout('Server Health Check', [
    'Multiple services are reporting degraded performance.',
    Element::heading('Affected Services'),
    'Look here: '.Element::link('https://example.com/health', 'Health Dashboard'),
    Element::link('https://example.com/health'),
]);
Wird das Label weggelassen, dient die URL selbst als Linktext.

Tabellen anzeigen

Mit table() zeigen Sie Daten in Tabellenform an.
use function Laravel\Prompts\table;

table(
    headers: ['Name', 'Email'],
    rows: User::all(['name', 'email'])->toArray()
);

Spinner (Ladeanzeige)

spin() zeigt während der Ausführung einer Closure eine Ladeanzeige an.
use function Laravel\Prompts\spin;

$response = spin(
    message: 'Fetching response...',
    callback: fn () => Http::get('http://example.com')
);
Für spin() wird die PHP-Erweiterung pcntl benötigt. In Umgebungen ohne diese Erweiterung erscheint der Spinner nicht.

Fortschrittsbalken

Mit progress() visualisieren Sie den Fortschritt einer Iteration.
use function Laravel\Prompts\progress;

$users = progress(
    label: 'Updating users',
    steps: User::all(),
    callback: fn ($user) => $this->performTask($user),
    hint: 'This may take some time.'
);
Sie können den Balken auch manuell steuern.
$progress = progress(label: 'Uploading files', steps: count($files));

$progress->start();

foreach ($files as $file) {
    $this->uploadFile($file);
    $progress->advance();
}

$progress->finish();

Tasks

task() zeigt während der Callback-Ausführung einen Spinner sowie einen scrollbaren Live-Log-Bereich an. Ideal, um langlaufende Vorgänge wie das Installieren von Abhängigkeiten oder Deploy-Skripte einzurahmen und in Echtzeit zu verfolgen.
use function Laravel\Prompts\task;

task(
    label: 'Installing dependencies',
    callback: function ($logger) {
        // Länger laufender Vorgang...
    }
);
Der Callback erhält eine Logger-Instanz, mit der Sie Logzeilen und Statusmeldungen in Echtzeit ausgeben.
Für task() wird die PHP-Erweiterung pcntl benötigt. Ohne diese greift eine statische Fallback-Anzeige.

Logzeilen ausgeben

Mit line schreiben Sie einzelne Zeilen in den scrollbaren Log-Bereich.
task(
    label: 'Installing dependencies',
    callback: function ($logger) {
        $logger->line('Resolving packages...');
        $logger->line('Downloading laravel/framework');
    }
);

Statusmeldungen

Mit success, warning und error fixieren Sie hervorgehobene Meldungen oberhalb des Log-Bereichs.
task(
    label: 'Deploying application',
    callback: function ($logger) {
        $logger->line('Pulling latest changes...');
        $logger->success('Changes pulled!');

        $logger->line('Running migrations...');
        $logger->warning('No new migrations to run.');

        $logger->line('Clearing cache...');
        $logger->success('Cache cleared!');
    }
);

Label aktualisieren

Mit label ändern Sie das Task-Label während der Ausführung. subLabel setzt eine untergeordnete, dezent dargestellte Beschriftung. Ein leerer String entfernt die Sub-Label; über das Argument subLabel legen Sie ein Start-Sub-Label fest.
task(
    label: 'Deploying',
    callback: function ($logger) {
        $logger->subLabel('Building assets...');
        // ...
        $logger->subLabel('Running migrations...');
        // ...
        $logger->subLabel('');
    },
    subLabel: 'Preparing...'
);

Text streamen

Für Vorgänge, die – wie KI-Antworten – Text schrittweise erzeugen, streamen Sie mit partial Stück für Stück. Nach Abschluss rufen Sie commitPartial, um zu committen.
task(
    label: 'Generating response...',
    callback: function ($logger) {
        foreach ($words as $word) {
            $logger->partial($word . ' ');
        }

        $logger->commitPartial();
    }
);

Zeilenlimit und Zusammenfassung

Standardmäßig werden bis zu 10 Zeilen scrollbar angezeigt. Über das Argument limit passen Sie das an. Sollen Statusmeldungen nach Abschluss auf dem Bildschirm bleiben, setzen Sie keepSummary: true.
task(
    label: 'Deploying',
    callback: function ($logger) {
        $logger->success('Assets built');
        $logger->success('Migrations complete');
    },
    limit: 20,
    keepSummary: true,
);

Streams

stream() gibt Text schrittweise im Terminal aus – ideal für KI-generierte Inhalte oder chunkweise eintreffende Daten.
use function Laravel\Prompts\stream;

$stream = stream();

foreach ($words as $word) {
    $stream->append($word . ' ');
    usleep(25_000); // Verzögerung zwischen Chunks simulieren...
}

$stream->close();
append fügt Text mit einem Fade-in-Effekt in den Stream ein. Nach dem vollständigen Streamen bestätigen Sie mit close, wodurch die Ausgabe committet und der Cursor wiederhergestellt wird.

Terminal-Steuerung

Terminal-Titel setzen

use function Laravel\Prompts\title;

title('My Application');
Ein leerer String setzt den Titel auf den Standard zurück.
title('');

Terminal leeren

use function Laravel\Prompts\clear;

clear();

Hinweise zum Terminal

Terminalbreite: Überschreiten Label, Optionen oder Validierungsmeldungen die Spaltenzahl des Terminals, werden sie automatisch gekürzt. Rechnen Sie für ein 80-spaltiges Terminal mit etwa 74 Zeichen. Terminalhöhe: Bei Prompts, die das Argument scroll akzeptieren, wird der Wert automatisch so angepasst, dass Validierungsmeldungen ebenfalls in die Terminalhöhe passen.

Fallback

In nicht unterstützten Umgebungen (z. B. Windows ohne WSL) schaltet Prompts automatisch auf Fallback. Standardmäßig werden dann die integrierten Methoden von Laravel wie $this->ask() oder $this->choice() verwendet.

Tests

Laravel Prompts arbeitet mit Pest und PHPUnit zusammen.
use Laravel\Prompts\Prompt;

Prompt::fake(['Taylor', true]);

$name      = text('What is your name?');
$confirmed = confirm('Do you accept the terms?');

Prompt::assertOutputContains('What is your name?');
Mit den Artisan-Test-Helfern von Laravel schreiben Sie auch Assertions für Info-Ausgaben.
// Pest
test('report generation', function () {
    $this->artisan('report:generate')
        ->expectsPromptsInfo('Welcome to the application!')
        ->expectsPromptsWarning('This action cannot be undone')
        ->expectsPromptsError('Something went wrong')
        ->expectsPromptsAlert('Important notice!')
        ->expectsPromptsTable(
            headers: ['Name', 'Email'],
            rows: [
                ['Taylor Otwell', '[email protected]'],
            ]
        )
        ->assertExitCode(0);
});
// PHPUnit
public function test_report_generation(): void
{
    $this->artisan('report:generate')
        ->expectsPromptsInfo('Welcome to the application!')
        ->expectsPromptsWarning('This action cannot be undone')
        ->expectsPromptsTable(
            headers: ['Name', 'Email'],
            rows: [['Taylor Otwell', '[email protected]']]
        )
        ->assertExitCode(0);
}

Verwandte Seiten

Artisan-Konsole

Prompts innerhalb von Artisan-Kommandos einsetzen
Zuletzt geändert am 13. Juli 2026