使用PHP开发的同学,都会接触过CLI命令行。经常有一些定时任务或者一些脚本用命令行直接处理比较方便。有时我们需要为这些命令行脚本提供参数,例如网页的GET和POST。比如在某个日期做统计的脚本中,需要给它传递一个日期,这样我们就可以统计出指定日期的一些数据。这样的需求应该是很常见的,那么我们如何接收这些命令行参数呢?今天就来介绍一下这方面的内容。$argv获取所有空格分隔参数的列表这个变量估计是大家用的比较多的一个参数变量。它是PHP为我们准备的固定变量,目的是获取传递给脚本的参数数组。print_r($argv);//php如何获取PHP命令行参数.php--a=1-b=2-c=3-d=4--e=5cccddd//Array//(//[0]=>如何获取PHP命令行参数.php//[1]=>--a=1//[2]=>-b=2//[3]=>-c=3//[4]=>-d=4//[5]=>--e=5//[6]=>ccc//[7]=>ddd//)这个数组在参数之间用空格隔开。第一个元素是当前运行的脚本文件名,也就是说,不管有没有参数,这个变量都必须有一个$argv[0]表示当前脚本文件名。在日常开发需要中,其实使用这个变量就足够了。但这显然不是我们今天的主题。大家有没有注意到,在上面的代码中我们有很多参数都是-x=xxx的形式。这些参数与Linux命令选项非常相似吗?是的,这就是我们今天要关注的内容:从命令行参数列表中获取选项。getopt()其实就是这么一个简单的从命令行参数列表中获取选项的函数,我们可以像Linux命令选项一样获取指定的命令值。并且命令选项函数不再像$argv那样用空格分隔,而是将这些命令选项封装成一个数组,形成一个以选项名为键,等号后面的内容为值的数组,这样更方便我们使用使用。//php如何获取PHP命令行参数.php--a=1-b=2-c=3-d=4--e=5cccdddprint_r(getopt('a:b:c:d:e:f:'));//Array//(//[b]=>2//[c]=>3//[d]=>4//)是不是很神奇,也很直观,我们b、c、d的内容直接以key-value数组的形式获取,格式非常清晰。有同学想问,a和e呢?后面的ccc和ddd呢?首先要注意的是ccc和ddd不是标准的option参数,即这个函数接收到的内容是以-开头的option,所以这里不会输出ccc和ddd,需要注意的是非-optionparameters会中断option参数的获取。如果在ccc之后继续添加以-开头的选项,将无法获取。我们稍后会看到这个。那么以--开头的选项参数呢?下面直接看longoption函数。Longoption//php如何获取PHP命令行参数.php--a=1-b=2-c=3-d=4--e=5cccdddprint_r(getopt('',['a:','b:','c:','d:','e:','f:']));//数组//(//[a]=>1//[e]=>5//)没错,getopt()函数的第二个参数就是在--开头定义这种长选项,需要注意的是第一个参数是字符串类型,第二个长选项参数是一个数组类型。然后我们把它们组合起来,当然就可以得到所有的参数信息了!//php如何获取PHP命令行参数.php--a=1-b=2-c=3-d=4--e=5cccdddprint_r(getopt('a:b:c:d:e:f:',['a:','b:','c:','d:','e:','f:']));//数组//(//[a]=>1//[b]=>2//[c]=>3//[d]=>4//[e]=>5//)OK,获取参数选项没有问题,细心的同学我一定又发现了一个问题。为什么我必须在getopt()函数的参数中定义的选项名称后添加一个冒号?这里涉及到我们的冒号规则,请直接往下看。冒号规则getopt()的前两个参数都支持一组选项获取规则:单个字符(不接受任何值)后跟一个冒号字符(此选项需要一个值)后跟两个冒号字符(此选项的Thevalue是可选的)我们直接通过代码来看一下。//一//php如何获取PHP命令行参数.php--a=1-b=2-c=3-d=4--e=5cccdddprint_r(getopt('abcdef'));//Array//(//[b]=>//[c]=>//[d]=>//)//二//php如何获取PHP命令行参数。php-fprint_r(getopt('f::'));//数组//(//[f]=>//)print_r(getopt('f:'));//数组//(//)//三//php如何获取PHP命令行参数.php-f22print_r(getopt('f::'));//数组//(//[f]=>//)print_r(getopt('f::'));//Array//(//[f]=>22//)//四//php如何获取PHP命令行参数。php-f=22print_r(getopt('f::'));//数组//(//[f]=>22//)print_r(getopt('f:'));//数组//(//[f]=>22//)这一节比较长,我们一一来看。第一个是没有冒号的abcdef。返回的数组包含键但没有值。对应以上规则,不接受这些参数选项的值。如果传递这些参数选项,则只有键名,内容为空。第二段定义了一个参数,但没有给出值。这时候双冒号::会有键名,而单冒号:什么都没有。第三段是空格形式的期权价值。双冒号::有一个键名但没有值,单冒号:有一个普通的键值。第四段是等号=形式的选项值,单双冒号都正常接收键值。选项参数中断我们上面提到了参数中断的问题,即如果选项参数后面有一个非选项参数,getopt()将无法再获取到非选项参数后面的所有内容。//php如何获取PHP命令行参数。php-f=22aa-b=33//选项解析在找到第一个非选项时终止,之后的任何内容都将被丢弃。//Array//(//[f]=>22//)通过这个测试,可以明显看出后面的b选项是得不到的。这时,如果我们想知道option参数在哪,或者哪个参数被打断了,就可以使用getopt()函数的第三个参数。//php如何获取PHP命令行参数。php-f=22aa-b=33$optind=null;getopt('f:b:',[],$optind);echo$optind,PHP_EOL;//返回中断位置的索引值,2echo$argv[$optind],PHP_EOL;//相当于$argv的索引顺序,aa注释已经写的很清楚了,第三个参数会回调一个参数option的中断位置的索引,并且这个索引和的索引顺序位置一致$argv。总结说实话,在看文档之前,我真的只知道有一个$argv变量可以用来获取命令行脚本的参数。通过这次学习,我发现原来还有这么强大的选项参数功能。学习过程非常简单。如何将其应用到实际项目中是重点。继续学习并努力练习!测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202006/source/%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96PHP%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0.php参考文档:https://www.php.net/manual/zh/reserved.variables.argv.phphttps://www.php.net/manual/zh/function.getopt.php各媒体平台均可搜索【硬核项目经理】
