Swoft2 小白教程系列-命令行

248 阅读3分钟
原文链接: mp.weixin.qq.com

Swoft 官方微信技术交流

定义命令

一个命令由命令组和执行命令组成,一个类就是一个命令组,类里面的方法对应操作命令,一个命令的运行,是通过执行命令组对应的操作命令。

命令使用场景

例如一些手动触发的任务,就可以定义成一个个命令,通过执行命令的方式触发任务.还有有例如大量计算任务后导出数据,或者项目初始化导入数据.

命令结构

    value of option: opt1

    option: opt1 |

    | |

    php bin/swoft group:cmd john male 43 --opt1 value1 -y

    | | | | | |

    script command | | |_____ option: yes, it use shortcat: y, and it is a bool, so no value.

    | |___ |

    argument: name | argument: age

    argument: sex

参数与选项

不以 - 开头的都认为是参数 (eg: status=2 arg0)

以 - 开头的则是选项数据 以 — 开头的是长选项(long-option) 以 - 开头的是短选项(short-option) 支持混合式选项的赋值 —id=154 和 —id 154 是等效的。

注意: 输入如下的字符串将会认为是布尔值

  • on | yes | true – true

  • off | no | false – false

简单示例

命令文件一般定义在 app/console/command目录下

    <?php

    namespace App\Console\Command;

    use Swoft\Console\Annotation\Mapping\Command;

    use Swoft\Console\Annotation\Mapping\CommandArgument;

    use Swoft\Console\Annotation\Mapping\CommandMapping;

    use Swoft\Console\Annotation\Mapping\CommandOption;

    use Swoft\Console\Input\Input;

    use Swoft\Console\Output\Output;

    /**

    * Class CacheCmd

    * @Command(name="showperson")

    */

    class ShowpersonCmd{

    /**

    * @CommandMapping()

    * @CommandArgument("t", type="string",

    * desc="出生当年年份 格式例如2019"

    * )

    * @CommandOption("mouth",short="m", type="string",

    * desc="出生当月月份,--mouth 或 -m 例如04"

    * )

    * @CommandOption("day",short="d", type="string",

    * desc="出生当天日期,--day -d 例如10"

    * )

    * @param Input $input

    * @param Output $output

    * @example

    * php {binFile} showperson:show t=2019 --mouth=04 --day=29

    */

    public function show(Input $input,Output $output){

    $output->writeln("请输入打印的人名");

    $name = $input->read();

    $mouth=$input->getOpt("mouth",'01');

    $day=$input->getOpt("day",'01');

    $year=$input->getArg("t","2019");

    $output->writeln("你输入的姓名");

    $output->writeln($name);

    $output->writeln("出生日期");

    $output->writeln($year.'-'.$mouth.'-'.$day);

    }

    }

代码分析

命令的定义主要通过 @Command 和 @CommandMapping 两个注解。 @Command 定义命令组名称,@CommandMapping 定义操作命令的映射关系。命令的命令使用帮助信息,也是通过注解完成定义。

注解

@Command

@Command 定义命令组,标记一个类为 console 命令类。作用域:class

拥有属性:

name string 定义命令组名称,如果缺省,根据类名称自动解析

alias string 命令组别名,通过别名仍然可以访问它。允许多个,以逗号隔开即可

desc string 命令组描述信息说明,支持颜色标签

coroutine bool 定义是否为协程下运行,默认 true, 框架会启动一个协程运行此组里面的命令

Tips: 若 desc 为空,将会自动解析类的第一行注释作为命令组描述

这个注解是必须设置的,且推荐设置name属性,以方便以后调用。


@CommandMapping

@CommandMapping 定义操作命令映射关系,标明了一个具体的命令。作用域:method

拥有属性:

name string 定义命令组名称,如果缺省,会执行使用方法名称

alias string 命令别名,通过别名仍然可以访问它。允许多个,以逗号隔开即可

desc string 命令的描述信息说明,支持颜色标签

Tips: 若 desc 为空,将会自动解析类的第一行注释作为描述

这个注解是必须设置的,且推荐设置name属性,如果不设置 name属性 则默认是方法名

> 以下的注解是可选的,可以任意组合搭配。

@CommandOption

@CommandOption 定义一个命令的选项。作用域:method|class

拥有属性:

name string 必填项 定义命令选项名称 eg: opt

short string 定义命令选项名称的短选项

default mixed 命令选项的默认值

desc string 命令选项的描述信息说明,支持颜色标签

type string 命令选项的值类型

mode int 命令选项的值输入限定:Command::OPT_BOOLEAN (int 1 可选),Command::OPT_REQUIRED (int 2 必须)

