Parsing Command-Line Arguments
When you are running a PHP script on the command line, you obviously can't pass arguments via $_GET and $_POST variables (the CLI has no concept of these Web protocols). Instead, you pass in arguments on the command line. Command-line arguments can be read in raw from the $argv autoglobal.
The following script:
#!/usr/bin/env php
<?php
print_r($argv);
?>
when run as this:
> ./dump_argv.php foo bar barbara
gives the following output:
Array
(
[0] => dump_argv.php
[1] => foo
[2] => bar
[3] => barbara
)
Notice that $argv[0] is the name of the running script.
Taking configuration directly from $argv can be frustrating because it requires you to put your options in a specific order. A more robust option than parsing options by hand is to use PEAR's Console_Getopt package. Console_Getopt provides an easy interface to use to break up command-line options into an easy-to-manage array. In addition to simple parsing, Console_Getopt handles both long and short options and provides basic validation to ensure that the options passed are in the correct format.
Console_Getopt works by being given format strings for the arguments you expect. Two forms of options can be passed: short options and long options.
Short options are single-letter options with optional data. The format specifier for the short options is a string of allowed tokens. Option letters can be followed with a single : to indicate that the option requires a parameter or with a double :: to indicate that the parameter is optional.
Long options are an array of full-word options (for example, --help).The option strings can be followed by a single = to indicate that the option takes a parameter or by a double == if the parameter is optional.
For example, for a script to accept the -h and --help flags with no options, and for the --file option with a mandatory parameter, you would use the following code:
require_once "Console/Getopt.php";
$shortoptions = "h";
$longoptons = array("file=", "help");
$con = new Console_Getopt;
$args = Console_Getopt::readPHPArgv();
$ret = $con->getopt($args, $shortoptions, $longoptions);
The return value of getopt() is an array containing a two-dimensional array. The first inner array contains the short option arguments, and the second contains the long option arguments. Console_Getopt::readPHPARGV() is a cross-configuration way of bringing in $argv (for instance, if you have register_argc_argv set to off in your php.ini file).
I find the normal output of getopt() to be a bit obtuse. I prefer to have my options presented as a single associative array of key/value pairs, with the option symbol as the key and the option value as the array value. The following block of code uses Console_Getopt to achieve this effect:
function getOptions($default_opt, $shortoptions, $longoptions)
{
require_once "Console/Getopt.php";
$con = new Console_Getopt;
$args = Console_Getopt::readPHPArgv();
$ret = $con->getopt($args, $shortoptions, $longoptions);
$opts = array();
foreach($ret[0] as $arr) {
$rhs = ($arr[1] !== null)?$arr[1]:true;
if(array_key_exists($arr[0], $opts)) {
if(is_array($opts[$arr[0]])) {
$opts[$arr[0]][] = $rhs;
}
else {
$opts[$arr[0]] = array($opts[$arr[0]], $rhs);
}
}
else {
$opts[$arr[0]] = $rhs;
}
}
if(is_array($default_opt)) {
foreach ($default_opt as $k => $v) {
if(!array_key_exists($k, $opts)) {
$opts[$k] = $v;
}
}
}
return $opts;
}
If an argument flag is passed multiple times, the value for that flag will be an array of all the values set, and if a flag is passed without an argument, it is assigned the Boolean value true. Note that this function also accepts a default parameter list that will be used if no other options match.
Using this function, you can recast the help example as follows:
$shortoptions = "h";
$longoptions = array("file=", "help");
$ret = getOptions(null, $shortoptions, $longoptions);
If this is run with the parameters -h --file=error.log, $ret will have the following structure:
Array
(
[h] => 1
[--file] => error.log
)
|