php-school / cli-menu
PHP 的命令行菜单助手
Requires
- php: >=7.1
- ext-mbstring: *
- ext-posix: *
- beberlei/assert: ^2.4 | ^3
- php-school/terminal: ^0.2.1
Requires (Dev)
- phpstan/phpstan: ^0.12
- phpunit/phpunit: ^8.0 | ^9.0
- squizlabs/php_codesniffer: ^3.2
README
内容
最低要求
- PHP 7.1
- Composer
- ext-posix
安装
composer require php-school/cli-menu
升级
请参阅升级文档,了解升级已安装的 cli-menu
版本所需的内容。
使用方法
快速设置
以下是一个非常基础的示例菜单,它将输出所选项目的文本,以帮助您开始。
<?php use PhpSchool\CliMenu\CliMenu; use PhpSchool\CliMenu\Builder\CliMenuBuilder; require_once(__DIR__ . '/../vendor/autoload.php'); $itemCallable = function (CliMenu $menu) { echo $menu->getSelectedItem()->getText(); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('First Item', $itemCallable) ->addItem('Second Item', $itemCallable) ->addItem('Third Item', $itemCallable) ->addLineBreak('-') ->setBorder(1, 2, 'yellow') ->setPadding(2, 4) ->setMarginAuto() ->build(); $menu->open();
示例
查看 示例目录 并运行它们,以查看可能的内容!运行示例的最佳方式是使用 git clone 仓库
git clone https://github.com/php-school/cli-menu.git cd cli-menu composer install --no-dev cd examples php basic.php
基本菜单
基本菜单自动居中
带有分隔的基本菜单
带有疯狂分隔的菜单
自定义样式
边框和 256 色彩
有用的分隔
显示项目额外
移除默认值
子菜单
分割项
禁用项目和子菜单
复选框项
单选按钮项
闪烁对话框
确认对话框
数字输入
文本输入
密码输入
使用 cli-menu 创建艺术
想看一些真正酷的东西吗?您可以使用 cli-menu 在您的终端上创建一个绘图画布。看看吧!
API
CliMenu
对象是通过 Builder 类构建的
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) /** * Customise **/ ->build();
一旦您有了菜单对象,您就可以像这样打开和关闭它
$menu->open(); $menu->close();
外观
菜单标题
您可以给您的菜单一个标题,并且可以自定义分隔符,即在标题下方显示的行。传递给 setTitleSeparator
的任何字符串都将重复,直到菜单的宽度。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setTitle('One Menu to rule them all!') ->setTitleSeparator('*-') ->build();
颜色
您可以将菜单的前景色和背景色更改为以下颜色中的任何一种
- 黑色
- 红色
- 绿色
- 黄色
- 蓝色
- 品红色
- 青色
- 白色
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setForegroundColour('green') ->setBackgroundColour('black') ->build();
如果您的终端支持 256 种颜色,则也可以使用其中任何一种,通过指定代码,如 230
。您可以在此处找到颜色和代码列表。如果您指定了代码,而终端不支持 256 种颜色,则将自动回退到合理的默认值,使用在 src/Util/ColourUtil.php 中可见的生成映射。您还可以手动指定回退颜色作为 setForegroundColour
和 `setBackgroundColour` 的第二个参数。
在此示例中,如果没有找到 256 色支持,它将自动回退到 绿色
和 蓝色
。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setForegroundColour('40') ->setBackgroundColour('92') ->build();
在这个例子中,如果没有找到256色支持,它将回退到黄色
和品红色
。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setForegroundColour('40', 'yellow') ->setBackgroundColour('92', 'magenta') ->build();
宽度
自定义菜单的宽度。设置一个大于终端大小的值将导致宽度与终端大小相同。宽度将包括填充和边框。因此,宽度为100,四周边框为5,四周填充为5,则内容宽度为80(5 + 5 + 80 + 5 + 5)。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setWidth(1000) //if terminal is only 400, width will also be 400 ->build();
如果您想使用终端的全宽度,可以获取终端对象并从那里获取/设置,如下所示
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = ($builder = new CliMenuBuilder) ->setWidth($builder->getTerminal()->getWidth()) ->build();
如果您想使用终端的全宽度并应用边距,请使用终端宽度,我们将自动进行计算(根据边距缩小宽度)。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = ($builder = new CliMenuBuilder) ->setWidth($builder->getTerminal()->getWidth()) ->setMargin(2) ->build();
填充
填充可以设置为一个值,用于所有边,或者可以单独为顶部/底部和左侧/右侧设置。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setPadding(10) //10 padding top/bottom/left/right ->build();
顶部/底部和左侧/右侧填充也可以设置不同的值
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setPaddingTopBottom(10) ->setPaddingLeftRight(5) ->build();
使用简写方法配置顶部/底部和左侧/右侧填充
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setPadding(10, 5) //top/bottom = 10, left/right = 5 ->build();
边距
边距可以自定义为一个值。它也可以自动设置,这样菜单就可以在终端中很好地居中。
自动居中菜单
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setWidth(200) ->setMarginAuto() ->build();
任意边距
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setWidth(200) ->setMargin(5) ->build();
边框
边框可以像CSS边框一样自定义。我们可以向任意一边添加任意数量的边框,包括左、右、上或下,并且我们可以为它应用颜色。
设置通用的2像素红色边框
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setWidth(200) ->setBorder(2, 'red') ->build();
分别配置每个边框
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setWidth(200) ->setBorderTopWidth(2) ->setBorderRightWidth(4) ->setBorderBottomWidth(2) ->setBorderLeftWidth(4) ->setBorderColour('42', 'red') //SpringGreen2 fallback to red ->build();
使用简写方法,像CSS一样分别配置每个边框
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setWidth(200) ->setBorder(3, 4, 'red') //top/bottom = 3, left/right = 4 ->setBorder(3, 4, 5, 'red') //top = 3, left/right = 4, bottom = 5 ->setBorder(3, 4, 5, 6, 'red') //top = 3, left = 4, bottom = 5, right = 6 ->build();
退出按钮文本
修改退出按钮的文本
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->setExitButtonText("Don't you want me baby?") ->build();
移除退出按钮
您可以将退出按钮完全删除
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->disableDefaultItems() ->build();
注意:这将同时禁用子菜单的返回按钮。
您可以使用以下方式手动添加退出和返回按钮
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\Action\ExitAction; use PhpSchool\CliMenu\Action\GoBackAction; $menu = (new CliMenuBuilder) ->disableDefaultItems() ->addSubMenu('Super Sub Menu', function (CliMenuBuilder $b) { $b->disableDefaultItems() ->setTitle('Behold the awesomeness') ->addItem('Return to parent menu', new GoBackAction); //add a go back button }) ->addItem('Leave this place now !', new ExitAction) //add an exit button ->build();
项目
您可以在菜单中添加几种不同类型的项目
- 可选项 - 这是您需要用于使某些内容可选择的类型(您可以按回车键并调用您的可调用函数)
- 复选框项 - 这是一个复选框类型的项,它跟踪其切换状态以显示不同的标记。
- 单选项 - 这是一个单选类型的项,它跟踪其切换状态以显示不同的标记。它将禁用其
CliMenu
级别内的所有其他单选按钮。 - 换行项 - 这用于分隔区域,它可以跨越多行,宽度与菜单相同。传递的任何字符串都将重复。
- 静态项 - 这将打印传递的任何文本,对于标题很有用。
- ASCII艺术项 - 允许使用ASCII艺术的特殊项。它负责填充和对齐。
- 子菜单项 - 允许一个项打开另一个菜单的特殊项。对于选项菜单很有用。
- 分隔项 - 适合同一行的多个项目的特殊项。
可选项
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $menu = (new CliMenuBuilder) ->addItem('The Item Text', function (CliMenu $menu) { echo 'I am alive!'; }) ->build();
您可以一次添加多个项,如下所示
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $callable = function (CliMenu $menu) { echo 'I am alive!'; }; $menu = (new CliMenuBuilder) ->addItems([ ['Item 1', $callable], ['Item 2', $callable], ['Item 3', $callable], ]) ->build();
注意:您可以添加任意数量的项,并且它们都可以有不同的操作。操作是第二个参数,必须是一个有效的PHP callable
。尝试使用Invokable
类来使您的操作易于测试。
复选框项
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $callable = function (CliMenu $menu) { echo $menu->getSelectedItem()->getText(); }; $menu = (new CliMenuBuilder) ->addCheckboxItem('Item 1', $callable) ->addCheckboxItem('Item 2', $callable) ->addCheckboxItem('Item 3', $callable) ->build();
您可以一次添加多个复选框项,如下所示
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $callable = function (CliMenu $menu) { echo 'I am alive!'; }; $menu = (new CliMenuBuilder) ->addCheckboxItems([ ['Item 1', $callable], ['Item 2', $callable], ['Item 3', $callable], ]) ->build();
在选择一个项时,它将被切换。注意,最初每个项都是未选中的。选择一个后,它将变为选中状态。
单选按钮项
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $callable = function (CliMenu $menu) { echo $menu->getSelectedItem()->getText(); }; $menu = (new CliMenuBuilder) ->addRadioItem('Item 1', $callable) ->addRadioItem('Item 2', $callable) ->addRadioItem('Item 3', $callable) ->build();
您可以一次添加多个单选项,如下所示
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $callable = function (CliMenu $menu) { echo 'I am alive!'; }; $menu = (new CliMenuBuilder) ->addRadioItems([ ['Item 1', $callable], ['Item 2', $callable], ['Item 3', $callable], ]) ->build();
在选择一个项时,它将被切换。注意,最初每个项都是未选中的。选择一个后,它将变为选中状态,并且同一级别的所有其他RadioItem
都将被取消选中。
换行项
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->addLineBreak('<3', 2) ->build();
上面的代码将在菜单中重复字符序列<3
跨越2行
静态项
静态项与换行符类似,但不会重复填充。它将按原样输出。如果文本长度超过菜单宽度,则将在下一行继续。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $menu = (new CliMenuBuilder) ->addStaticItem('AREA 1') //add some items here ->addStaticItem('AREA 2') //add some boring items here ->addStaticItem('AREA 51') //add some top secret items here ->build();
ASCII 码艺术项
以下操作将ASCII艺术放置在菜单的中心。使用这些常量来更改对齐方式
- AsciiArtItem::POSITION_CENTER
- AsciiArtItem::POSITION_LEFT
- AsciiArtItem::POSITION_RIGHT
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\MenuItem\AsciiArtItem; $art = <<<ART _ __ _ / |..| \ \/ || \/ |_''_| PHP SCHOOL LEARNING FOR ELEPHANTS ART; $menu = (new CliMenuBuilder) ->addAsciiArt($art, AsciiArtItem::POSITION_CENTER) ->build();
addAsciiArt
的第三个可选参数是备用文本。如果ASCII艺术对于终端来说太宽,则根本不会显示。然而,如果您传递一个字符串给第三个参数,如果ASCII艺术对于终端来说太宽,备用文本将代替显示。
子菜单项
子菜单功能强大!您可以在菜单中添加菜单,哇塞?您可以有主菜单和选项菜单。选项项将看起来像一个普通项,除非您点击它,您将进入另一个菜单,该菜单可以有不同的样式和颜色!
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $callable = function (CliMenu $menu) { echo "I'm just a boring selectable item"; }; $menu = (new CliMenuBuilder) ->addItem('Normal Item', $callable) ->addSubMenu('Super Sub Menu', function (CliMenuBuilder $b) { $b->setTitle('Behold the awesomeness') ->addItem(/** **/); }) ->build();
在此示例中,将创建一个单独的子菜单。进入子菜单后,您将能够返回主菜单或完全退出。将自动添加一个“返回”按钮。您可以使用CliMenuBuilder
实例的->setGoBackButtonText()
方法自定义此文本,该实例用于子菜单。
关于语法和构建过程有以下几点需要注意
addSubMenu
的第一个参数是要显示在菜单上的文本,用于选择进入子菜单。- 第二个参数是一个闭包,它将使用一个新实例的
CliMenuBuilder
调用,您可以使用它以完全相同的方式自定义子菜单,就像父菜单一样。 - 如果您没有修改子菜单的样式(例如,颜色),它将继承父菜单的样式!
如果您已经有一个配置好的菜单构建器,您只需将其传递给addSubMenuFromBuilder
即可完成。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; $subMenuBuilder = (new CliMenuBuilder) ->setTitle('Behold the awesomeness') ->addItem(/** **/); $menu = (new CliMenuBuilder) ->addSubMenuFromBuilder('Super Sub Menu', $subMenuBuilder) ->build();
注意:子菜单菜单项将是\PhpSchool\CliMenu\MenuItem\MenuMenuItem
的实例。如果您需要访问子菜单,可以通过$menuMenuItem->getSubMenu()
获取。
分割项
分隔项允许您在同一行上添加多个项目。菜单的全宽将均匀分配给所有项目。您可以使用左右箭头在这些项目之间移动。
您可以使用->setGutter()
(默认为2)设置项目之间分隔的空格数。
目前,在分隔项内部仅允许使用可选择的、复选框、单选按钮、静态和子菜单项。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\Builder\SplitItemBuilder; use PhpSchool\CliMenu\CliMenu; $itemCallable = function (CliMenu $menu) { echo $menu->getSelectedItem()->getText(); }; $menu = (new CliMenuBuilder) ->setWidth(150) ->addStaticItem('Below is a SplitItem') ->addSplitItem(function (SplitItemBuilder $b) use ($itemCallable) { $b->setGutter(5) ->addSubMenu('Sub Menu on a split item', function (CliMenuBuilder $b) { $b->setTitle('Behold the awesomeness') ->addItem('This is awesome', function() { print 'Yes!'; }); }) ->addItem('Item 2', $itemCallable) ->addStaticItem('Item 3 - Static'); }) ->build(); $menu->open();
关于语法和构建过程有以下几点需要注意
addSplitItem
的第一个参数是一个闭包,它将使用一个新实例的SplitItemBuilder
调用,您可以使用它向分隔项添加项目。- 您可以在
SplitItemBuilder
上调用addItem
、addCheckboxItem
、addRadioItem
、addSubMenu
和addStaticItem
。 SplitItemBuilder
具有流畅的接口,因此您可以链式调用方法。
禁用项目和子菜单
在此示例中,我们将禁用某些项目和子菜单,但仍然在菜单中显示它们。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $itemCallable = function (CliMenu $menu) { echo $menu->getSelectedItem()->getText(); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu Disabled Items') ->addItem('First Item', $itemCallable) ->addItem('Second Item', $itemCallable, false, true) ->addItem('Third Item', $itemCallable, false, true) ->addSubMenu('Submenu', function (CliMenuBuilder $b) use ($itemCallable) { $b->setTitle('Basic CLI Menu Disabled Items > Submenu') ->addItem('You can go in here!', $itemCallable); }) ->addSubMenu('Disabled Submenu', function (CliMenuBuilder $b) use ($itemCallable) { $b->setTitle('Basic CLI Menu Disabled Items > Disabled Submenu') ->addItem('Nope can\'t see this!', $itemCallable) ->disableMenu(); }) ->addLineBreak('-') ->build();
->addItem
调用的第三个参数是禁用项目的因素,而->disableMenu
调用禁用相关菜单。
结果是具有褪色行的完整菜单,以表示它们已被禁用。当用户导航菜单时,这些项将被跳过,转到下一个可用的可选项。
项目标记
目前,当前活动项旁边的标记可以修改,支持UTF-8字符。未选择项的标记也可以修改。如果您想禁用它,只需将其设置为空字符串即可。项目标记仅在可选择项上显示,这些项是:\PhpSchool\CliMenu\MenuItem\SelectableItem
和\PhpSchool\CliMenu\MenuItem\MenuMenuItem
。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\Style\SelectableStyle; $menu = (new CliMenuBuilder) ->modifySelectableStyle(function (SelectableStyle $style) { $style->setUnselectedMarker('❅ ') ->setSelectedMarker('✏ ') // disable unselected marker ->setUnselectedMarker('') ; }) ->build();
您还可以更改\PhpSchool\CliMenu\MenuItem\CheckboxItem
的标记
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\Style\CheckboxStyle; $menu = (new CliMenuBuilder) ->modifyCheckboxStyle(function (CheckboxStyle $style) { $style->setUncheckedMarker('[○] ') ->setCheckedMarker('[●] '); }) ->addCheckboxItem('Orange juice', function () {}) ->addCheckboxItem('Bread', function () {}) ->build();
和为\PhpSchool\CliMenu\MenuItem\RadioItem
。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\Style\RadioStyle; $menu = (new CliMenuBuilder) ->modifyRadioStyle(function (RadioStyle $style) { $style->setUncheckedMarker('[ ] ') ->setCheckedMarker('[✔] '); }) ->addRadioItem('Go shopping', function () {}) ->addRadioItem('Go camping', function () {}) ->build();
项目额外
您可以选择在项目右侧显示任意文本。您可以自定义此文本,并指定要在哪些项目上显示。我们使用它来显示 [完成]
在完成的练习上,菜单列出了研讨会应用的练习。
项目额外功能目前仅限于可选择的项(包括菜单、复选框和单选按钮)
addItem
的第三个参数是一个布尔值,表示是否显示项目额外内容。默认为 false。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; use PhpSchool\CliMenu\Style\SelectableStyle; $menu = (new CliMenuBuilder) ->modifySelectableStyle(function (SelectableStyle $style) { $style->setItemExtra('✔'); }) ->addItem('Exercise 1', function (CliMenu $menu) { echo 'I am complete!'; }, true) ->build();
如果没有项目设置显示额外内容为 true,则项目额外内容将不会显示。如果您在回调或运行时切换项目以显示其项目额外内容,则渲染将不正确。
为了修复此问题,您需要显式告诉菜单显示项目额外内容。您可以在构建菜单时这样做
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $menu = (new CliMenuBuilder) ->setItemExtra('✔') ->addItem('Exercise 1', function (CliMenu $menu) { $selectedItem = $menu->getSelectedItem(); if ($selectedItem->showsItemExtra()) { $selectedItem->hideItemExtra(); } else { $selectedItem->showItemExtra(); } }) ->displayExtra() ->build();
菜单方法
以下文档适用于直接在 \PhpSchool\CliMenu\CliMenu
实例上的方法。通常,您将在菜单打开时在您的操作回调中调用这些方法。
重绘菜单
您可以在执行操作时修改菜单及其样式,然后您可以重新绘制它!在这个例子中,我们将切换背景颜色。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $itemCallable = function (CliMenu $menu) { $menu->getStyle()->setBg($menu->getStyle()->getBg() === 'red' ? 'blue' : 'red'); $menu->redraw(); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('First Item', $itemCallable) ->addItem('Second Item', $itemCallable) ->addItem('Third Item', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
如果您剧烈更改菜单,例如使宽度更小,当它重新绘制时,您可能会看到上一个绘制的碎片,因为 redraw
只在终端顶部绘制。如果发生这种情况,您可以将 true
传递给 redraw
,它将首先清除终端然后再重新绘制。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $itemCallable = function (CliMenu $menu) { $menu->getStyle()->setWidth($menu->getStyle()->getWidth() === 100 ? 80 : 100); $menu->redraw(true); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('First Item', $itemCallable) ->addItem('Second Item', $itemCallable) ->addItem('Third Item', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
获取、移除和添加项目
您还可以在操作中与菜单项交互。您可以添加、删除和替换项。如果您这样做,您可能还想重新绘制菜单,以便渲染新列表。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; use PhpSchool\CliMenu\MenuItem\LineBreakItem; $itemCallable = function (CliMenu $menu) { foreach ($menu->getItems() as $item) { $menu->removeItem($item); } //add single item $menu->addItem(new LineBreakItem('-')); //add multiple items $menu->addItems([new LineBreakItem('-'), new LineBreakItem('*')]); //replace all items $menu->setItems([new LineBreakItem('+'), new LineBreakItem('-')]); $menu->redraw(); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('First Item', $itemCallable) ->addItem('Second Item', $itemCallable) ->addItem('Third Item', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
自定义控制映射
此功能允许将自定义按键映射到可调用的函数。例如,我们可以将按键“x”设置为关闭菜单
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $exit = function(CliMenu $menu) { $menu->close(); }; $menu = (new CliMenuBuilder) ->addItem('Item 1', function(CliMenu $menu) {}) ->build(); $menu->addCustomControlMapping("x", $exit); $menu->open();
另一个示例是将快捷键映射到项目列表
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $myCallback = function(CliMenu $menu) { echo "Client 1\nClient 2\nClient 3\n"; }; $menu = (new CliMenuBuilder) ->addItem('List of [C]lients', $myCallback) ->build(); // Now, pressing Uppercase C (it's case sensitive) will call $myCallback $menu->addCustomControlMapping('C', $myCallback); $menu->open();
项目键盘快捷键
如果您启用自动快捷键,则 CliMenuBuilder
将解析项目文本并检查快捷键。方括号内的任何单个字符都将被视为快捷键。当菜单打开时按下该字符将触发该项目的可调用函数。
此功能也适用于分割项目和子菜单。可以在子菜单中使用相同的字符,并且调用的可调用函数将取决于当前打开的菜单。
注意:所有快捷键都是小写。
要启用此自动键盘快捷键映射,只需调用 ->enableAutoShortcuts()
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $myCallback = function(CliMenu $menu) { echo "Client 1\nClient 2\nClient 3\n"; }; $menu = (new CliMenuBuilder) ->enableAutoShortcuts() ->addItem('List of [C]lients', $myCallback) ->build(); $menu->open(); //Pressing c will execute $myCallback.
您可以通过传递自己的正则表达式到 enableAutoShortcuts
来自定义快捷键匹配。请小心只匹配第一个捕获组中的一个字符,否则会抛出异常。
对话框
闪烁
在菜单上方显示一条单行消息。它有一个单独的样式对象,默认情况下颜色与菜单不同。您可以修改它以适合您自己的样式。对话框可以通过任何按键来取消。以下示例中,我们将闪屏的背景颜色改为绿色。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; require_once(__DIR__ . '/../vendor/autoload.php'); $itemCallable = function (CliMenu $menu) { $flash = $menu->flash("PHP School FTW!!"); $flash->getStyle()->setBg('green'); $flash->display(); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('First Item', $itemCallable) ->addItem('Second Item', $itemCallable) ->addItem('Third Item', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
确认
提示与闪屏非常相似,除了显示一个必须选择的按钮来取消它们。按钮文本可以自定义。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $itemCallable = function (CliMenu $menu) { $menu->confirm('PHP School FTW!') ->display('OK!'); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('First Item', $itemCallable) ->addItem('Second Item', $itemCallable) ->addItem('Third Item', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
输入
输入 - 在 cli-menu
的 3.0 版本中添加 - 允许提示用户输入并验证它。支持以下类型:文本、数字和密码。可以在任何项目回调中执行输入。它们有独立的样式对象,默认情况下颜色与菜单不同。您可以修改它们以适合您自己的样式。
每个输入是通过调用一个 ask*
方法创建的,它将返回您请求的输入的实例。要执行提示并等待输入,您必须在输入上调用 ask()
。当接收到并验证输入后,ask()
将返回一个 InputResult
的实例。 InputResult
提供了 fetch
方法来获取原始输入。
文本输入
文本输入将提示输入一个字符串,当按下回车键时,将验证该字符串是否为空。除了样式外,您还可以修改提示文本(默认为'输入文本:')、占位文本(默认为空)以及验证失败文本(默认为'无效,请重试')。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $itemCallable = function (CliMenu $menu) { $result = $menu->askText() ->setPromptText('Enter your name') ->setPlaceholderText('Jane Doe') ->setValidationFailedText('Please enter your name') ->ask(); var_dump($result->fetch()); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('Enter text', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
数字输入
数字输入将提示输入一个整数(有符号或无符号)值,当按下回车键时,将验证输入是否实际上是一个数字(/^-?\d+$/
)。除了样式外,您还可以修改提示文本(默认为'输入一个数字:')、占位文本(默认为空)以及验证失败文本(默认为'不是有效的数字,请重试')。
当输入数字时,您可以使用上下键来增加和减少数字。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $itemCallable = function (CliMenu $menu) { $result = $menu->askNumber() ->setPromptText('Enter your age') ->setPlaceholderText(10) ->setValidationFailedText('Invalid age, try again') ->ask(); var_dump($result->fetch()); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('Enter number', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
密码输入
密码输入将提示输入文本值,当按下回车键时,将验证输入是否为16个字符或更长。除了样式外,您还可以修改提示文本(默认为'输入密码:')、占位文本(默认为空)以及验证失败文本(默认为'无效密码,请重试')。您还可以设置一个自定义的密码验证器作为PHP可调用。当输入密码时,它们将回显为星号。
使用默认验证请求密码
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $itemCallable = function (CliMenu $menu) { $result = $menu->askPassword() ->setPromptText('Please enter your password') ->setValidationFailedText('Invalid password, try again') ->setPlaceholderText('') ->ask(); var_dump($result->fetch()); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('Enter password', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
验证器可以是任何PHP可调用。可调用将被传递输入值,必须返回一个布尔值,false表示验证失败,true表示验证成功。如果验证失败,则将显示验证失败文本。
还有可能动态自定义验证失败消息,但仅当使用Closure
作为验证器时。闭包将被绑定到Password
输入类,这将允许您在闭包内部调用setValidationFailedText
。
使用自定义验证请求密码。这里我们验证密码不等于password
且密码长度超过20个字符。
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $itemCallable = function (CliMenu $menu) { $result = $menu->askPassword() ->setPromptText('Please enter your password') ->setValidationFailedText('Invalid password, try again') ->setPlaceholderText('') ->setValidator(function ($password) { return $password !== 'password' && strlen($password) > 20; }) ->ask(); var_dump($result->fetch()); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('Enter password', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
使用自定义验证请求密码并动态设置验证失败消息
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; $itemCallable = function (CliMenu $menu) { $result = $menu->askPassword() ->setPromptText('Please enter your password') ->setValidationFailedText('Invalid password, try again') ->setPlaceholderText('') ->setValidator(function ($password) { if ($password === 'password') { $this->setValidationFailedText('Password is too weak'); return false; } else if (strlen($password) <= 20) { $this->setValidationFailedText('Password is not long enough'); return false; } return true; }) ->ask(); var_dump($result->fetch()); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('Enter password', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
自定义输入
如果您需要一个未在捆绑选择中涵盖的新类型输入,您可以通过实现\PhpSchool\CliMenu\Input\Input
来创建自己的输入 - 查看现有实现以了解它们是如何构建的。如果您只需要一些自定义验证,则扩展\PhpSchool\CliMenu\Input\Text
类并重写validate
方法。然后您可以在菜单项操作中使用它,如下所示
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; use PhpSchool\CliMenu\MenuStyle; use PhpSchool\CliMenu\Input\Text; use PhpSchool\CliMenu\Input\InputIO; $itemCallable = function (CliMenu $menu) { $style = (new MenuStyle()) ->setBg('yellow') ->setFg('black'); $input = new class (new InputIO($menu, $menu->getTerminal()), $style) extends Text { public function validate(string $value) : bool { //some validation return true; } }; $result = $input->ask(); var_dump($result->fetch()); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('Enter password', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
对话框和输入样式
所有对话框和输入都公开了一个getStyle()
方法,您可以使用它来自定义它们的外观。但是,如果您想为所有对话框和输入创建一个一致的风格,而无需为每个配置它,则可以构建一个MenuStyle
对象并将其传递给对话框和输入方法,如下所示
<?php use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; use PhpSchool\CliMenu\MenuStyle; $popupStyle = (new MenuStyle) ->setBg('green') ->setFg('magenta'); $itemCallable = function (CliMenu $menu) use ($popupStyle) { $menu->flash("PHP School FTW!!", $popupStyle)->display(); $menu->confirm('PHP School FTW!', $popupStyle)->display('OK!'); $menu->askNumber($popupStyle)->ask(); }; $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('First Item', $itemCallable) ->addItem('Second Item', $itemCallable) ->addItem('Third Item', $itemCallable) ->addLineBreak('-') ->build(); $menu->open();
一旦开始,您可能会得到一些看起来像这样的事物...
您可以在以下代码中查看构建代码,以更清楚地了解如何执行高级配置: PHP School