承接 aura/cli 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

aura/cli

Composer 安装命令:

composer require aura/cli

包简介

Provides the equivalent of request (Context) and response (Stdio) classes for a command line environment, including Getopt support.

README 文档

README

Provides the equivalent of request ( Context ) and response ( Stdio ) objects for the command line interface, including Getopt support, and an independent Help object for describing commands.

Foreword

Installation

This library requires PHP 7.2 or later; we recommend using the latest available version of PHP as a matter of principle.

It has no userland dependencies.

It is installable and autoloadable via Composer as aura/cli.

Alternatively, download a release or clone this repository, then require or include its autoload.php file.

Quality

Continuous Integration

To run the unit tests at the command line, issue composer install and then composer test at the package root. This requires Composer to be available as composer.

This library attempts to comply with PSR-1, PSR-2, and PSR-4. If you notice compliance oversights, please send a patch via pull request.

Community

To ask questions, provide feedback, or otherwise communicate with the Aura community, please join our Google Group, follow @auraphp on Twitter, or chat with us on #auraphp on Freenode.

Getting Started

Context Discovery

The Context object provides information about the command line environment, including any option flags passed via the command line. (This is the command line equivalent of a web request object.)

Instantiate a Context object using the CliFactory; pass it a copy of $GLOBALS.

<?php
use Aura\Cli\CliFactory;

$cli_factory = new CliFactory;
$context = $cli_factory->newContext($GLOBALS);
?>

You can access the $_ENV, $_SERVER, and $argv values with the $env, $server, and $argv property objects, respectively. (Note that these properties are copies of those superglobals as they were at the time of Context instantiation.) You can pass an alternative default value if the related key is missing.

<?php
// get copies of superglobals
$env    = $context->env->get();
$server = $context->server->get();
$argv   = $context->argv->get();

// equivalent to:
// $value = isset($_ENV['key']) ? $_ENV['key'] : null;
$value = $context->env->get('key');

// equivalent to:
// $value = isset($_ENV['key']) ? $_ENV['key'] : 'other_value';
$value = $context->env->get('key', 'other_value');
?>

Getopt Support

The Context object provides support for retrieving command-line options and params, along with positional arguments.

To retrieve options and arguments parsed from the command-line $argv values, use the getopt() method on the Context object. This will return a GetoptValues object for you to use as as you wish.

Defining Options and Params

To tell getopt() how to recognize command line options, pass an array of option definitions. The definitions array format is similar to, but not exactly the same as, the one used by the getopt() function in PHP. Instead of defining short flags in a string and long options in a separate array, they are both defined as elements in a single array. Adding a * after the option name indicates it can be passed multiple times; its values will be stored in an array.

<?php
$options = [
    'a',        // short flag -a, parameter is not allowed
    'b:',       // short flag -b, parameter is required
    'c::',      // short flag -c, parameter is optional
    'foo',      // long option --foo, parameter is not allowed
    'bar:',     // long option --bar, parameter is required
    'baz::',    // long option --baz, parameter is optional
    'g*::',     // short flag -g, parameter is optional, multi-pass
];

$getopt = $context->getopt($options);
?>

N.b.: When we say "required" here, it means "the option, when present, must have a parameter." It does not mean "the option must be present." These are options, after all. If a particular value must be passed, consider using positional arguments instead.

Use the get() method on the returned GetoptValues object to retrieve the option values. You can provide an alternative default value for when the option is missing.

<?php
$a   = $getopt->get('-a', false); // true if -a was passed, false if not
$b   = $getopt->get('-b');
$c   = $getopt->get('-c', 'default value');
$foo = $getopt->get('--foo', 0); // true if --foo was passed, false if not
$bar = $getopt->get('--bar');
$baz = $getopt->get('--baz', 'default value');
$g   = $getopt->get('-g', []);
?>

If you want to alias one option name to another, comma-separate the two names. The values will be stored under both names;

<?php
// alias -f to --foo
$options = [
    'foo,f:',  // long option --foo or short flag -f, parameter required
];

$getopt = $context->getopt($options);

$foo = $getopt->get('--foo'); // both -f and --foo have the same values
$f   = $getopt->get('-f'); // both -f and --foo have the same values
?>

If you want to allow an option to be passed multiple times, add a '*' to the end of the option name.

<?php
$options = [
    'f*',
    'foo*:'
];

$getopt = $context->getopt($options);