Tips: 特别提示 @CommandOption 可以用在 @Command 类注解上面,这样子相当于给里面所有的命令都加了公共选项。

    php bin/swoft showperson:show t=2019 --mouth=04 --day=29

这个注解是用来定义选项,也就是上面示例代码的 mouth 和 day 选项


@CommandArgument

@CommandArgument 定义一个命令的参数。作用域:method

拥有属性:

name string 必填项 定义命令参数名称。eg: arg

default mixed 命令参数的默认值

desc string 命令参数的描述信息说明,支持颜色标签

type string 命令参数的值类型

mode int 命令选项的值输入限定:Command::OPT_BOOLEAN (int 1 可选),Command::OPT_REQUIRED (int 2 必须)

Tips: 命令参数是根据输入位置(有顺序的)来获取的,name 是代码里给这个位置的参数添加的命名。

    php bin/swoft showperson:show t=2019 --mouth=04 --day=29

这个注解是用来定义参数的 也就是上面示例代码的 t 参数

example 注释

@example 注释会被特殊处理(不是注解),如果你的命令方法上面有这个注释,它的内容也会被显示到命令帮助信息上面。

使用与运行

完成定义命令后,可以执行命令,处理对应业务逻辑

如果是docker 部署记得进入到容器内部,并且在swoft根目录进行操作

现在你可以执行 php bin/swoft, 命令列表中将会显示 showperson 组命令

执行 php bin/swoft serve 或者 php bin/swoft showperson -h 将会看到 showperson组里拥有的具体命令

执行 php bin/swoft showperson:show -h 将会看到此命令的完整帮助信息

如果不特殊设置,swoft 默认在 协程环境 运行命令

command 里是始终不可能直接操作 server,你每运行一次 command,都是在一个全新的进程里,除了使用一样的代码,其他毫无关系。

运行命令

    php bin/swoft showperson:show -h

控制台输出

运行命令

    php bin/swoft showperson:show t=2019 --mouth=04 --day=29

控制台输出

输入输出对象

输入对象 是 Swoft\Console\Input\Input 的实例,用于获取用户输入的命令参数选项等信息。命令逻辑里面,可以通过函数参数和全局函数获取输入输出对象。

输出对象 是 Swoft\Console\Output\Output 的实例,用于显示信息到控制台。命令逻辑里面,可以通过函数参数和全局函数获取输入输出对象。

获取输入输出对象

我们可以通过 方法参数注入 或 全局函数 两种方式来获取输入输出对象,使用方式如下。

方法参数注入示例

    /**

    * Test command

    *

    * @Command(coroutine=true)

    */

    class TestCommand

    {

    /**

    * 使用方法参数注入获取输入对象。

    * @param Input $input 输入对象

    * @param Output $output 输出对象

    *

    * @CommandMapping("test2")

    */

    public function test(Input $input, Output $output)

    {

    // 这里就可以使用$input和$output操作输入输出对象

    }

    }

全局函数示例

    /**

    * Test command

    *

    * @Command(coroutine=true)

    */

    class TestCommand

    {

    /**

    * 使用全局方法获取输入对象。

    * @CommandMapping()

    */

    public function demo()

    {

    $input = \input(); //输入对象

    $output = \output(); //输出对象

    // ......

    }

    }

输入对象详解

以命令 php bin/swoft showperson:show t=2019 —mouth=04 —day=29 进行解析

获取基本信息

    echo $input->getScriptFile(); // 'bin/swoft' 执行的入口脚本文件

    echo $input->getCommand(); // 'showperson:show' 命令名称 解析到的第一个参数将会被认为是命令名称,并且不会再存入到 参数列表中

    echo $input->getPwd(); // 当前工作目录

打印所有的参数信息

    var_dump($input->getArgs());

控制台输出

    array(1) {

    ["t"]=>

    string(4) "2019"

    }

获取命令参数值

    // argument

    $first = $input->getFirstArg(); // 'arg0'

    $status = $input->getArg('status', '3'); // '2'

    $status = $input->getInt('status'); // 2

    // 获取一个必须的参数,若用户没有输入值,将会抛出错误信息

    $id = $input->getRequiredArg('id');

命令选项信息

获取解析后的选项信息

  • 没有值的选项,将设置默认值为 bool(true)

  • 短选项不仅仅只是以一个 - 开头,而且名称 只能是一个字符

  • 多个(默认值的)短选项可以合并到一起写。如 -rf 会被解析为两个短选项 ‘r’ => bool(true) ‘f’ => bool(true)

示例

    var_dump($input->getOpts());

