spaceboy/nette-cli

用于在Nette PHP框架中轻松创建CLI脚本的简单工具

v1.2 2022-03-16 18:01 UTC

This package is auto-updated.

Last update: 2024-09-16 23:43:19 UTC


README

用于在Nette框架中轻松创建CLI应用的简单工具

安装

将Nette web应用安装到Nette框架中的最佳方法是使用最简单的方法。打开控制台,转到您的应用程序目录,并执行以下命令

composer require spaceboy/nette-cli

我的第一个CLI应用程序

我强烈建议您在应用程序根目录中为CLI应用程序创建一个专用空间。例如,对于从命令行运行的应用程序使用bin,对于从cron运行的应用程序使用cron

安装后,将nette-cli.php文件从vendor/spaceboy/nette-cli/bin目录复制(或链接)到CLI脚本专用文件夹(例如bin)。

bin目录中创建一个PHP文件,例如command.php

root
 +- app   // Nette app directory
 +- bin   // CLI commands directory
 |    command.php   // Out first CLI aplication
 +- cron  // cron CLI commands directory
 +- log   // Nette log directory
 ...

或通过在bin目录中简单运行nette-cli.php来创建模板脚本

php nette-cli.php create --name command.php

command.php中,我们首先必须创建应用程序命名空间和包含所需的文件和命名空间。

<?php
namespace App\Bin;

require_once __DIR__ . '/../vendor/autoload.php';

use Spaceboy\NetteCli\Cli;
use Spaceboy\NetteCli\Argument;
use Spaceboy\NetteCli\Command;

然后我们可以创建我们的第一个应用程序

(new Cli())
    // Argument definition:
    ->registerArgument(
        Argument::create('name')
            ->setShortcut('n')
            ->setFormat('string:2..25')
    )
    // Option definition:
    ->registerOption(
        Argument::create('strong')
    )
    // Command definition:
    ->registerCommand(
        Command::create('hello')
            ->withArgumentRequired('name')
            ->withOption('strong')
            ->setWorker(
                // worker function:
                function ($name, $strong) {
                    echo "Hello, {$name}";
                    echo ($strong ? "!" : ".");
                    echo PHP_EOL;
                }
            )
    )
    // Don't forget to run whole CLI application:
    ->run();

这就完成了,朋友们。在命令行中尝试一下

php command.php hello --name World

因为我们注册了一个名为“hello”的命令,所以它的工作函数会被调用和执行。

因为我们注册了一个名为“name”的参数,并设置了该参数为“hello”命令的必需参数(Command->withArgumentRequired([arg-name])),所以我们的应用程序在没有在命令行中输入参数的情况下不会运行。

因为我们还注册了一个名为“shortcut”的参数名(Argument->setShortcut()),所以我们可以用更少的输入来运行我们的应用程序

php command.php hello -n=World

因为我们设置了参数“name”的必需格式(Argument->setFormat())为string:2..25(至少2个字符长,最多25个字符),所以我们的应用程序不会在参数太短或太长的情况下运行。自己试试看。

因为我们还在应用程序中注册了一个名为“strong”的参数(Cli->registerOption('strong'))并在命令“hello”中启用了此参数(Command->withOption(strong)),所以我们可以使用它

php command.php hello --name World --strong

Cli 公共方法

  • setName(string $name): Cli

    设置应用程序在每次命令执行期间显示的名称。

  • setDescription(string $description): Cli

    设置应用程序描述,当应用程序在没有任何命令/参数(帮助)运行时显示,后跟命令、参数和选项列表。

  • registerArgument(Argument $argument): Cli

    注册参数(见Argument)。只有注册的参数才能被命令引用。

  • registerOption(Argument $option): Cli

    注册选项(见Argument,因为选项具有Argument类型)。只有注册的参数才能被命令引用。

  • registerCommand(Command $command): Cli

    注册可执行命令(见Command)。

  • run(string $arguments = null)

    运行整个应用程序。当您需要从命令行操作参数(例如在测试期间)时,请使用$arguments参数。示例

    ...
      ->run('--arg1 "Argument one" --arg2 Argument2 --option')
    
  • error(string $message): void

    静态方法;显示错误消息($message)并退出脚本。