// if the script was invoked with:
// php script.php --foo=foo --foo=bar --foo=baz -f -f -f
$foo = $getopt->get('--foo'); // ['foo', 'bar', 'baz']
$f   = $getopt->get('-f'); // [true, true, true]
?>

If the user passes options that do not conform to the definitions, the GetoptValues object retains various errors related to the parsing failures. In these cases, hasErrors() will return true, and you can then review the errors. (The errors are actually Aura\Cli\Exception objects, but they don't get thrown as they occur; this is so that you can deal with or ignore the different kinds of errors as you like.)

<?php
$getopt = $context->getopt($options);
if ($getopt->hasErrors()) {
    $errors = $getopt->getErrors();
    foreach ($errors as $error) {
        // print error messages to stderr using a Stdio object
        $stdio->errln($error->getMessage());
    }
};
?>

Positional Arguments

To get the positional arguments passed to the command line, use the get() method and the argument position number:

<?php
$getopt = $context->getopt($options);

// if the script was invoked with:
// php script.php arg1 arg2 arg3 arg4

$val0 = $getopt->get(0); // script.php
$val1 = $getopt->get(1); // arg1
$val2 = $getopt->get(2); // arg2
$val3 = $getopt->get(3); // arg3
$val4 = $getopt->get(4); // arg4
?>

Defined options will be removed from the arguments automatically.

<?php
$options = [
    'a',
    'foo:',
];

$getopt = $context->getopt($options);

// if the script was invoked with:
// php script.php arg1 --foo=bar -a arg2
$arg0 = $getopt->get(0); // script.php
$arg1 = $getopt->get(1); // arg1
$arg2 = $getopt->get(2); // arg2
$foo  = $getopt->get('--foo'); // bar
$a    = $getopt->get('-a'); // 1
?>

N.b.: If a short flag has an optional parameter, the argument immediately after it will be treated as the option value, not as an argument.

Standard Input/Output Streams

The Stdio object allows you to work with standard input/output streams. (This is the command line equivalent of a web response object.)

Instantiate a Stdio object using the CliFactory.

<?php
use Aura\Cli\CliFactory;

$cli_factory = new CliFactory;
$stdio = $cli_factory->newStdio();
?>

It defaults to using php://stdin, php://stdout, and php://stderr, but you can pass whatever stream names you like as parameters to the newStdio() method.

The Stdio object methods are ...

  • getStdin(), getStdout(), and getStderr() to return the respective Handle objects;

  • outln() and out() to print to stdout, with or without a line ending;

  • errln() and err() to print to stderr, with or without a line ending;

  • inln() and in() to read from stdin until the user hits enter; inln() leaves the trailing line ending in place, whereas in() strips it.

You can use special formatting markup in the output and error strings to set text color, text weight, background color, and other display characteristics. See the formatter cheat sheet below.

<?php
// print to stdout
$stdio->outln('This is normal text.');

// print to stderr
$stdio->errln('<<red>>This is an error in red.');
$stdio->errln('Output will stay red until a formatting change.<<reset>>');
?>

Exit Codes

This library comes with a Status class that defines constants for exit status codes. You should use these whenever possible. For example, if a command is used with the wrong number of arguments or improper option flags, exit() with Status::USAGE. The exit status codes are the same as those found in sysexits.h.

Writing Commands

The Aura.Cli library does not come with an abstract or base command class to extend from, but writing commands for yourself is straightforward. The following is a standalone command script, but similar logic can be used in a class. Save it in a file named hello and invoke it with php hello [-v,--verbose] [name].

<?php
use Aura\Cli\CliFactory;
use Aura\Cli\Status;

require '/path/to/Aura.Cli/autoload.php';

// get the context and stdio objects
$cli_factory = new CliFactory;
$context = $cli_factory->newContext($GLOBALS);
$stdio = $cli_factory->newStdio();

// define options and named arguments through getopt
$options = ['verbose,v'];
$getopt = $context->getopt($options);

// do we have a name to say hello to?
$name = $getopt->get(1);
if (! $name) {
    // print an error
    $stdio->errln("Please give a name to say hello to.");
    exit(Status::USAGE);
}

// say hello
if ($getopt->get('--verbose')) {
    // verbose output
    $stdio->outln("Hello {$name}, it's nice to see you!");
} else {
    // plain output
    $stdio->outln("Hello {$name}!");
}

// done!
exit(Status::SUCCESS);
?>

Writing Command Help

Sometimes it will be useful to provide help output for your commands. With Aura.Cli, the Help object is separate from any command you may write. It may be manipulated externally or extended.

For example, extend the Help object and override the init() method.

<?php
use Aura\Cli\Help;

class MyCommandHelp extends Help
{
    protected function init()
    {
        $this->setSummary('A single-line summary.');
        $this->setUsage('<arg1> [<arg2>]');
        $this->setOptions([
            'f,foo' => "The -f/--foo option description.",
            'bar::' => "The --bar option description.",
        ]);
        $this->setDescr("A multi-line description of the command.");
    }
}
?>

Then instantiate the new class and pass its getHelp() output through Stdio:

<?php
use Aura\Cli\CliFactory;
use Aura\Cli\Context\OptionFactory;

$cli_factory = new CliFactory;
$stdio = $cli_factory->newStdio();

$help = new MyCommandHelp(new OptionFactory);
$stdio->outln($help->getHelp('my-command'));
?>
  • We keep the command name itself outside of the help class, because the command name may be mapped differently in different projects.

  • We pass a GetoptParser to the Help object so it can parse the option definitions.

  • We can get the option definitions out of the Help object using getOptions(); this allows us to pass a Help object into a hypothetical command object and reuse the definitions.

The output will look something like this:

SUMMARY
    my-command -- A single-line summary.

USAGE
    my-command <arg1> [<arg2>]

DESCRIPTION
    A multi-line description of the command.

OPTIONS
    -f
    --foo
        The -f/--foo option description.

    --bar[=<value>]
        The --bar option description.

As a side note, the array of options passed to setOptions() may contain argument descriptions as well. These are in the format #argname (to indicate a required argument) and #argname? (to indicate an optional argument). They may additionally be used as keys, with corresponding description values. Their presence in a Getopt definition array is ignored, but the Help object will read them and generate output for them automatically.

For example, the following code (notice the lack of a setUsage() call)...

<?php
use Aura\Cli\CliFactory;
use Aura\Cli\Context\OptionFactory;
use Aura\Cli\Help;

$cli_factory = new CliFactory;
$stdio = $cli_factory->newStdio();

$help = new Help(new OptionFactory);
$this->setSummary('A single-line summary.');
$help->setOptions([
    'f,foo' => "The -f/--foo option description.",
    'bar::' => "The --bar option description.",
    '#arg1' => "The description for argument 1.",
    '#arg2?' => "The description for argument 2.",
]);
$this->setDescr("A multi-line description of the command.");

$stdio->outln($help->getHelp('my-command'));
?>

... will generate the following output:

SUMMARY
    my-command -- A single-line summary.

USAGE
    my-command <arg1> [<arg2>]

DESCRIPTION
    A multi-line description of the command.

ARGUMENTS
    <foo>
        The description for argument 1.

    <bar>
        The description for argument 2.

OPTIONS
    -f
    --foo
        The -f/--foo option description.

    --bar[=<value>]
        The --bar option description.

Formatter Cheat Sheet

On POSIX terminals, <<markup>> strings will change the display characteristics. Note that these are not HTML tags; they will be converted into terminal control codes, and do not get "closed". You can place as many space-separated markup codes between the double angle-brackets as you like.

reset       reset display to defaults

black       black text
red         red text
green       green text
yellow      yellow text
blue        blue text
magenta     magenta (purple) text
cyan        cyan (light blue) text
white       white text

blackbg     black background
redbg       red background
greenbg     green background
yellowbg    yellow background
bluebg      blue background
magentabg   magenta (purple) background
cyanbg      cyan (light blue) background
whitebg     white background

bold        bold in the current text and background colors
dim         dim in the current text and background colors
ul          underline in the current text and background colors
blink       blinking in the current text and background colors
reverse     reverse the current text and background colors

For example, to set bold white text on a red background, add <<bold white redbg>> into your output or error string. Reset back to normal with <<reset>>.

aura/cli 适用场景与选型建议

aura/cli 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.62M 次下载、GitHub Stars 达 102, 最近一次更新时间为 2012 年 01 月 20 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「cli」 「command」 「command line」 「getopt」 「options」 「stdio」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 aura/cli 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 aura/cli 我们能提供哪些服务?
定制开发 / 二次开发

基于 aura/cli 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 1.62M
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 105
  • 点击次数: 32
  • 依赖项目数: 30
  • 推荐数: 0

GitHub 信息

  • Stars: 102
  • Watchers: 14
  • Forks: 20
  • 开发语言: PHP

其他信息

  • 授权协议: BSD-2-Clause
  • 更新时间: 2012-01-20