Introduction
Laravel Promptsは、プレースホルダーテキストやバリデーションを含むブラウザのような機能を備えた、美しくユーザーフレンドリーなフォームをコマンドラインアプリケーションに追加するためのPHPパッケージです。
Laravel Promptsは、Artisanコンソールコマンドでユーザー入力を受け付けるのに最適ですが、任意のコマンドラインPHPプロジェクトでも使用できます。
Laravel Promptsは、macOS、Linux、およびWSLを使用したWindowsをサポートしています。詳細については、サポートされていない環境とフォールバックに関するドキュメントをご覧ください。
Installation
Laravel Promptsは、最新のLaravelリリースにすでに含まれています。
Laravel Promptsは、Composerパッケージマネージャーを使用して他のPHPプロジェクトにもインストールできます:
composer require laravel/prompts
Available Prompts
Text
``````php
use function Laravel\Prompts\text;
$name = text('What is your name?');
`
プレースホルダーテキスト、デフォルト値、および情報のヒントを含めることもできます:
$name = text(
label: 'What is your name?',
placeholder: 'E.g. Taylor Otwell',
default: $user?->name,
hint: 'This will be displayed on your profile.'
);
Required Values
値の入力が必要な場合は、required
引数を渡すことができます:
$name = text(
label: 'What is your name?',
required: true
);
バリデーションメッセージをカスタマイズしたい場合は、文字列を渡すこともできます:
$name = text(
label: 'What is your name?',
required: 'Your name is required.'
);
Additional Validation
最後に、追加のバリデーションロジックを実行したい場合は、validate
引数にクロージャを渡すことができます:
$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
}
);
クロージャは、入力された値を受け取り、エラーメッセージを返すか、バリデーションが成功した場合はnull
を返すことができます。
また、Laravelのvalidatorの力を活用することもできます。そのためには、validate
引数に属性名と希望するバリデーションルールを含む配列を提供します:
$name = text(
label: 'What is your name?',
validate: ['name' => 'required|max:255|unique:users']
);
Textarea
``````php
use function Laravel\Prompts\textarea;
$story = textarea('Tell me a story.');
`
プレースホルダーテキスト、デフォルト値、および情報のヒントを含めることもできます:
$story = textarea(
label: 'Tell me a story.',
placeholder: 'This is a story about...',
hint: 'This will be displayed on your profile.'
);
Required Values
値の入力が必要な場合は、required
引数を渡すことができます:
$story = textarea(
label: 'Tell me a story.',
required: true
);
バリデーションメッセージをカスタマイズしたい場合は、文字列を渡すこともできます:
$story = textarea(
label: 'Tell me a story.',
required: 'A story is required.'
);
Additional Validation
最後に、追加のバリデーションロジックを実行したい場合は、validate
引数にクロージャを渡すことができます:
$story = textarea(
label: 'Tell me a story.',
validate: fn (string $value) => match (true) {
strlen($value) < 250 => 'The story must be at least 250 characters.',
strlen($value) > 10000 => 'The story must not exceed 10,000 characters.',
default => null
}
);
クロージャは、入力された値を受け取り、エラーメッセージを返すか、バリデーションが成功した場合はnull
を返すことができます。
また、Laravelのvalidatorの力を活用することもできます。そのためには、validate
引数に属性名と希望するバリデーションルールを含む配列を提供します:
$story = textarea(
label: 'Tell me a story.',
validate: ['story' => 'required|max:10000']
);
Password
``````php
use function Laravel\Prompts\password;
$password = password('What is your password?');
`
プレースホルダーテキストと情報のヒントを含めることもできます:
$password = password(
label: 'What is your password?',
placeholder: 'password',
hint: 'Minimum 8 characters.'
);
Required Values
値の入力が必要な場合は、required
引数を渡すことができます:
$password = password(
label: 'What is your password?',
required: true
);
バリデーションメッセージをカスタマイズしたい場合は、文字列を渡すこともできます:
$password = password(
label: 'What is your password?',
required: 'The password is required.'
);
Additional Validation
最後に、追加のバリデーションロジックを実行したい場合は、validate
引数にクロージャを渡すことができます:
$password = password(
label: 'What is your password?',
validate: fn (string $value) => match (true) {
strlen($value) < 8 => 'The password must be at least 8 characters.',
default => null
}
);
クロージャは、入力された値を受け取り、エラーメッセージを返すか、バリデーションが成功した場合はnull
を返すことができます。
また、Laravelのvalidatorの力を活用することもできます。そのためには、validate
引数に属性名と希望するバリデーションルールを含む配列を提供します:
$password = password(
label: 'What is your password?',
validate: ['password' => 'min:8']
);
Confirm
ユーザーに「はいまたはいいえ」の確認を求める必要がある場合は、confirm
関数を使用できます。ユーザーは矢印キーを使用するか、y
またはn
を押して応答を選択できます。この関数はtrue
またはfalse
のいずれかを返します。
use function Laravel\Prompts\confirm;
$confirmed = confirm('Do you accept the terms?');
デフォルト値、カスタマイズされた「はい」と「いいえ」ラベルの文言、および情報のヒントを含めることもできます:
$confirmed = confirm(
label: 'Do you accept the terms?',
default: false,
yes: 'I accept',
no: 'I decline',
hint: 'The terms must be accepted to continue.'
);
Requiring “Yes”
必要に応じて、required
引数を渡すことでユーザーに「はい」を選択させることができます:
$confirmed = confirm(
label: 'Do you accept the terms?',
required: true
);
バリデーションメッセージをカスタマイズしたい場合は、文字列を渡すこともできます:
$confirmed = confirm(
label: 'Do you accept the terms?',
required: 'You must accept the terms to continue.'
);
Select
ユーザーに事前定義された選択肢から選択させる必要がある場合は、select
関数を使用できます:
use function Laravel\Prompts\select;
$role = select(
label: 'What role should the user have?',
options: ['Member', 'Contributor', 'Owner']
);
デフォルトの選択肢と情報のヒントを指定することもできます:
$role = select(
label: 'What role should the user have?',
options: ['Member', 'Contributor', 'Owner'],
default: 'Owner',
hint: 'The role may be changed at any time.'
);
選択されたキーがその値の代わりに返されるように、options
引数に連想配列を渡すこともできます:
$role = select(
label: 'What role should the user have?',
options: [
'member' => 'Member',
'contributor' => 'Contributor',
'owner' => 'Owner',
],
default: 'owner'
);
最大5つのオプションが表示され、リストがスクロールし始める前に表示されます。このカスタマイズは、scroll
引数を渡すことで行えます:
$role = select(
label: 'Which category would you like to assign?',
options: Category::pluck('name', 'id'),
scroll: 10
);
Additional Validation
他のプロンプト関数とは異なり、select
関数はrequired
引数を受け付けません。なぜなら、何も選択しないことはできないからです。ただし、選択肢を提示しながら選択を防ぐ必要がある場合は、validate
引数にクロージャを渡すことができます:
$role = select(
label: 'What role should the user have?',
options: [
'member' => 'Member',
'contributor' => 'Contributor',
'owner' => 'Owner',
],
validate: fn (string $value) =>
$value === 'owner' && User::where('role', 'owner')->exists()
? 'An owner already exists.'
: null
);
<a name="multiselect"></a>
### Multi-select
ユーザーが複数のオプションを選択できるようにする必要がある場合は、`````multiselect`````関数を使用できます:
``````php
use function Laravel\Prompts\multiselect;
$permissions = multiselect(
label: 'What permissions should be assigned?',
options: ['Read', 'Create', 'Update', 'Delete']
);
`
デフォルトの選択肢と情報のヒントを指定することもできます:
use function Laravel\Prompts\multiselect;
$permissions = multiselect(
label: 'What permissions should be assigned?',
options: ['Read', 'Create', 'Update', 'Delete'],
default: ['Read', 'Create'],
hint: 'Permissions may be updated at any time.'
);
選択されたオプションのキーをその値の代わりに返すように、options
引数に連想配列を渡すこともできます:
$permissions = multiselect(
label: 'What permissions should be assigned?',
options: [
'read' => 'Read',
'create' => 'Create',
'update' => 'Update',
'delete' => 'Delete',
],
default: ['read', 'create']
);
最大5つのオプションが表示され、リストがスクロールし始める前に表示されます。このカスタマイズは、scroll
引数を渡すことで行えます:
$categories = multiselect(
label: 'What categories should be assigned?',
options: Category::pluck('name', 'id'),
scroll: 10
);
Requiring a Value
デフォルトでは、ユーザーは0個以上のオプションを選択できます。required
引数を渡すことで、1つ以上のオプションを強制することができます:
$categories = multiselect(
label: 'What categories should be assigned?',
options: Category::pluck('name', 'id'),
required: true
);
バリデーションメッセージをカスタマイズしたい場合は、required
引数に文字列を提供できます:
$categories = multiselect(
label: 'What categories should be assigned?',
options: Category::pluck('name', 'id'),
required: 'You must select at least one category'
);
Additional Validation
選択肢を提示しながら選択を防ぐ必要がある場合は、validate
引数にクロージャを渡すことができます:
$permissions = multiselect(
label: 'What permissions should the user have?',
options: [
'read' => 'Read',
'create' => 'Create',
'update' => 'Update',
'delete' => 'Delete',
],
validate: fn (array $values) => ! in_array('read', $values)
? 'All users require the read permission.'
: null
);
<a name="suggest"></a>
### Suggest
`````suggest`````関数は、可能な選択肢の自動補完を提供するために使用できます。ユーザーは自動補完のヒントに関係なく、任意の回答を提供できます:
``````php
use function Laravel\Prompts\suggest;
$name = suggest('What is your name?', ['Taylor', 'Dayle']);
`
また、suggest
関数の第2引数としてクロージャを渡すこともできます。クロージャは、ユーザーが入力文字をタイプするたびに呼び出されます。クロージャは、ユーザーの現在の入力を含む文字列パラメータを受け取り、自動補完のためのオプションの配列を返す必要があります:
$name = suggest(
label: 'What is your name?',
options: fn ($value) => collect(['Taylor', 'Dayle'])
->filter(fn ($name) => Str::contains($name, $value, ignoreCase: true))
)
プレースホルダーテキスト、デフォルト値、および情報のヒントを含めることもできます:
$name = suggest(
label: 'What is your name?',
options: ['Taylor', 'Dayle'],
placeholder: 'E.g. Taylor',
default: $user?->name,
hint: 'This will be displayed on your profile.'
);
Required Values
値の入力が必要な場合は、required
引数を渡すことができます:
$name = suggest(
label: 'What is your name?',
options: ['Taylor', 'Dayle'],
required: true
);
バリデーションメッセージをカスタマイズしたい場合は、文字列を渡すこともできます:
$name = suggest(
label: 'What is your name?',
options: ['Taylor', 'Dayle'],
required: 'Your name is required.'
);
Additional Validation
最後に、追加のバリデーションロジックを実行したい場合は、validate
引数にクロージャを渡すことができます:
$name = suggest(
label: 'What is your name?',
options: ['Taylor', 'Dayle'],
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
}
);
クロージャは、入力された値を受け取り、エラーメッセージを返すか、バリデーションが成功した場合はnull
を返すことができます。
また、Laravelのvalidatorの力を活用することもできます。そのためには、validate
引数に属性名と希望するバリデーションルールを含む配列を提供します:
$name = suggest(
label: 'What is your name?',
options: ['Taylor', 'Dayle'],
validate: ['name' => 'required|min:3|max:255']
);
Search
ユーザーが選択するオプションが多い場合、search
関数を使用すると、ユーザーは検索クエリを入力して結果をフィルタリングし、矢印キーを使用してオプションを選択できます:
use function Laravel\Prompts\search;
$id = 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()
: []
);
クロージャは、ユーザーがこれまでに入力したテキストを受け取り、オプションの配列を返す必要があります。連想配列を返すと、選択されたオプションのキーが返されます。そうでない場合は、その値が返されます。
プレースホルダーテキストと情報のヒントを含めることもできます:
$id = search(
label: 'Search for the user that should receive the mail',
placeholder: 'E.g. Taylor Otwell',
options: fn (string $value) => strlen($value) > 0
? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()
: [],
hint: 'The user will receive an email immediately.'
);
最大5つのオプションが表示され、リストがスクロールし始める前に表示されます。このカスタマイズは、scroll
引数を渡すことで行えます:
$id = 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()
: [],
scroll: 10
);
Additional Validation
追加のバリデーションロジックを実行したい場合は、validate
引数にクロージャを渡すことができます:
$id = 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()
: [],
validate: function (int|string $value) {
$user = User::findOrFail($value);
if ($user->opted_out) {
return 'This user has opted-out of receiving mail.';
}
}
);
<a name="multisearch"></a>
### Multi-search
検索可能なオプションが多く、ユーザーが複数のアイテムを選択できるようにする必要がある場合、`````multisearch`````関数を使用すると、ユーザーは検索クエリを入力して結果をフィルタリングし、矢印キーとスペースバーを使用してオプションを選択できます:
``````php
use function Laravel\Prompts\multisearch;
$ids = multisearch(
'Search for the users that should receive the mail',
fn (string $value) => strlen($value) > 0
? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()
: []
);
`
クロージャは、ユーザーがこれまでに入力したテキストを受け取り、オプションの配列を返す必要があります。連想配列を返すと、選択されたオプションのキーが返されます。そうでない場合は、その値が返されます。
プレースホルダーテキストと情報のヒントを含めることもできます:
$ids = multisearch(
label: 'Search for the users that should receive the mail',
placeholder: 'E.g. Taylor Otwell',
options: fn (string $value) => strlen($value) > 0
? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()
: [],
hint: 'The user will receive an email immediately.'
);
最大5つのオプションが表示され、リストがスクロールし始める前に表示されます。このカスタマイズは、scroll
引数を提供することで行えます:
$ids = 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()
: [],
scroll: 10
);
Requiring a Value
デフォルトでは、ユーザーは0個以上のオプションを選択できます。required
引数を渡すことで、1つ以上のオプションを強制することができます:
$ids = 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()
: [],
required: true
);
バリデーションメッセージをカスタマイズしたい場合は、required
引数に文字列を提供できます:
$ids = 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()
: [],
required: 'You must select at least one user.'
);
Additional Validation
追加のバリデーションロジックを実行したい場合は、validate
引数にクロージャを渡すことができます:
$ids = 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()
: [],
validate: function (array $values) {
$optedOut = User::whereLike('name', '%a%')->findMany($values);
if ($optedOut->isNotEmpty()) {
return $optedOut->pluck('name')->join(', ', ', and ').' have opted out.';
}
}
);
<a name="pause"></a>
### Pause
`````pause`````関数は、ユーザーに情報テキストを表示し、Enter / Returnキーを押して進むことを確認するのを待つために使用できます:
``````php
use function Laravel\Prompts\pause;
pause('Press ENTER to continue.');
`
Transforming Input Before Validation
時には、バリデーションが行われる前にプロンプト入力を変換したい場合があります。たとえば、提供された文字列から空白を削除したい場合です。これを実現するために、多くのプロンプト関数は、クロージャを受け入れるtransform
引数を提供します:
$name = text(
label: 'What is your name?',
transform: fn (string $value) => trim($value),
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
}
);
Forms
通常、追加のアクションを実行する前に情報を収集するために、順番に表示される複数のプロンプトがあります。form
関数を使用して、ユーザーが完了するためのプロンプトのグループセットを作成できます:
use function Laravel\Prompts\form;
$responses = form()
->text('What is your name?', required: true)
->password('What is your password?', validate: ['password' => 'min:8'])
->confirm('Do you accept the terms?')
->submit();
``````php
use App\Models\User;
use function Laravel\Prompts\form;
$responses = form()
->text('What is your name?', required: true, name: 'name')
->password(
label: 'What is your password?',
validate: ['password' => 'min:8'],
name: 'password'
)
->confirm('Do you accept the terms?')
->submit();
User::create([
'name' => $responses['name'],
'password' => $responses['password'],
]);
`
form
関数を使用する主な利点は、ユーザーがCTRL + U
を使用してフォーム内の以前のプロンプトに戻ることができることです。これにより、ユーザーは間違いを修正したり、選択を変更したりすることができ、フォーム全体をキャンセルして再起動する必要がなくなります。
フォーム内のプロンプトに対してより詳細な制御が必要な場合は、プロンプト関数の1つを直接呼び出す代わりにadd
メソッドを呼び出すことができます。add
メソッドには、ユーザーが提供したすべての以前の応答が渡されます:
use function Laravel\Prompts\form;
use function Laravel\Prompts\outro;
$responses = form()
->text('What is your name?', required: true, name: 'name')
->add(function ($responses) {
return text("How old are you, {$responses['name']}?");
}, name: 'age')
->submit();
outro("Your name is {$responses['name']} and you are {$responses['age']} years old.");
Informational Messages
``````php
use function Laravel\Prompts\info;
info('Package installed successfully.');
`
Tables
``````php
use function Laravel\Prompts\table;
table(
headers: ['Name', 'Email'],
rows: User::all(['name', 'email'])->toArray()
);
`
Spin
``````php
use function Laravel\Prompts\spin;
$response = spin(
message: 'Fetching response...',
callback: fn () => Http::get('http://example.com')
);
`
spin
関数は、スピナーをアニメーション化するためにpcntl
PHP拡張を必要とします。この拡張が利用できない場合、スピナーの静的バージョンが表示されます。
Progress Bars
長時間実行されるタスクの場合、タスクの完了度をユーザーに知らせるプログレスバーを表示することが役立ちます。progress
関数を使用すると、Laravelはプログレスバーを表示し、指定された反復可能な値の各反復に対してその進行を進めます:
use function Laravel\Prompts\progress;
$users = progress(
label: 'Updating users',
steps: User::all(),
callback: fn ($user) => $this->performTask($user)
);
コールバックは`````Laravel\Prompts\Progress`````インスタンスを受け入れることもでき、各反復でラベルとヒントを変更できます:
``````php
$users = progress(
label: 'Updating users',
steps: User::all(),
callback: function ($user, $progress) {
$progress
->label("Updating {$user->name}")
->hint("Created on {$user->created_at}");
return $this->performTask($user);
},
hint: 'This may take some time.'
);
`
時には、プログレスバーの進行を手動で制御する必要がある場合があります。まず、プロセスが反復する総ステップ数を定義します。次に、各アイテムを処理した後、advance
メソッドを介してプログレスバーを進めます:
$progress = progress(label: 'Updating users', steps: 10);
$users = User::all();
$progress->start();
foreach ($users as $user) {
$this->performTask($user);
$progress->advance();
}
$progress->finish();
Clearing the Terminal
``````php
use function Laravel\Prompts\clear;
clear();
`
Terminal Considerations
Terminal Width
ラベル、オプション、またはバリデーションメッセージの長さがユーザーのターミナルの「列」の数を超えると、自動的に切り捨てられます。ユーザーが狭いターミナルを使用する可能性がある場合は、これらの文字列の長さを最小限に抑えることを検討してください。通常、安全な最大長は74文字で、80文字のターミナルをサポートします。
Terminal Height
<a name="fallbacks"></a>
## Unsupported Environments and Fallbacks
Laravel Promptsは、macOS、Linux、およびWSLを使用したWindowsをサポートしています。PHPのWindowsバージョンの制限により、現在WSL以外のWindowsでLaravel Promptsを使用することはできません。
このため、Laravel Promptsは、[Symfony Console Question Helper](https://symfony.com/doc/7.0/components/console/helpers/questionhelper.html)などの代替実装にフォールバックすることをサポートしています。
LaravelフレームワークでLaravel Promptsを使用する場合、各プロンプトのフォールバックが自動的に設定され、サポートされていない環境で自動的に有効になります。
<a name="fallback-conditions"></a>
#### Fallback Conditions
Laravelを使用していない場合や、フォールバック動作が使用されるタイミングをカスタマイズする必要がある場合は、`````fallbackWhen`````静的メソッドにブール値を渡すことができます。`````Prompt`````クラス:
``````php
use Laravel\Prompts\Prompt;
Prompt::fallbackWhen(
! $input->isInteractive() || windows_os() || app()->runningUnitTests()
);
`
Fallback Behavior
Laravelを使用していない場合や、フォールバック動作をカスタマイズする必要がある場合は、各プロンプトクラスのfallbackUsing
静的メソッドにクロージャを渡すことができます:
use Laravel\Prompts\TextPrompt;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;
TextPrompt::fallbackUsing(function (TextPrompt $prompt) use ($input, $output) {
$question = (new Question($prompt->label, $prompt->default ?: null))
->setValidator(function ($answer) use ($prompt) {
if ($prompt->required && $answer === null) {
throw new \RuntimeException(
is_string($prompt->required) ? $prompt->required : 'Required.'
);
}
if ($prompt->validate) {
$error = ($prompt->validate)($answer ?? '');
if ($error) {
throw new \RuntimeException($error);
}
}
return $answer;
});
return (new SymfonyStyle($input, $output))
->askQuestion($question);
});
フォールバックは、各プロンプトクラスごとに個別に設定する必要があります。クロージャは、プロンプトクラスのインスタンスを受け取り、プロンプトに適した型を返す必要があります。