PHP脚本指南-解析GNU C风格命令行选项

2020年新年第一文,冲鸭~来说一下PHP脚本开发时如何去解析对应的命令行选项

获取脚本名称

我们先来说一下如何获取当前执行的脚本是什么,我们可以使用$argv来获取,$argv包含当运行于命令行下时传递给当前脚本的参数的数组

而第一个参数总是当前脚本的文件名,因此$argv[0]就是脚本文件名,这个在PHP手册当中也有说明

#script.php 
<?php
var_dump($argv);
$ php script.php 

array(1) {
  [0]=>
  string(10) "script.php"
}

这里需要注意的是$argv可以直接在单入口文件中使用,但是在类中就不可以啦,需要声明全局,比如

#script.php
<?php
class A
{
    public static function b()
    {
        //global $argv;
        //$argv = $GLOBALS['argv'];
        var_dump($argv);
        var_dump(isset($argv));
    }
}

A::b();

不声明为全局时结果就是nullfalse

获取命令行参数

在 PHP 中,当我们在获取命令行参数时,可以通过遍历$argv来获取,遍历这里就不说了,提供一个代码段,见GithubGist

我们来说一下PHP使用 getopt 这个函数来解析命令行选项,PHP手册地址

getopt ( string $options [, array $longopts [, int &$optind ]] ) : array

参数分为短参数名、完整参数名和optind,但是PHP缺少了长短选项的映射关系配置,比如-v--version-h--help

$options短参数字符列表,该字符串中的每个字符会被当做选项字符,匹配传入脚本的选项以单个连字符-开头。只允许 a-z、A-Z 和 0-9

$longopts长参数字符列表,此数组中的每个元素会被作为选项字符串,匹配了以两个连字符--传入到脚本的选项。 长参数由于是多字节,所以必须是数组,否则没法分隔

以上的两个参数字符后用单独的字符表示不接受传值;后面跟随一个冒号:的字符表示此选项需要值(必填);后面跟随两个冒号::的字符表示此选项的值可选

下面我们来看一下具体代码示例

$ cat getopt.php
<?php
$shortOpts = "e:s::dh";
$longOpts = ["exec:","signal::", "debug", "help"];
$options = getopt($shortOpts, $longOpts);

var_export($options);

短参数:

$ php getopt.php -etest.php
array (
    'e' => 'test.php',
)

$ php getopt.php -e test.php
array (
  'e' => 'test.php',
)

$ php getopt.php -e"test.php"
array (
    'e' => 'test.php',
)

$ php getopt.php -e=test.php
array (
    'e' => 'test.php',
)

$ php getopt.php -e="test.php"
array (
    'e' => 'test.php',
)

$ php getopt.php -e="test.php" -dh
array (
    'e' => 'test.php',
    'd' => false,
    'h' => false,
)

$ php getopt.php -e="test.php" -dh -s15
array (
    'e' => 'test.php',
    'd' => false,
    'h' => false,
    's' => '15',
)

如果短参数和完整参数都传的话,程序两个值都会收到,需要我们自己判断短参数和完整参数使用哪个。比如:

$ php getopt.php -e=test.php --exec=index.php
array (
  'e' => 'test.php',
  'exec' => 'index.php',
)

完整参数:

$ php getopt.php --exec=index.php --debug --help --signal=1
array (
  'exec' => 'index.php',
  'debug' => false,
  'help' => false,
  'signal' => '1',
)

3 条评论

发表评论

*