控制台输出

    array(2) {

    ["mouth"]=>

    string(2) "04"

    ["day"]=>

    string(2) "29"

    }

获取选项值

    // option

    $page = $input->getOpt('page') // '23' 这里有个bug如果用户传的是短选项则值获取不到,所以推荐使用 sameOpt

    $page = $input->getIntOpt('page') // 23

    $debug = $input->getBoolOpt('debug') // True

    $test = $input->getBoolOpt('test') // False

    $d = $input->getBoolOpt('d') // True

    // 获取到一个值就返回,对同一个含义的选项选项非常有用

    $showHelp = $input->sameOpt(['h','help']);

    // 获取一个必须的选项,若用户没有输入值,将会抛出错误信息

    $id = $input->getRequiredOpt('id');

读取用户输入

    echo "Your name:";

    $name = $input->read();

    echo 'input is ' . $name; // 'inhere'

控制台输出

    Your name: wike

    input is wike

输出对象详解

Console 数据展示 - 提供格式化信息的输出显示。主要功能封装在命名空间 Swoft\Console\Advanced\Formatter 下,提供了 Swoft\Console\Helper\Show 辅助类来快速使用它们。

输出单行

    $output->writeln("末尾有换行符")

输出不换行

    $output->write("不换行")

标题文本输出

    Show::title("标题文本")

    $output->title("标题文本") //功能以上面代码一样

段落式文本输出

    Show::section("标题文本","段落内容")

    $output->section("标题文本","段落内容") //功能以上面代码一样

列表数据展示输出

    $title = 'list title';

    $data = [

    'name' => 'value text', // key-value

    'name2' => 'value text 2',

    'more info please XXX', // only value

    ];

    Show::aList($data, $title);

    $output->aList($data, $title) //功能以上面代码一样

渲染效果

多列表数据展示输出

    $data = [

    'list1 title' => [

    'name' => 'value text',

    'name2' => 'value text 2',

    ],

    'list2 title' => [

    'name' => 'value text',

    'name2' => 'value text 2',

    ],

    // ... ...

    ];

    Show::mList($data);

    $output->mList($data, $title) //功能以上面代码一样

渲染效果

面板展示信息输出

    $data = [

    'application version' => '1.2.0',

    'system version' => '5.2.3',

    'see help' => 'please use php bin/app -h',

    'a only value message',

    ];

    Show::panel($data, 'panel show', ['borderChar' => '#']);

    $output->panel($data, 'panel show', ['borderChar' => '#']); //功能以上面代码一样

渲染效果

数据表格信息输出

    // like from database query's data.

    $data = [

    [ col1 => value1, col2 => value2, col3 => value3, ... ], // first row

    [ col1 => value4, col2 => value5, col3 => value6, ... ], // second row

    ... ...

    ];

    Show::table($data, 'a table');

    $output->table($data, 'a table'); //功能以上面代码一样

    // use custom head

    $data = [

    [ value1, value2, value3, ... ], // first row

    [ value4, value5, value6, ... ], // second row

    // ... ...

    ];

    $opts = [

    'showBorder' => true,

    'columns' => [col1, col2, col3, ...]

    ];

    Show::table($data, 'a table', $opts);

    $output->table($data, 'a table', $opts); //功能以上面代码一样

    $data = [

    ['1', 'john', '2', 'john@email.com'],

    ['2', 'tom', '0', 'tom@email.com'],

    ['3', 'jack', '1', 'jack@email.com'],

    ];

    $opts = [

    'showBorder' => true,

    'columns' => ['id', 'name', 'status', 'email']

    ];

    Show::table($data, 'Table Show', $opts);

    $opts['showBorder'] = false;

    Show::table($data, 'No Border Table Show', $opts);

    $opts['bodyStyle'] = 'red';

    $opts['showBorder'] = true;

    Show::table($data, 'Change Style Table Show', $opts);

    $opts['bodyStyle'] = '';

    $opts['showBorder'] = true;

    $opts['columns'] = [];

    Show::table($data, 'No Head Table Show', $opts);

    $output->table($data, 'Head Table Show', $opts); //功能以上面代码一样

渲染效果

渲染帮助信息面板

    Show::helpPanel([

    "description" => 'a help panel description text. (help panel show)',

    "usage" => 'a usage text',

    "arguments" => [

    'arg1' => 'arg1 description',

    'arg2' => 'arg2 description',

    ],

    "options" => [

    '--opt1' => 'a long option',

    '-s' => 'a short option',

    '-d' => 'Run the server on daemon.(default: <comment>false</comment>)',

    '-h, --help' => 'Display this help message'

    ],

    ]);

渲染效果