stefaminator/php-cli-cmd

PHP CLI CMD 库

dev-master 2020-06-16 21:57 UTC

This package is auto-updated.

Last update: 2024-09-17 07:24:53 UTC


README

PHP CLI CMD 库。帮助您快速轻松地创建结构良好的 PHP CLI 应用程序。

此库支持设置选项和参数,子命令,并提供集成命令帮助。使用颜色或进度条助手来可视化重要输出。

Packagist PHP Version Support Latest Stable Version Build Status Scrutinizer Code Quality Code Coverage Packagist License

目录

入门

最简单的安装方法是参考 packagist 上的源。

composer require stefaminator/php-cli-cmd

构建您的第一个应用

让我们从创建一个名为 cli-app-helloworld.php 的新 PHP 文件开始,并引入 Composer 的自动加载器。

通过扩展 Stefaminator\Cli\App 创建一个自定义类,并实现必需的 setup 方法,该方法必须返回 Stefaminator\Cli\Cmd 实例。在下面的示例中,我们创建了一个根 Cmd 并将执行该根命令的行放入 run 方法中。

最后,调用应用的 run() 方法并感受魔法。

(您可以在以下位置找到此示例: examples/cli-app-helloworld.php)

<?php

/** Please do not forget to require composers autoloader here */

use Stefaminator\Cli\App;
use Stefaminator\Cli\Cmd;

(new class extends App {

    public function setup(): Cmd {    
        return (new class extends Cmd {

            public function init(): void {
            }

            public function run(): void {
                echo "Hello world";
                echo "\n";
            }
        });    
    }
})->run();

如果您从命令行执行该脚本,您将看到

# php cli-app-helloworld.php
Hello World

哇,为了这样的简单输出,代码太多了,您可能会想:“我可以用更少的代码做到同样的事情。” - 是的,我相信你可以!

选项

好,让我们从一个简单的例子开始,给我们的应用添加一些选项! 让我们添加一个帮助标志选项(--help-h),以输出内置命令帮助,并添加一个名称选项,以便能够向给定的名称说你好(例如,--name=Stefaminator)。

<?php

use Stefaminator\Cli\App;
use Stefaminator\Cli\Cmd;
use Stefaminator\Cli\Color;

(new class extends App {

    public function setup(): Cmd {
        return (new class extends Cmd {

            public function init(): void {

                $this
                    ->addOption('h|help', [
                        'description' => 'Displays the command help.'
                    ])
                    ->addOption('name:', [
                        'description' => 'Name option. This option requires a value.',
                        'isa' => 'string',
                        'default' => 'World'
                    ]);
            }

            public function run(): void {

                if ($this->hasProvidedOption('help')) {
                    $this->runHelp();
                    return;
                }

                $name = $this->getProvidedOption('name');

                self::eol();
                self::echo(sprintf('Hello %s', $name), Color::FOREGROUND_COLOR_YELLOW);
                self::eol();
                self::eol();
            }

            public function help(): void {

                echo '' .
                    ' This is the custom help for ' . Color::green('cli-app-options') . ' command. ' . self::EOL .
                    ' Please use the --name option to pass your name to this command and you will be greeted personally. ' . self::EOL .
                    ' ' . self::EOL .
                    ' ' . Color::green('php cli-app-options.php --name="great Stefaminator"') . self::EOL;
            }
        });
    }

})->run();

添加选项

应根据以下方案在 Cmd::init() 方法中添加选项

$this->addOption($specString, $configArray);

addOption() 方法是可链的,因此您可以像这样添加选项

$this
    ->addOption($specString1, $configArray1)
    ->addOption($specString2, $configArray2);

请注意,基于 https://github.com/c9s/GetOptionKit 的选项解析。选项规范和基于该优秀库的选项值验证。因此,如果您对这些功能有任何问题或问题,请首先查看他们的文档。

选项规范

使用 $specStringaddOption 方法的第一个参数)来定义选项的长名和/或短名,并使用限定符 :+? 来确定它是否为标志、必需的、多值或可选值。

h|help         flag option with single char option name (-h) and long option name (--help).
n|name:        option require a value (-n=Stefaminator or --name="great Stefaminator").
i|input+       option with multiple values (-i=file1 -i=file2).
o|output?      option with optional value (--output or -o=output.txt)
v              single character only option (-v)
dir            long option name (--dir)

选项配置

通过 $configArrayaddOption 方法的第二个参数)指定更多的选项属性。以下是一个可能的键列表

description    string    The description string is used in builtin command help
isa            string    The option value type to validate the input (see: Option value validation)
regex          string    A regex to validate the input value against (in case of isa=regex)
default        mixed     The options default value
incremental    bool      Typically used for verbose mode (with -vvv the value will be 3)

选项值验证

选项配置中 isa 键的可能值。

string         To ensure the given value is a string.
number         To ensure the given value is a number.
boolean        To ensure the given value is a boolean (true, false, 0, 1).
file           To ensure the given value is an existing file.
date           To ensure the given value is a valid date (Y-m-d).
url            To ensure the given value is a valid url.
email          To ensure the given value is a valid email.
ip             To ensure the given value is a valid ip(v4/v6).
ipv4           To ensure the given value is a valid ipv4.
ipv6           To ensure the given value is a valid ipv6.
regex          Validate the value against a custom regex (specified in regex key).