Argument 公共方法

  • create(string $name): Argument

    静态方法,创建一个Argument实例。所有其他方法都可以链式调用。

      Argument::create('my-argument')
    
  • setDescription(string $description): Argument

    设置参数描述(在用户查找帮助时显示,因此请尽量准确)。

  • setShortcut(string $shortcut): Argument

    为参数名称设置一个字符快捷键。尽量找一个可预测且直观的字符,或者直接不使用快捷键。

  • setFormat(string $format): 参数

    为参数设置所需的Nette 验证类型。可以在命令工作函数体中节省很多验证。

Command 公共方法

  • create(string $name)

    静态方法,创建一个Command实例。其他所有方法都可以链式调用。

      Command::create('my-command')
    
  • setDescription(string $description): Command

    设置参数描述(在用户查找帮助时显示,因此请尽量准确)。

  • withArgumentRequired(string $argumentName): Command

    为命令工作函数设置必需参数。只能使用已注册的参数名称。

  • withArgumentOptional(string $argumentName): Command

    为命令工作函数设置可选参数。只能使用已注册的参数名称。

  • withOption(string $optionName): Command

    为命令工作函数设置可选布尔参数(选项)。只能使用已注册的选项名称。

  • setWorker(callable $worker): Command

    为命令设置执行函数。函数参数必须是

    1. 在 Cli 中注册(使用 Cli->registerArgument()Cli->registerOption())并在命令定义中声明(使用 Command->withArgumentRequired()Command->withArgumentOptional()Command->withOption())(从命令行传入的参数)

    或者

    1. 通过类型提示声明(Nette 应用程序类/对象)

    示例

    ->registerArgument(
        Argument::create('name')
    )
    ...
    ->registerCommand(
      Command::create('use-database')
        ->withArgumentRequired('name')
        ->setWorker(
            function (
                \Nette\Database\Connection $connection, // DI
                $name
            ) {
                $row = $connection->query(
                    'SELECT * FROM table WHERE name = ?', $name
                )->fetch();
            }
        )
    )

Format

Format 是一个简单的辅助类,用于更方便地进行命令行文本格式化。

方法

  • reset(): string

    返回一个字符串,将文本/背景颜色设置重置为标准。

  • color(string ...$color): string

    返回一个字符串,在控制台回显后设置文本/背景颜色为下一个输出。最后,别忘了将设置重置为默认值(使用 reset 方法)!

  echo
      Format::color(Format::RED, Format::BG_WHITE)
      . 'Red text on white background'
      . Format::color(Format::GREEN)
      . 'GREEN text on white background'
      . Format::reset()
      ;
  • bold(string $text): string

    返回一个字符串,在控制台回显后以粗体显示。

  • dim(string $text): string

    返回一个字符串,在控制台回显后以暗淡方式显示。

  • underlined(string $text): string

    返回一个字符串,在控制台回显后以下划线显示。

  • blink(string $text): string

    返回一个字符串,在控制台回显后以闪烁方式显示。

  • reverse(string $text): string

    返回一个字符串,在控制台回显后以反转方式显示(文本和背景颜色交换)。

  • hidden(string $text): string

    返回一个字符串,在控制台回显后以隐藏方式显示(例如密码等)。

  • bell(): string

    返回一个字符串,在控制台回显后发出蜂鸣声(就像古老的电传蜂鸣器)。

  • backspace(): string

    返回一个字符串,在控制台回显后将光标左移一个位置。

  • tab(): string

    返回一个字符串,在控制台回显后将光标移至下一个制表位(或行尾,如果没有更多的制表位)。

  • getConsoleColumns: int

    返回控制台宽度(以字符为单位)。

  • getConsoleLines: int

    返回控制台高度(以行为单位)。

颜色表

使用辅助工具

当事情变得复杂时,你可能需要在两个或多个脚本之间共享某些参数或工作函数(例如在 cli 脚本和 cron 脚本之间)。请随意使用辅助工具。您可以将静态和动态方法以及闭包都设置为命令工作函数。只需记住,这些方法必须是公共的。

  ...
  ->registerArgument(ArgumentsClass::argName());
  ...
  ->registerCommand($commandClass->getCommand('commandOne'));
  ->registerCommand(
    Command::create('command')
      ->withArgumentRequired('name')
      // Use static method:
      ->setWorker([WorkersClass::class, 'staticMethod'])
      // Or use dynamic method:
      ->setWorker([new WorkersClass(), 'dynamicMethod'])
  );
  ...
  ->run();