3

我在 PHP 5.2 中使用 Console_Getopt,发现它与其他语言(perl、bash、java)中的 getopt 有多么不同,这让我感到惊讶。谁能推荐如何从返回的数组“$opts”中解析参数?

php myprog.php -a varA -c -b varB

$o= new Console_Getopt;
$opts = $o->getopt($argv, "a:b:c");
print_r($opts);

// print_r 在下面返回

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => a
                    [1] => varA
                )

            [1] => Array
                (
                    [0] => c
                    [1] =>
                )

            [2] => Array
                (
                    [0] => b
                    [1] => varB
                )

        )

    [1] => Array
        (
        )

)

我开始做类似下面的事情,这是冗长的,所以我正在寻找关于在 php.ini 中处理命令行标志的建议。

foreach($opts[0] as $i -> $keyval) {
    list($key, $val) = $keyval;
    if($key == 'a') {
        print "valueForA: $val\n";
    } else if($key == 'b') {
        print "valueForB: $val\n";         
    } else if($key == 'c') {
        print "c is set\n";
    }
}

我想知道为什么 PHP 的 getopt 不像 perl 的那样,其中数组的键是标志,例如 $opts{'a'} .. 那会很方便。

4

4 回答 4

4

检查 PHP 的 GetOptionKit:

https://github.com/c9s/php-GetOptionKit

概要

use GetOptionKit\OptionCollection;
use GetOptionKit\OptionParser;

$options = new OptionCollection;
$options->add( 'f|foo:' , 'option require value' );  # returns spec object.

$options->add( 'b|bar+' , 'option with multiple value' );
$options->add( 'z|zoo?' , 'option with optional value' );

$options->add( 'f|foo:=i' , 'option require value, with integer type' );
$options->add( 'f|foo:=s' , 'option require value, with string type' );

$options->add( 'v|verbose' , 'verbose flag' );
$options->add( 'd|debug'   , 'debug flag' );


$parser = new OptionParser($options);
$result = $parser->parse( array( 'program' , '-f' , 'foo value' , '-v' , '-d' ) );

$spec = $result->verbose;
$spec = $result->debug;
$spec->value;  # get value

GetOptionKit\OptionPrinter 可以为您打印选项:

* Available options:
              -f, --foo   option requires a value.
              -b, --bar   option with multiple value.
              -z, --zoo   option with optional value.
          -v, --verbose   verbose message.
            -d, --debug   debug message.
                 --long   long option name only.
                     -s   short option name only.
于 2011-11-29T07:03:53.733 回答
3

根据内联文档

返回值是一个包含两个元素的数组:已解析选项列表和非选项命令行参数列表。已解析选项列表中的每个条目都是一对元素 - 第一个指定选项,第二个指定选项参数,如果有的话。

这意味着您可以轻松丢弃第二个数组,并承诺保留数组数组、第一个元素选项、第二个元素值、格式。

有了这个假设,尝试

$o= new Console_Getopt;
$opts = $o->getopt($argv, "a:b:c");
print_r(getHashOfOpts($opts));

function getHashOfOpts($opts) {
    $opts = $opts[0];
    $return_opts = $opts;
    $return_opts = Array();
    foreach($opts as $pair){
        $return_opts[$pair[0]] = $pair[1];
    }
    return $return_opts;
}

获得更喜欢的数据结构。

至于为什么这与 getopt 的其他实现不同,请询问维护人员。

于 2009-06-21T03:36:08.260 回答
1

我围绕 getopt() 编写了一个包装类,类似于 Console_GetOpt,但我认为更好一些。

你可以在这里找到它:http: //github.com/pete-otaqui/ClipClop

基于 getopt() 的 PHP 选项解析器。

ClipClop 允许您轻松创建带有选项的命令行工具。ClipClop 自动生成格式良好的使用说明,并提供方便的 API 用于访问参数和值。

ClipClop 处理必需和可选参数以及它们的值。因此,诸如“--verbose”之类的给定选项本身可以是必需的或可选的,它可以没有参数值,也可以是可选的,也可以是必需的。

ClipClop 管理多个值,尽管默认情况下强制执行单个值,可以根据正则表达式进行验证,并可以为您解析出某些类型:整数、数字、json 和 url。

快速示例使用以下代码创建一个名为“environment_test”的脚本

#!/usr/bin/env php
<?php

// do this unless you have setup an Autoloader
require_once('/path/to/ClipClop.php');

$clipclop = new ClipClop();

$clipclop->addOption(array(
    'short' => 'e', // shortname, i.e. "-e"
    'long' => 'environment', // longname, i.e. "--environment"
    'value' => TRUE, // A value must be given such as "--environment=TEST"
    'help' => 'Set the environment', // help text for the 'usage' text
    'required' => TRUE, // Environment must be provided
));

// as soon as we ask for an option, ClipClop will parse CLI arguments with getopt()

$environment = $clipclop->getOption('e'); // returns the value set for 'e' OR 'environment'

print "You ran this script with environment: $environment";
?>

它包括各种其他选项和单元测试。

于 2012-09-03T09:44:33.670 回答
0

对于它的价值,我最近破解了我自己的一个小项目,用于在 PHP 中解析命令行选项。我称它为Pharse(类似于“PHP Parse”……之类的)。可以在 github 上下载:

https://github.com/chrisallenlane/Pharse

它深受Trollop的启发,你几乎可以认为它是一个端口,尽管我没有实现 Trollop 的所有功能。(出于我自己的目的,我不需要一些功能——比如子命令——所以我没有打扰。)

该库的一般要点是它的用法涉及需要一个基本文件,然后将 Pharse 类传递给一个单一的关联选项数组。例如:

    <?php

   # specify some options
   $options = array(
        'user_name'     => array(
            'description'   => 'Your username',
            'default'       => 'admin',
            'type'          => 'string',
            'required'      => true,
            'short'         => 'u',
        ),

        'password' => array(
            'description'   => 'Your password',
            'default'       => 'sexsecretlovegod',
            'type'          => 'string',
            'required'      => true,
        ),
    );

# You may specify a program banner thusly:
$banner = "This program logs you in to the Gibson.";
Pharse::setBanner($banner);

# After you've configured Pharse, run it like so:
$opts = Pharse::options($options);

?>

我在这里写了一篇介绍该库的博客文章:

http://chris-allen-lane.com/2012/03/pharse-a-library-for-php-command-line-option-parsing/

我为我的个人项目临时使用了这个库,所以在将此脚本部署到生产环境之前我会谨慎行事。我什至还没有开始实施适当的单元测试,所以请注意。

尽管如此,我认为这是一个非常漂亮的小脚本,我认为它非常适合业余项目等。

于 2012-03-31T19:19:57.473 回答