在运行时获取提供的选项

可以使用以下调用之一在 Cmd::run() 方法中捕获提供的选项的值

/**
 * Returns true if a value for the given option name is present.
 * @param string $key Long option name if present, otherwise short option char
 * @return bool
 */
$this->hasProvidedOption($key);

/**
 * Returns the value for the given option name.
 * @param string $key Long option name if present, otherwise short option char
 * @return mixed
 */
$value = $this->getProvidedOption($key);

/**
 * Returns an array of key value pairs with all present option values.
 * @return array
 */
$all = $this->getAllProvidedOptions();
    
/**
 * Holds the original OptionResult of c9s/GetOptionKit library
 * @var OptionResult|null
 */
$this->optionResult;

参数

参数通常始终接受,并且不通过配置进行验证。任何端点都必须决定是否处理参数,并且必须自行验证它们。但是,如果您接受参数,您可能希望使它们可见并在帮助输出中解释它们。因此,并且仅因此,您可以像下面这样声明它们。

添加参数

应根据以下方案在 Cmd::init() 方法中添加参数

$this->addArgument($specString, $configArray);

addArgument() 方法是链式的,因此您可以将其与 addOption() 结合使用,并像这样添加参数:

$this
    ->addOption($specString1, $configArray1)
    ->addOption($specString2, $configArray2)
    ->addArgument($specString3, $configArray3);

参数规范

使用 $specStringaddArgument 方法的第一个参数)为参数提供一个有意义的名称。

参数配置

通过 $configArrayaddArgument 方法的第二个参数)指定更多的参数属性。以下是一个可能的键列表:

description    string    The description string is used in builtin command help
multiple       bool      The multiple flag is used in builtin command help to mark it as multiple (works only for the last declared arg)

在运行时获取提供的参数

可以使用以下调用之一在 Cmd::run() 方法中捕获提供的选项的值

/**
 * Returns an indexed array of provided arguments.
 * @return array
 */
$args = $this->arguments();

如上所述,无论参数是否通过 addArgument() 声明,都没有关系。与选项不同,选项只有在验证成功后才会存在,而参数只要被输入就会存在。

子命令

以下示例(cli-app-subcommands.php)展示了一个输出根命令帮助的根命令,一个输出显示命令帮助的子命令 show,以及为 show 命令提供的两个子命令(hellophpversion)。

php cli-app-subcommands.php                      // Outputs command help for root command
php cli-app-subcommands.php show                 // Outputs command help for the "show" command
php cli-app-subcommands.php show hello           // Outputs "Hello World"
php cli-app-subcommands.php show hello -h        // Outputs command help for the "show hello" command
php cli-app-subcommands.php show hello --name=me // Outputs "Hello me"
php cli-app-subcommands.php show phpversion      // Outputs the current php version of your cli

好的,以下是代码

<?php

use Stefaminator\Cli\App;
use Stefaminator\Cli\Cmd;
use Stefaminator\Cli\Color;

(new class extends App {

    public function setup(): Cmd {
        return (
        new class extends Cmd {

            public function init(): void {
            }

            public function run(): void {
                $this->runHelp();
            }
        })
            ->addChild((new class('show') extends Cmd {

                public function init(): void {

                    $this
                        ->setDescription(
                            'This command is used to show something. Take a look at the subcommands.'
                        );

                }

                public function run(): void {
                    $this->runHelp();
                }

            })
                ->addChild((new class('hello') extends Cmd {

                    public function init(): void {

                        $this
                            ->setDescription(
                                'Displays hello world.'
                            )
                            ->addOption('h|help', [
                                'description' => 'Displays the command help.'
                            ])
                            ->addOption('name:', [
                                'description' => 'Name option. This option requires a value.',
                                'isa' => 'string',
                                'default' => 'World'
                            ]);
                    }

                    public function run(): void {

                        if ($this->hasProvidedOption('help')) {
                            $this->runHelp();
                            return;
                        }

                        $name = $this->getProvidedOption('name');

                        self::eol();
                        self::echo(sprintf('Hello %s!', $name), Color::FOREGROUND_COLOR_CYAN);
                        self::eol();
                        self::eol();
                    }
                }))
                ->addChild((new class('phpversion') extends Cmd {

                    public function init(): void {

                        $this
                            ->addOption('h|help', [
                                'description' => 'Displays the command help.'
                            ])
                            ->setDescription(
                                'Displays the current php version of your cli.'
                            );
                    }

                    public function run(): void {

                        if ($this->hasProvidedOption('help')) {
                            $this->runHelp();
                            return;
                        }
                        
                        self::eol();
                        self::echo('  Your PHP version is:', Color::FOREGROUND_COLOR_YELLOW);
                        self::eol();
                        self::echo('  ' . PHP_VERSION);
                        self::eol();
                        self::eol();
                    }
                }))
            );
    }

})->run();

如您已经注意到,通过调用 Cmd::addChild() 方法配置了一个子命令。该方法接受另一个 Cmd 对象,该对象也可能被分配了一个或多个子命令。