Book HomePHP CookbookSearch this book

20.3. Parsing Program Arguments with getopt

20.3.1. Problem

You want to parse program options that may be specified as short or long options, or they may be grouped.

20.3.2. Solution

Use PEAR's Console_Getopt class. Its getopt( ) method can parse both short-style options such as -a or -b and long-style options such as --alice or --bob:

$o = new Console_Getopt;

// accepts -a, -b, and -c
$opts = $o->getopt($_SERVER['argv'],'abc');

// accepts --alice and --bob
$opts = $o->getopt($_SERVER['argv'],'',array('alice','bob'));

20.3.3. Discussion

To parse short-style options, pass Console_Getopt::getopt( ) the array of command-line arguments and a string specifying valid options. This example allows -a, -b, or -c as arguments, alone or in groups:

$o = new Console_Getopt;
$opts = $o->getopt($_SERVER['argv'],'abc');

For the previous option string abc, these are valid sets of options to pass:

% program.php -a -b -c
% program.php -abc
% program.php -ab -c

The getopt( ) method returns an array. The first element in the array is a list of all of the parsed options that were specified on the command line, along with their values. The second element is any specified command-line option that wasn't in the argument specification passed to getopt( ). For example, if the previous program is run as:

% program.php -a -b sneeze

then $opts is:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => a
                    [1] => 
                )
            [1] => Array
                (
                    [0] => b
                    [1] => 
                )
        )
    [1] => Array
        (
            [0] => program.php
            [1] => sneeze
        )
)

Put a colon after an option in the specification string to indicate that it requires a value. Two colons means the value is optional. So, ab:c:: means that a can't have a value, b must, and c can take a value if specified. With this specification string, running the program as:

% program.php -a -b sneeze

makes $opts:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => a
                    [1] => 
                )
            [1] => Array
                (
                    [0] => b
                    [1] => sneeze
                )
        )
    [1] => Array
        (
            [0] => program.php
        )
)

Because sneeze is now set as the value of b, it is no longer in the array of unparsed options. Note that the array of unparsed options always contains the name of the program.

To parse long-style arguments, supply getopt( ) with an array that describes your desired arguments. Put each argument in an array element (leave off the leading --) and follow it with = to indicate a mandatory argument or = = to indicate an optional argument. This array is the third argument to getopt( ). The second argument (the string for short-style arguments) can be left blank or not, depending on whether you also want to parse short-style arguments. This example allows debug as an argument with no value, name with a mandatory value, and size with an optional value:

require 'Console/Getopt.php';
$o = new Console_Getopt;
$opts = $o->getopt($_SERVER['argv'],'',array('debug','name=','size=='));

These are valid ways to run this program:

% program.php --debug
% program.php --name=Susannah
% program.php --name Susannah
% program.php --debug --size
% program.php --size=56 --name=Susannah
% program.php --name --debug

The last example is valid (if counterproductive) because it treats --debug as the value of the name argument and doesn't consider the debug argument to be set. Values can be separated from their arguments on the command line by either a = or a space.

For long-style arguments, getopt( ) includes the leading -- in the array of parsed arguments; for example, when run as:

% program.php --debug --name=Susannah

$opts is set to:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => --debug
                    [1] => 
                )
            [1] => Array
                (
                    [0] => --name
                    [1] => Susannah
                )
        )
    [1] => Array
        (
            [0] => program.php
        )
)

We've been using $_SERVER['argv'] as the array of command-line arguments, which is fine by default. Console_Getopt provides a method, readPHPArgv( ), to look also in $argv and $HTTP_SERVER_VARS['argv'] for command-line arguments. Use it by passing its results to getopt( ):

require 'Console/Getopt.php';
$o = new Console_Getopt;
$opts = $o->getopt($o->readPHPArgv(),'',array('debug','name=','size=='));

Both getopt( ) and readPHPArgv( ) return a Getopt_Error object when these encounter an error; for example, having no option specified for an option that requires one. Getopt_Error extends the PEAR_Error base class, so you can use familiar methods to handle errors:

require 'Console/Getopt.php';
$o = new Console_Getopt;
$opts = $o->getopt($o->readPHPArgv(),'',array('debug','name=','size=='));

if (PEAR::isError($opts)) {
    print $opts->getMessage();
} else {
    // process options
}

20.3.4. See Also

Recipe 20.2 for parsing of program options without getopt; documentation on Console_Getopt at http://pear.php.net/manual/en/core.console.getopt.php .



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.