Question

I'm using Console_Getopt in PHP 5.2, and finding it surprising about how different it is from getopt in other languages (perl, bash, java). Can anyone recommend how to parse the args from the array "$opts" returned?

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

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

// the print_r returns below

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

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

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

        )

    [1] => Array
        (
        )

)

I started doing something like below, which is long-winded, so I'm looking for suggestions on dealing with command-line flags in php.

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";
    }
}

I wonder why PHP's getopt isn't like perl's, where the array's key is the flag eg $opts{'a'} .. that would be convenient.

Was it helpful?

Solution

Per the inline documentation

The return value is an array of two elements: the list of parsed options and the list of non-option command-line arguments. Each entry in the list of parsed options is a pair of elements - the first one specifies the option, and the second one specifies the option argument, if there was one.

Which means you easily discard the second array, and assume a commitment to the keeping the array of arrays, first element option, second element value, format.

With that assumption in place, try

$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;
}

to get an data structure more of your liking.

As for why this is different than other implementation of getopt, ask the maintainers.

OTHER TIPS

Check GetOptionKit for PHP:

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

Synopsis

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 can print options for you:

* 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.

I wrote a wrapper class around getopt(), similar to Console_GetOpt but I think a bit nicer.

You can find it here: http://github.com/pete-otaqui/ClipClop

A PHP option parser based on getopt().

ClipClop allows you to easily create command line tools with options. ClipClop automatically generates nicely formatted usage instructions, and also gives a convenient API for accessing parameters and values.

ClipClop handles required and optional parameters, and values for them. So a given option such as "--verbose" can be required or optional in itself, and it can have no parameter value or an optional one, or a required one.

ClipClop manages multiple values, although enforces single values by default, can validate against regular expressions and can parse out certain types for you: integers, numbers, json and urls.

Quick Example Create a script called "environment_test", with the following code

#!/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";
?>

It includes various other options, and unit tests.

For what it's worth, I recently hacked out a little project of my own for command line option parsing in PHP. I call it Pharse (like "PHP Parse" ... kind of). It's available for download on github here:

https://github.com/chrisallenlane/Pharse

It was so heavily inspired by Trollop that you could almost consider it a port, though I did not implement all of the features Trollop has. (I didn't need some features - like sub-commands - for my own purposes, so I didn't bother.)

The general gist of the library is that its usage involves requiring a single base file, and then passing the Pharse class a single associative array of options. For example:

    <?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);

?>

I wrote a blog post introducing the library here:

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

I hacked out the library for casual use for my personal projects, so I'd use caution before deploying this script to a production environment. I haven't even gotten around to implementing proper unit tests yet, so be ye warned.

With that said, though, I think it's a pretty nifty little script, and I think it's perfectly suitable for hobby projects and the like.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top