Prompts
- 簡介
- 安裝
- 可用提示 (Prompts)
- 在驗證前轉換輸入
- 表單 (Forms)
- 提示訊息
- 資料表 (Tables)
- 載入動畫 (Spin)
- 進度條 (Progress Bar)
- 任務 (Task)
- 流式輸出 (Stream)
- 終端標題 (Terminal Title)
- 清空終端
- 終端注意事項
- 不支援的環境與回退機制
- 測試
簡介
Laravel Prompts 是一個 PHP 軟體包,旨在為你的命令列應用程式新增美觀且使用者友好的表單,並提供類似瀏覽器的功能,包括佔位符文字和驗證。
Laravel Prompts 非常適合在 Artisan 控制檯命令中獲取使用者輸入,但它也可以用於任何命令列 PHP 專案。
Laravel Prompts 支援 macOS、Linux 和帶有 WSL 的 Windows。有關詳細資訊,請參閱我們關於不支援的環境與回退機制的文件。
安裝
Laravel Prompts 已包含在 Laravel 的最新版本中。
Laravel Prompts 也可以透過 Composer 軟體包管理器安裝到你的其他 PHP 專案中。
1composer require laravel/prompts
可用提示 (Prompts)
文字輸入 (Text)
text 函式將向用戶提出給定的問題,接收他們的輸入,並將其返回。
1use function Laravel\Prompts\text;2 3$name = text('What is your name?');
你還可以包含佔位符文字、預設值和提示資訊。
1$name = text(2 label: 'What is your name?',3 placeholder: 'E.g. Taylor Otwell',4 default: $user?->name,5 hint: 'This will be displayed on your profile.'6);
必需值
如果你要求必須輸入一個值,可以傳遞 required 引數。
1$name = text(2 label: 'What is your name?',3 required: true4);
如果你想自定義驗證訊息,也可以傳遞一個字串。
1$name = text(2 label: 'What is your name?',3 required: 'Your name is required.'4);
額外驗證
最後,如果你想執行額外的驗證邏輯,可以向 validate 引數傳遞一個閉包。
1$name = text(2 label: 'What is your name?',3 validate: fn (string $value) => match (true) {4 strlen($value) < 3 => 'The name must be at least 3 characters.',5 strlen($value) > 255 => 'The name must not exceed 255 characters.',6 default => null7 }8);
閉包將接收已輸入的值,並返回一個錯誤訊息;如果驗證透過,則返回 null。
此外,你也可以利用 Laravel 驗證器 的強大功能。為此,請向 validate 引數提供一個包含屬性名稱和所需驗證規則的陣列。
1$name = text(2 label: 'What is your name?',3 validate: ['name' => 'required|max:255|unique:users']4);
多行文字輸入 (Textarea)
textarea 函式將向用戶提出給定的問題,透過多行文字區域接收輸入,然後將其返回。
1use function Laravel\Prompts\textarea;2 3$story = textarea('Tell me a story.');
你還可以包含佔位符文字、預設值和提示資訊。
1$story = textarea(2 label: 'Tell me a story.',3 placeholder: 'This is a story about...',4 hint: 'This will be displayed on your profile.'5);
必需值
如果你要求必須輸入一個值,可以傳遞 required 引數。
1$story = textarea(2 label: 'Tell me a story.',3 required: true4);
如果你想自定義驗證訊息,也可以傳遞一個字串。
1$story = textarea(2 label: 'Tell me a story.',3 required: 'A story is required.'4);
額外驗證
最後,如果你想執行額外的驗證邏輯,可以向 validate 引數傳遞一個閉包。
1$story = textarea(2 label: 'Tell me a story.',3 validate: fn (string $value) => match (true) {4 strlen($value) < 250 => 'The story must be at least 250 characters.',5 strlen($value) > 10000 => 'The story must not exceed 10,000 characters.',6 default => null7 }8);
閉包將接收已輸入的值,並返回一個錯誤訊息;如果驗證透過,則返回 null。
此外,你也可以利用 Laravel 驗證器 的強大功能。為此,請向 validate 引數提供一個包含屬性名稱和所需驗證規則的陣列。
1$story = textarea(2 label: 'Tell me a story.',3 validate: ['story' => 'required|max:10000']4);
數字輸入 (Number)
number 函式將向用戶提出給定的問題,接收他們的數字輸入,然後將其返回。number 函式允許使用者使用上下箭頭鍵來調整數字。
1use function Laravel\Prompts\number;2 3$number = number('How many copies would you like?');
你還可以包含佔位符文字、預設值和提示資訊。
1$name = number(2 label: 'How many copies would you like?',3 placeholder: '5',4 default: 1,5 hint: 'This will be determine how many copies to create.'6);
必需值
如果你要求必須輸入一個值,可以傳遞 required 引數。
1$copies = number(2 label: 'How many copies would you like?',3 required: true4);
如果你想自定義驗證訊息,也可以傳遞一個字串。
1$copies = number(2 label: 'How many copies would you like?',3 required: 'A number of copies is required.'4);
額外驗證
最後,如果你想執行額外的驗證邏輯,可以向 validate 引數傳遞一個閉包。
1$copies = number(2 label: 'How many copies would you like?',3 validate: fn (?int $value) => match (true) {4 $value < 1 => 'At least one copy is required.',5 $value > 100 => 'You may not create more than 100 copies.',6 default => null7 }8);
閉包將接收已輸入的值,並返回一個錯誤訊息;如果驗證透過,則返回 null。
此外,你也可以利用 Laravel 驗證器 的強大功能。為此,請向 validate 引數提供一個包含屬性名稱和所需驗證規則的陣列。
1$copies = number(2 label: 'How many copies would you like?',3 validate: ['copies' => 'required|integer|min:1|max:100']4);
密碼輸入 (Password)
password 函式與 text 函式類似,但使用者輸入時在控制檯會被掩碼。這在詢問敏感資訊(如密碼)時非常有用。
1use function Laravel\Prompts\password;2 3$password = password('What is your password?');
你還可以包含佔位符文字和提示資訊。
1$password = password(2 label: 'What is your password?',3 placeholder: 'password',4 hint: 'Minimum 8 characters.'5);
必需值
如果你要求必須輸入一個值,可以傳遞 required 引數。
1$password = password(2 label: 'What is your password?',3 required: true4);
如果你想自定義驗證訊息,也可以傳遞一個字串。
1$password = password(2 label: 'What is your password?',3 required: 'The password is required.'4);
額外驗證
最後,如果你想執行額外的驗證邏輯,可以向 validate 引數傳遞一個閉包。
1$password = password(2 label: 'What is your password?',3 validate: fn (string $value) => match (true) {4 strlen($value) < 8 => 'The password must be at least 8 characters.',5 default => null6 }7);
閉包將接收已輸入的值,並返回一個錯誤訊息;如果驗證透過,則返回 null。
此外,你也可以利用 Laravel 驗證器 的強大功能。為此,請向 validate 引數提供一個包含屬性名稱和所需驗證規則的陣列。
1$password = password(2 label: 'What is your password?',3 validate: ['password' => 'min:8']4);
確認 (Confirm)
如果你需要向用戶詢問“是或否”的確認,可以使用 confirm 函式。使用者可以使用箭頭鍵或按下 y 或 n 來選擇他們的響應。此函式將返回 true 或 false。
1use function Laravel\Prompts\confirm;2 3$confirmed = confirm('Do you accept the terms?');
你還可以包含預設值、自定義“是”和“否”標籤的文字,以及提示資訊。
1$confirmed = confirm(2 label: 'Do you accept the terms?',3 default: false,4 yes: 'I accept',5 no: 'I decline',6 hint: 'The terms must be accepted to continue.'7);
要求選擇“是”
如有必要,你可以透過傳遞 required 引數要求使用者必須選擇“是”。
1$confirmed = confirm(2 label: 'Do you accept the terms?',3 required: true4);
如果你想自定義驗證訊息,也可以傳遞一個字串。
1$confirmed = confirm(2 label: 'Do you accept the terms?',3 required: 'You must accept the terms to continue.'4);
單選 (Select)
如果你需要使用者從預定義的選項集中進行選擇,可以使用 select 函式。
1use function Laravel\Prompts\select;2 3$role = select(4 label: 'What role should the user have?',5 options: ['Member', 'Contributor', 'Owner']6);
你還可以指定預設選項和提示資訊。
1$role = select(2 label: 'What role should the user have?',3 options: ['Member', 'Contributor', 'Owner'],4 default: 'Owner',5 hint: 'The role may be changed at any time.'6);
你也可以向 options 引數傳遞關聯陣列,以返回所選的鍵而不是值。
1$role = select(2 label: 'What role should the user have?',3 options: [4 'member' => 'Member',5 'contributor' => 'Contributor',6 'owner' => 'Owner',7 ],8 default: 'owner'9);
在列表滾動之前最多顯示五個選項。你可以透過傳遞 scroll 引數來自定義此數量。
1$role = select(2 label: 'Which category would you like to assign?',3 options: Category::pluck('name', 'id'),4 scroll: 105);
次要資訊
info 引數可用於顯示關於當前高亮選項的附加資訊。當提供閉包時,它將接收當前高亮選項的值,並應返回字串或 null。
1$role = select( 2 label: 'What role should the user have?', 3 options: [ 4 'member' => 'Member', 5 'contributor' => 'Contributor', 6 'owner' => 'Owner', 7 ], 8 info: fn (string $value) => match ($value) { 9 'member' => 'Can view and comment.',10 'contributor' => 'Can view, comment, and edit.',11 'owner' => 'Full access to all resources.',12 default => null,13 }14);
如果資訊不依賴於高亮選項,你也可以向 info 引數傳遞一個靜態字串。
1$role = select(2 label: 'What role should the user have?',3 options: ['Member', 'Contributor', 'Owner'],4 info: 'The role may be changed at any time.'5);
額外驗證
與其他提示函式不同,select 函式不接受 required 引數,因為不可能什麼都不選。但是,如果你需要展示一個選項但阻止它被選中,可以將閉包傳遞給 validate 引數。
1$role = select( 2 label: 'What role should the user have?', 3 options: [ 4 'member' => 'Member', 5 'contributor' => 'Contributor', 6 'owner' => 'Owner', 7 ], 8 validate: fn (string $value) => 9 $value === 'owner' && User::where('role', 'owner')->exists()10 ? 'An owner already exists.'11 : null12);
如果 options 引數是關聯陣列,閉包將接收選定的鍵;否則,它將接收選定的值。閉包可以返回錯誤訊息,或者在驗證透過時返回 null。
多選 (Multi-select)
如果你需要使用者能夠選擇多個選項,可以使用 multiselect 函式。
1use function Laravel\Prompts\multiselect;2 3$permissions = multiselect(4 label: 'What permissions should be assigned?',5 options: ['Read', 'Create', 'Update', 'Delete']6);
你還可以指定預設選擇和提示資訊。
1use function Laravel\Prompts\multiselect;2 3$permissions = multiselect(4 label: 'What permissions should be assigned?',5 options: ['Read', 'Create', 'Update', 'Delete'],6 default: ['Read', 'Create'],7 hint: 'Permissions may be updated at any time.'8);
你也可以向 options 引數傳遞關聯陣列,以返回所選選項的鍵而不是值。
1$permissions = multiselect( 2 label: 'What permissions should be assigned?', 3 options: [ 4 'read' => 'Read', 5 'create' => 'Create', 6 'update' => 'Update', 7 'delete' => 'Delete', 8 ], 9 default: ['read', 'create']10);
在列表滾動之前最多顯示五個選項。你可以透過傳遞 scroll 引數來自定義此數量。
1$categories = multiselect(2 label: 'What categories should be assigned?',3 options: Category::pluck('name', 'id'),4 scroll: 105);
次要資訊
info 引數可用於顯示關於當前高亮選項的附加資訊。當提供閉包時,它將接收當前高亮選項的值,並應返回字串或 null。
1$permissions = multiselect( 2 label: 'What permissions should be assigned?', 3 options: [ 4 'read' => 'Read', 5 'create' => 'Create', 6 'update' => 'Update', 7 'delete' => 'Delete', 8 ], 9 info: fn (string $value) => match ($value) {10 'read' => 'View resources and their properties.',11 'create' => 'Create new resources.',12 'update' => 'Modify existing resources.',13 'delete' => 'Permanently remove resources.',14 default => null,15 }16);
要求必須選擇
預設情況下,使用者可以選擇零個或多個選項。你可以透過傳遞 required 引數來強制要求選擇一個或多個選項。
1$categories = multiselect(2 label: 'What categories should be assigned?',3 options: Category::pluck('name', 'id'),4 required: true5);
如果你想自定義驗證訊息,可以向 required 引數提供一個字串。
1$categories = multiselect(2 label: 'What categories should be assigned?',3 options: Category::pluck('name', 'id'),4 required: 'You must select at least one category'5);
額外驗證
如果你需要展示一個選項但阻止它被選中,可以將閉包傳遞給 validate 引數。
1$permissions = multiselect( 2 label: 'What permissions should the user have?', 3 options: [ 4 'read' => 'Read', 5 'create' => 'Create', 6 'update' => 'Update', 7 'delete' => 'Delete', 8 ], 9 validate: fn (array $values) => ! in_array('read', $values)10 ? 'All users require the read permission.'11 : null12);
如果 options 引數是關聯陣列,閉包將接收選定的鍵;否則,它將接收選定的值。閉包可以返回錯誤訊息,或者在驗證透過時返回 null。
建議 (Suggest)
suggest 函式可用於為可能的選擇提供自動補全。無論自動補全的提示如何,使用者仍然可以輸入任何答案。
1use function Laravel\Prompts\suggest;2 3$name = suggest('What is your name?', ['Taylor', 'Dayle']);
此外,你可以將閉包作為 suggest 函式的第二個引數傳遞。每次使用者輸入字元時都會呼叫該閉包。閉包應接受一個包含使用者目前輸入內容的字串引數,並返回一個用於自動補全的選項陣列。
1$name = suggest(2 label: 'What is your name?',3 options: fn ($value) => collect(['Taylor', 'Dayle'])4 ->filter(fn ($name) => Str::contains($name, $value, ignoreCase: true))5)
你還可以包含佔位符文字、預設值和提示資訊。
1$name = suggest(2 label: 'What is your name?',3 options: ['Taylor', 'Dayle'],4 placeholder: 'E.g. Taylor',5 default: $user?->name,6 hint: 'This will be displayed on your profile.'7);
次要資訊
info 引數可用於顯示關於當前高亮選項的附加資訊。當提供閉包時,它將接收當前高亮選項的值,並應返回字串或 null。
1$name = suggest(2 label: 'What is your name?',3 options: ['Taylor', 'Dayle'],4 info: fn (string $value) => match ($value) {5 'Taylor' => 'Administrator',6 'Dayle' => 'Contributor',7 default => null,8 }9);
必需值
如果你要求必須輸入一個值,可以傳遞 required 引數。
1$name = suggest(2 label: 'What is your name?',3 options: ['Taylor', 'Dayle'],4 required: true5);
如果你想自定義驗證訊息,也可以傳遞一個字串。
1$name = suggest(2 label: 'What is your name?',3 options: ['Taylor', 'Dayle'],4 required: 'Your name is required.'5);
額外驗證
最後,如果你想執行額外的驗證邏輯,可以向 validate 引數傳遞一個閉包。
1$name = suggest(2 label: 'What is your name?',3 options: ['Taylor', 'Dayle'],4 validate: fn (string $value) => match (true) {5 strlen($value) < 3 => 'The name must be at least 3 characters.',6 strlen($value) > 255 => 'The name must not exceed 255 characters.',7 default => null8 }9);
閉包將接收已輸入的值,並返回一個錯誤訊息;如果驗證透過,則返回 null。
此外,你也可以利用 Laravel 驗證器 的強大功能。為此,請向 validate 引數提供一個包含屬性名稱和所需驗證規則的陣列。
1$name = suggest(2 label: 'What is your name?',3 options: ['Taylor', 'Dayle'],4 validate: ['name' => 'required|min:3|max:255']5);
搜尋
如果你有大量選項供使用者選擇,search 函式允許使用者鍵入搜尋查詢來過濾結果,然後再使用箭頭鍵選擇選項。
1use function Laravel\Prompts\search;2 3$id = search(4 label: 'Search for the user that should receive the mail',5 options: fn (string $value) => strlen($value) > 06 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()7 : []8);
閉包將接收使用者目前鍵入的文字,並必須返回一個選項陣列。如果你返回關聯陣列,則將返回所選選項的鍵;否則將返回其值。
當過濾陣列且打算返回該值時,應使用 array_values 函式或 values 集合方法,以確保陣列不會變成關聯陣列。
1$names = collect(['Taylor', 'Abigail']);2 3$selected = search(4 label: 'Search for the user that should receive the mail',5 options: fn (string $value) => $names6 ->filter(fn ($name) => Str::contains($name, $value, ignoreCase: true))7 ->values()8 ->all(),9);
你還可以包含佔位符文字和提示資訊。
1$id = search(2 label: 'Search for the user that should receive the mail',3 placeholder: 'E.g. Taylor Otwell',4 options: fn (string $value) => strlen($value) > 05 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()6 : [],7 hint: 'The user will receive an email immediately.'8);
在列表滾動之前最多顯示五個選項。你可以透過傳遞 scroll 引數來自定義此數量。
1$id = search(2 label: 'Search for the user that should receive the mail',3 options: fn (string $value) => strlen($value) > 04 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()5 : [],6 scroll: 107);
次要資訊
info 引數可用於顯示關於當前高亮選項的附加資訊。當提供閉包時,它將接收當前高亮選項的值,並應返回字串或 null。
1$id = search(2 label: 'Search for the user that should receive the mail',3 options: fn (string $value) => strlen($value) > 04 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()5 : [],6 info: fn (int $userId) => User::find($userId)?->email7);
額外驗證
如果你想執行額外的驗證邏輯,可以向 validate 引數傳遞一個閉包。
1$id = search( 2 label: 'Search for the user that should receive the mail', 3 options: fn (string $value) => strlen($value) > 0 4 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all() 5 : [], 6 validate: function (int|string $value) { 7 $user = User::findOrFail($value); 8 9 if ($user->opted_out) {10 return 'This user has opted-out of receiving mail.';11 }12 }13);
如果 options 閉包返回關聯陣列,閉包將接收選定的鍵;否則,它將接收選定的值。閉包可以返回錯誤訊息,或者在驗證透過時返回 null。
多選搜尋 (Multi-search)
如果你有大量可搜尋的選項,並且需要使用者能夠選擇多個專案,multisearch 函式允許使用者鍵入搜尋查詢來過濾結果,然後再使用箭頭鍵和空格鍵選擇選項。
1use function Laravel\Prompts\multisearch;2 3$ids = multisearch(4 'Search for the users that should receive the mail',5 fn (string $value) => strlen($value) > 06 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()7 : []8);
閉包將接收使用者目前鍵入的文字,並必須返回一個選項陣列。如果你返回關聯陣列,則將返回所選選項的鍵;否則將返回它們的值。
當過濾陣列且打算返回該值時,應使用 array_values 函式或 values 集合方法,以確保陣列不會變成關聯陣列。
1$names = collect(['Taylor', 'Abigail']);2 3$selected = multisearch(4 label: 'Search for the users that should receive the mail',5 options: fn (string $value) => $names6 ->filter(fn ($name) => Str::contains($name, $value, ignoreCase: true))7 ->values()8 ->all(),9);
你還可以包含佔位符文字和提示資訊。
1$ids = multisearch(2 label: 'Search for the users that should receive the mail',3 placeholder: 'E.g. Taylor Otwell',4 options: fn (string $value) => strlen($value) > 05 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()6 : [],7 hint: 'The user will receive an email immediately.'8);
在列表滾動之前最多顯示五個選項。你可以透過提供 scroll 引數來自定義此數量。
1$ids = multisearch(2 label: 'Search for the users that should receive the mail',3 options: fn (string $value) => strlen($value) > 04 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()5 : [],6 scroll: 107);
次要資訊
info 引數可用於顯示關於當前高亮選項的附加資訊。當提供閉包時,它將接收當前高亮選項的值,並應返回字串或 null。
1$ids = multisearch(2 label: 'Search for the users that should receive the mail',3 options: fn (string $value) => strlen($value) > 04 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()5 : [],6 info: fn (int $userId) => User::find($userId)?->email7);
要求必須選擇
預設情況下,使用者可以選擇零個或多個選項。你可以透過傳遞 required 引數來強制要求選擇一個或多個選項。
1$ids = multisearch(2 label: 'Search for the users that should receive the mail',3 options: fn (string $value) => strlen($value) > 04 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()5 : [],6 required: true7);
如果你想自定義驗證訊息,也可以向 required 引數提供一個字串。
1$ids = multisearch(2 label: 'Search for the users that should receive the mail',3 options: fn (string $value) => strlen($value) > 04 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()5 : [],6 required: 'You must select at least one user.'7);
額外驗證
如果你想執行額外的驗證邏輯,可以向 validate 引數傳遞一個閉包。
1$ids = multisearch( 2 label: 'Search for the users that should receive the mail', 3 options: fn (string $value) => strlen($value) > 0 4 ? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all() 5 : [], 6 validate: function (array $values) { 7 $optedOut = User::whereLike('name', '%a%')->findMany($values); 8 9 if ($optedOut->isNotEmpty()) {10 return $optedOut->pluck('name')->join(', ', ', and ').' have opted out.';11 }12 }13);
如果 options 閉包返回關聯陣列,閉包將接收選定的鍵;否則,它將接收選定的值。閉包可以返回錯誤訊息,或者在驗證透過時返回 null。
暫停 (Pause)
pause 函式可用於向用戶顯示提示文字,並等待他們按下回車鍵(Enter / Return)來確認他們希望繼續。
1use function Laravel\Prompts\pause;2 3pause('Press ENTER to continue.');
自動補全 (Autocomplete)
autocomplete 函式可用於為可能的選擇提供內聯自動補全。當用戶輸入時,匹配輸入的建議將以虛影文字形式出現,使用者可以透過按下 Tab 鍵或右箭頭鍵來接受該建議。
1use function Laravel\Prompts\autocomplete;2 3$name = autocomplete(4 label: 'What is your name?',5 options: ['Taylor', 'Dayle', 'Jess', 'Nuno', 'Tim']6);
你還可以包含佔位符文字、預設值和提示資訊。
1$name = autocomplete(2 label: 'What is your name?',3 options: ['Taylor', 'Dayle', 'Jess', 'Nuno', 'Tim'],4 placeholder: 'E.g. Taylor',5 default: $user?->name,6 hint: 'Use tab to accept, up/down to cycle.'7);
動態選項
你還可以傳遞一個閉包,根據使用者的輸入動態生成選項。每次使用者輸入字元時都會呼叫該閉包,它應返回一個用於自動補全的選項陣列。
1$file = autocomplete(2 label: 'Which file?',3 options: fn (string $value) => collect($files)4 ->filter(fn ($file) => str_starts_with(strtolower($file), strtolower($value)))5 ->values()6 ->all(),7);
必需值
如果你要求必須輸入一個值,可以傳遞 required 引數。
1$name = autocomplete(2 label: 'What is your name?',3 options: ['Taylor', 'Dayle', 'Jess', 'Nuno', 'Tim'],4 required: true5);
如果你想自定義驗證訊息,也可以傳遞一個字串。
1$name = autocomplete(2 label: 'What is your name?',3 options: ['Taylor', 'Dayle', 'Jess', 'Nuno', 'Tim'],4 required: 'Your name is required.'5);
額外驗證
最後,如果你想執行額外的驗證邏輯,可以向 validate 引數傳遞一個閉包。
1$name = autocomplete(2 label: 'What is your name?',3 options: ['Taylor', 'Dayle', 'Jess', 'Nuno', 'Tim'],4 validate: fn (string $value) => match (true) {5 strlen($value) < 3 => 'The name must be at least 3 characters.',6 strlen($value) > 255 => 'The name must not exceed 255 characters.',7 default => null8 }9);
閉包將接收已輸入的值,並返回一個錯誤訊息;如果驗證透過,則返回 null。
在驗證前轉換輸入
有時你可能希望在驗證發生之前轉換提示輸入。例如,你可能希望刪除任何提供字串中的空格。為了實現這一點,許多提示函式提供了 transform 引數,該引數接受一個閉包。
1$name = text(2 label: 'What is your name?',3 transform: fn (string $value) => trim($value),4 validate: fn (string $value) => match (true) {5 strlen($value) < 3 => 'The name must be at least 3 characters.',6 strlen($value) > 255 => 'The name must not exceed 255 characters.',7 default => null8 }9);
表單 (Forms)
通常,你需要按順序顯示多個提示,以便在執行額外操作之前收集資訊。你可以使用 form 函式建立一組提示,供使用者完成。
1use function Laravel\Prompts\form;2 3$responses = form()4 ->text('What is your name?', required: true)5 ->password('What is your password?', validate: ['password' => 'min:8'])6 ->confirm('Do you accept the terms?')7 ->submit();
submit 方法將返回一個包含表單中所有提示響應的數字索引陣列。但是,你可以透過 name 引數為每個提示提供名稱。當提供名稱時,可以透過該名稱訪問指定提示的響應。
1use App\Models\User; 2use function Laravel\Prompts\form; 3 4$responses = form() 5 ->text('What is your name?', required: true, name: 'name') 6 ->password( 7 label: 'What is your password?', 8 validate: ['password' => 'min:8'], 9 name: 'password'10 )11 ->confirm('Do you accept the terms?')12 ->submit();13 14User::create([15 'name' => $responses['name'],16 'password' => $responses['password'],17]);
使用 form 函式的主要好處是使用者可以使用 CTRL + U 返回表單中的上一個提示。這允許使用者糾正錯誤或更改選擇,而無需取消並重新啟動整個表單。
如果你需要對錶單中的提示進行更細粒度的控制,可以呼叫 add 方法,而不是直接呼叫提示函式。add 方法會接收使用者提供的所有先前響應。
1use function Laravel\Prompts\form; 2use function Laravel\Prompts\outro; 3use function Laravel\Prompts\text; 4 5$responses = form() 6 ->text('What is your name?', required: true, name: 'name') 7 ->add(function ($responses) { 8 return text("How old are you, {$responses['name']}?"); 9 }, name: 'age')10 ->submit();11 12outro("Your name is {$responses['name']} and you are {$responses['age']} years old.");
提示訊息
note、info、warning、error 和 alert 函式可用於顯示提示資訊。
1use function Laravel\Prompts\info;2 3info('Package installed successfully.');
資料表 (Tables)
table 函式可以輕鬆顯示多行和多列資料。你只需提供列名和表格資料即可。
1use function Laravel\Prompts\table;2 3table(4 headers: ['Name', 'Email'],5 rows: User::all(['name', 'email'])->toArray()6);
載入動畫 (Spin)
spin 函式在執行指定回撥時會顯示一個載入動畫和可選訊息。它用於指示正在進行的過程,並在完成後返回回撥的結果。
1use function Laravel\Prompts\spin;2 3$response = spin(4 callback: fn () => Http::get('http://example.com'),5 message: 'Fetching response...'6);
spin 函式需要 PCNTL PHP 擴充套件來播放載入動畫。當此擴充套件不可用時,將顯示靜態版本的載入動畫。
進度條
對於長時間執行的任務,顯示一個進度條來通知使用者任務的完成進度非常有用。使用 progress 函式,Laravel 將顯示一個進度條,並針對給定可迭代值的每次迭代推進進度。
1use function Laravel\Prompts\progress;2 3$users = progress(4 label: 'Updating users',5 steps: User::all(),6 callback: fn ($user) => $this->performTask($user)7);
progress 函式類似於 map 函式,並將返回一個數組,其中包含回撥每次迭代的返回值。
回撥還可以接受 Laravel\Prompts\Progress 例項,允許你在每次迭代時修改標籤和提示。
1$users = progress( 2 label: 'Updating users', 3 steps: User::all(), 4 callback: function ($user, $progress) { 5 $progress 6 ->label("Updating {$user->name}") 7 ->hint("Created on {$user->created_at}"); 8 9 return $this->performTask($user);10 },11 hint: 'This may take some time.'12);
有時,你可能需要更手動地控制進度條的推進方式。首先,定義程序將迭代的總步數。然後,在處理每個專案後透過 advance 方法推進進度條。
1$progress = progress(label: 'Updating users', steps: 10); 2 3$users = User::all(); 4 5$progress->start(); 6 7foreach ($users as $user) { 8 $this->performTask($user); 9 10 $progress->advance();11}12 13$progress->finish();
任務 (Task)
task 函式在給定回撥執行時顯示一個帶有載入動畫和滾動即時輸出區域的帶標籤任務。它非常適合封裝長時間執行的程序,如依賴項安裝或部署指令碼,從而提供對正在發生的事情的即時可見性。
1use function Laravel\Prompts\task;2 3task(4 label: 'Installing dependencies',5 callback: function ($logger) {6 // Long-running process...7 }8);
回撥接收一個 Logger 例項,你可以使用它在任務的輸出區域顯示日誌行、狀態訊息和流式文字。
task 函式需要 PCNTL PHP 擴充套件來播放載入動畫。當此擴充套件不可用時,將顯示靜態版本的任務。
日誌記錄
line 方法將單行日誌寫入任務的滾動輸出區域。
1task(2 label: 'Installing dependencies',3 callback: function ($logger) {4 $logger->line('Resolving packages...');5 // ...6 $logger->line('Downloading laravel/framework');7 // ...8 }9);
狀態訊息
你可以使用 success、warning 和 error 方法顯示狀態訊息。它們作為穩定的高亮訊息顯示在滾動日誌區域上方。
1task( 2 label: 'Deploying application', 3 callback: function ($logger) { 4 $logger->line('Pulling latest changes...'); 5 // ... 6 $logger->success('Changes pulled!'); 7 8 $logger->line('Running migrations...'); 9 // ...10 $logger->warning('No new migrations to run.');11 12 $logger->line('Clearing cache...');13 // ...14 $logger->success('Cache cleared!');15 }16);
更新標籤
label 方法允許你在任務執行時更新其標籤。
1task( 2 label: 'Starting deployment...', 3 callback: function ($logger) { 4 $logger->label('Pulling latest changes...'); 5 // ... 6 $logger->label('Running migrations...'); 7 // ... 8 $logger->label('Clearing cache...'); 9 // ...10 }11);
流式文字
對於增量產生輸出的程序(如 AI 生成的響應),partial 方法允許你逐字或逐塊流式傳輸文字。流完成後,呼叫 commitPartial 來完成輸出。
1task( 2 label: 'Generating response...', 3 callback: function ($logger) { 4 foreach ($words as $word) { 5 $logger->partial($word . ' '); 6 } 7 8 $logger->commitPartial(); 9 }10);
自定義輸出限制
預設情況下,任務最多顯示 10 行滾動輸出。你可以透過 limit 引數自定義此設定。
1task(2 label: 'Installing dependencies',3 callback: function ($logger) {4 // ...5 },6 limit: 207);
流式輸出 (Stream)
stream 函式顯示流向終端的文字,非常適合顯示 AI 生成的內容或任何增量到達的文字。
1use function Laravel\Prompts\stream; 2 3$stream = stream(); 4 5foreach ($words as $word) { 6 $stream->append($word . ' '); 7 usleep(25_000); // Simulate delay between chunks... 8} 9 10$stream->close();
append 方法將文字新增到流中,並以逐漸淡入的效果渲染它。當所有內容都流式傳輸完畢後,呼叫 close 方法來完成輸出並恢復游標。
終端標題 (Terminal Title)
title 函式更新使用者終端視窗或標籤頁的標題。
1use function Laravel\Prompts\title;2 3title('Installing Dependencies');
要將終端標題重置回預設狀態,請傳遞一個空字串。
1title('');
清空終端
clear 函式可用於清空使用者的終端。
1use function Laravel\Prompts\clear;2 3clear();
終端注意事項
終端寬度
如果任何標籤、選項或驗證訊息的長度超過使用者終端中的“列”數,它將被自動截斷以適應。如果你的使用者可能使用較窄的終端,請考慮儘量縮短這些字串的長度。為了支援 80 字元的終端,通常安全的最大長度為 74 個字元。
終端高度
對於任何接受 scroll 引數的提示,配置的值將自動減小以適應使用者終端的高度,包括驗證訊息的空間。
不支援的環境與回退機制
Laravel Prompts 支援 macOS、Linux 和帶有 WSL 的 Windows。由於 Windows 版 PHP 的限制,目前無法在 WSL 之外的 Windows 上使用 Laravel Prompts。
因此,Laravel Prompts 支援回退到替代實現,例如 Symfony 控制檯問答助手 (Symfony Console Question Helper)。
當在 Laravel 框架中使用 Laravel Prompts 時,每個提示的回退設定已經為你配置好,並且會在不支援的環境中自動啟用。
回退條件
如果你沒有使用 Laravel 或需要自定義何時使用回退行為,可以向 Prompt 類上的 fallbackWhen 靜態方法傳遞一個布林值。
1use Laravel\Prompts\Prompt;2 3Prompt::fallbackWhen(4 ! $input->isInteractive() || windows_os() || app()->runningUnitTests()5);
回退行為
如果你沒有使用 Laravel 或需要自定義回退行為,可以向每個提示類上的 fallbackUsing 靜態方法傳遞一個閉包。
1use Laravel\Prompts\TextPrompt; 2use Symfony\Component\Console\Question\Question; 3use Symfony\Component\Console\Style\SymfonyStyle; 4 5TextPrompt::fallbackUsing(function (TextPrompt $prompt) use ($input, $output) { 6 $question = (new Question($prompt->label, $prompt->default ?: null)) 7 ->setValidator(function ($answer) use ($prompt) { 8 if ($prompt->required && $answer === null) { 9 throw new \RuntimeException(10 is_string($prompt->required) ? $prompt->required : 'Required.'11 );12 }13 14 if ($prompt->validate) {15 $error = ($prompt->validate)($answer ?? '');16 17 if ($error) {18 throw new \RuntimeException($error);19 }20 }21 22 return $answer;23 });24 25 return (new SymfonyStyle($input, $output))26 ->askQuestion($question);27});
必須為每個提示類單獨配置回退。閉包將接收該提示類的例項,並必須返回適合該提示的型別。
測試
Laravel 提供了多種方法來測試你的命令是否顯示了預期的提示訊息。
1test('report generation', function () { 2 $this->artisan('report:generate') 3 ->expectsPromptsInfo('Welcome to the application!') 4 ->expectsPromptsWarning('This action cannot be undone') 5 ->expectsPromptsError('Something went wrong') 6 ->expectsPromptsAlert('Important notice!') 7 ->expectsPromptsIntro('Starting process...') 8 ->expectsPromptsOutro('Process completed!') 9 ->expectsPromptsTable(10 headers: ['Name', 'Email'],11 rows: [14 ]15 )16 ->assertExitCode(0);17});
1public function test_report_generation(): void 2{ 3 $this->artisan('report:generate') 4 ->expectsPromptsInfo('Welcome to the application!') 5 ->expectsPromptsWarning('This action cannot be undone') 6 ->expectsPromptsError('Something went wrong') 7 ->expectsPromptsAlert('Important notice!') 8 ->expectsPromptsIntro('Starting process...') 9 ->expectsPromptsOutro('Process completed!')10 ->expectsPromptsTable(11 headers: ['Name', 'Email'],12 rows: [15 ]16 )17 ->assertExitCode(0);18}