Laravel学习记录(七):Command

简单来说,Command命令文件写了已经不少了,从一开始写的拉取报表的触发器(Dispatcher),到监测报表拉取延迟,查找确实站点之类的脚本,都算是Laravel的自定义命令文件,就算抄我也有一点点印象了,稍微总结一下这部分的内容,方便之后。

简介

简单来说,自定义命令就是自定义Laravel的artisan命令,像是自带的创建类型文件的make之类的,我们做的就是自定义相关功能的命令,这样的命令文件也就能直接被artisan识别并且使用了。可是目前我对这种脚本的使用完全是手动调用,至于我写的东西怎么就在线上自动执行了呢?不清楚,之后看看。

构成的元素

首先一般这类自定义artisan的命令都在App/Console/Commands目录里面。当然Laravel不怎么限制文件出现的位置,写在其他地方似乎也没有影响,但是文件组织还是要有的。

下面说的这些前提是要继承Command基类,不然基本上是空谈。

signature

这个protected元素定义了artisan元素的调用句柄,参数和选项之类的东西。类比到定义一个Linux命令切换目录,大概就是cd {path}这种形式的东西(可能例子不太合适,稍微理解一下)。

description

这个变量是用来对命令的作用进行说明的,在列出命令时搭配这个变量说明命令的作用。

handle()

这个方法是整个命令脚本的主方法,只要运行命令就一定会运行这个方法,感觉就是个很像C中main()的东西。

argument和option

这两个内容是在定义signature时候定义的东西,个人感觉这两个的区别不是很大,很多功能都是互通的,就是写法和获取内容的方法有一点不同。

在signature中定义的写法是,argument用{arg}的形式,option用{--opt}的形式,后者比前者多了两个杠。

参数后面带?标识参数可选,也可以用等号来给参数添加默认值;而选项在不带值的情况下使用就是个判断true和false的标志,带上就是true,不带就是false,而带值选项的定义就是加个=,这样的用法感觉和参数就差不多了,甚至也能在后面写默认值。用|来标识选项的另一种写法,像是做个简写命令什么的。

数组参数在参数后面带个*,这样的话,就会把输入的多个参数值封装成数组参数,选项也可以使用{--opt=*}来实现选项的多个输入。

可以使用$this->argument('arg')、$this->arguments()来获取单个或者是全部参数,用$this->option('opt')、$this->options()来获取单个或是全部选项。

用编程方式执行命令

简单来说就是不用命令行而用程序调用命令。可以用Artisan下面的call()方法来实现,第一个参数是命令的句柄,第二个参数是数组,传入对应的option或者argument。或者直接第一个参数一步到位。选项布尔类型的用true或false来实现。

可以命令排队。前提需要配置好队列。

从一个命令文件来调用另一个命令文件也可以用call()方法,属于Command类。调用但禁止所有输出,可以使用callSilenly()方法。

其他内容

php artisan make:command xxx 用来生成空白的命令脚本。

选项可以简写,用--Q|queue类似的结构实现,实际用的时候也是,改成一道杠就可以了。

选项或参数的说明可以写在signature中。

交互式输入,可以用ask()来实现,secret()实现的是内容不可见。confirm()来实现用户的确认,用户用y或者yes来返回确认。anticipate实现的是自动补全,可以在第二个参数写一个可能结果的数组,也可以写一个闭包函数,专门处理返回内容的相关功能。choice(),预定义选择。最大的尝试次数,是否允许多次选择。

控制台输出:line,info,comment,question,error,newLine(空白行)

表格:table([title],[content])

进度条:withProgressBar(all,item),还可以设置推进进度条:

$users = App\Models\User::all();

$bar = $this->output->createProgressBar(count($users));

$bar->start();

foreach ($users as $user) {
    $this->performTask($user);

    $bar->advance();
}

$bar->finish();

确定步数,start->advance->finish。

注册命令是在App\Console\Kernel类中注册的,只有经过这一步,系统才能检索到添加的命令脚本。简单来说就是在commands方法里面,用load方法读取对应脚本所在的目录,理论上只要读到,就可以搜索到命令脚本完成注册。

结尾

暂时写到这里,可能写的并不详细,只起到了知道有这么个东西的作用,具体用到的时候还是需要去看一下文档。