Get Options Improved (or Getopti) is written to be a better command-line parsing tool for PHP programs. Inspired by the Optparser library for Ruby, as well as the Console_Getopt library for PEAR/PHP, Getopti aims to make interacting with the command-line inside your PHP applications a much more enjoyable experience.
- PHP 5.3 or greater
- PHP 5.3 Only (which is, in fact, a feature)
- No more formatting option strings
- Automated help output
- Callbacks (see the Using Callbacks section of this README)
To install using PEAR, you first have to discover my Pearfarm Channel, then you can install the library (please note, installation via this channel may only be a temporary solution.). All you have to do is hit up your command-line and type the following:
[sudo] pear channel-discover bschaeffer.pearfarm.org
[sudo] pear install bschaeffer/Getotpi-beta
Just require the library and get a new instance:
require 'Getopti/Getopti.php';
$opts = new Getopti\Command;
Banners are simply unpadded lines of text to be added to the automated help output.
$opts->banner(string $banner);
Usage lines should be used for longer, more descriptive lines of text. They are automatically wrapped and left padding is added to them (see the 'Configuration' section of this readme for padding information).
$opts->usage(string $usage);
$opts->command(string $command[, string $description]);
This method is primarily hear to enable uniformity in generating output. The output is similar to the output generated when calling $opts->on()
. Use it in your main help class when displaying a list of commands available within you CLI application.
This method is used to add options. Option data is automatically added to the automated help output.
$opts->on(mixed $opts, [string $parameter, string $description, closure $callback]);
Examples
Specify only the short option -v
:
$opts->on('v');
Specify only the long option --verbose
:
$opts->on('verbose');
Specify both -v
and --verbose
options:
$opts->on(array('v', 'verbose'));
Specify the option --revision
that expects a REQUIRED parameter (Getopti will raise a Getopti\Exception
if the parameter is missing.):
$opts->on('revision', 'REV');
Specify the option --revision
that expects an [OPTIONAL] parameter:
$opts->on('revision', '[REV]');
Specify the option --revision
with an REQUIRED parameter that can be specified multiple times using the [+]
indicator:
$opts->on('revision', 'REV [+]');
Specify both the -h
and --help
options, setting a description and using a callback to display automated help output:
$opts->on(array('h', 'help'), NULL, 'show help information',
function ($help) use ($opts) {
echo $opts->help();
exit();
}
);
Please note: The default is not to run the callback unless the option is specified.
Parses the passed arguments based on previously defined options.
$opts->parse(array $arguments [, bool $flatten])
This method requires that you pass the $arguments
array directly to it. Fortunately this is really easy.
$args = Getopti::read_args();
$results = $opts->parse($args);
The optional $flatten
parameter is described in the Results section of this README.
A static function that attempts to retrieve the command-line arguments from various global PHP variables:
Getopti\Utils::read_args([int $trim]);
The optional $trim
parameter simply removes n
number of arguments from the beginning of the arguments array:
// $ cmd my great arguments
$args = Getopti\Utils::read_args(1); // array('great', 'arguments')
Getopti::$columns = 0; # columns to wrap at (defaults to 75, auto-discovered if possible)
Getopti::$left_padding = 1; # cmd/opt padding for the left side of the terminal
Getopti::$right_padding = 2; # all output padding for the right side
Getopti::$option_padding = 26; # padding between cmd/opt and their descriptions
Assuming a CLI that can handle the following command:
$ cmd write -C "I love PHP!" --content "Getopti rules!" -N file -- brkopt
We might set up our application like so:
<?php
require 'yourapp.php';
require 'Getopti/Getopti.php';
$APP = new YourApp();
$opts = new Getopti();
$opts->banner('cmd write');
$opts->usage('A really, really hard way to create a file!');
$opts->banner('');
$opts->banner('command options:');
$opts->on(array('N', 'name'), '[PATH]', 'set the name of the file',
function ($name) use ($APP) {
$APP->set_name($name);
}
);
$opts->on('ext', array('[EXT]', 'txt'), 'set the file extension',
function ($ext) use ($APP) {
$APP->set_ext($ext);
}
);
$opts->on(array('C', 'content'), 'CONTENT [+]', 'add content to the file',
function ($content) use ($APP) {
$APP->add_content($content);
}
);
$opts->banner('');
$opts->banner('global options:');
$opts->on('help', FALSE, 'show help information for a given command',
function ($help) use ($opts) {
echo $opts->help();
exit();
}
);
$args = Getopti::read_args();
$results = $opts->parse($args);
?>
To output usage information for the above command, use $opts->help()
. It would look something like this:
cmd write
A really, really hard way to create a file!
command options:
-N, --name [PATH] set the name of the file
--ext [EXT] set the file extension
-C, --content CONTENT [+]
add content to this file
global options:
--help show help information for a given command
After setting up the above command, running $opts->parse()
would default to returning the following results:
$results = array(
0 => array(
0 => array('C', 'I love PHP!'),
1 => array('content', 'Getopti rules!'),
2 => array('N', 'my_file')
),
1 => array(
0 => 'write'
),
2 => array(
0 => 'brkopt'
)
);
$results[0]
- all the matched option flags (and values) from the command-line arguments.$results[1]
- all the non-options that the parser was not able to match with any flags.$results[2]
- all the options specified after a--
argument.
The following variables will be populated after parsing:
$opts->results # identical to the entire $results array above
$opts->options # smartly indexed array of options (see 'Flattened Options' below)
$opts->nonopts # identical to $results[1] above
$opts->breakopts # identical to $results[2] above
After parsing, the $opts->options
property will hold an array of values indexed based on the option used to specify them:
$flattened = array(
'name' => 'my_file',
'ext' => 'txt',
'content' => array('I love PHP!', 'Getopti rules!'),
'help' => FALSE
);
The following rules explain how the above options are organized:
- They are sorted based on the order in which they were set using the
$opts->on()
method. - Non-mulitple options (no
[+]
in the param string) are single values, whereas multiple allowed option's values can be accessed through an array (Notename
is single value andcontent
is an array). - If a long option is present, they will be indexed based on the long option. Otherwise, we use the short option.
- Uncalled options will be set to
FALSE
unless a default was given (note that neither-h
,--help
or--ext
was called in the arguments from the example above). - If the option accepts a parameter, it can be specified multiple times. If it doesn't accept a parameter, it will either be set to
TRUE
(indicated in the arguments) orFALSE
(not indicated).
In PHP 5.3, you can pass closures (anonymous functions) as parameters to other functions so that they may be used as callbacks. This is one of the reasons Getopti requires PHP 5.3.
Here's an example of how to use closures/callbacks with Getopti (or, for that matter, any PHP application):
<?php
class Macintosh {
public $version = "10.7";
function __construct()
{
$opts = new Getopti();
// We must make a copy of $this and explicitly 'use' it
$self = $this;
$opts->on(array('v', 'version'), FALSE, 'show version',
function ($show) use ($self) {
echo "OS X {$self->version}";
}
);
$args = Getopti::read_args();
$opts->parse($args);
}
}
?>
For more information on closures, see:
- Removal of $this in closures
- Inheriting $this (a bug report, but shows why you must use copies of
$this
)
- Validations are needed (i.e. making sure the same option can only get set once, etc...).
- Much more documentation is needed (variables, constants, etc..)
- A few more tests are needed (run
phpunit Test/ && open build/coverage/index.html
for info on what needs testing) - Add functionality that would allow indicating which options are allowed to be specified multiple times. Something like "ITEM [+]" or "[ITEM] [+]" (see Mercurial's help output as an example).
Getopti is Copyright © 2011 Braden Schaeffer. It is free software, and may be redistributed under the terms specified in the LICENSE file.