View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFDEV:Zend Proposal Zone Template}

{zone-data:component-name}
Zend_Console_Getopt
{zone-data}

{zone-data:proposer-list}
[Bill Karwin|mailto:bill.k@zend.com]
{zone-data}

{zone-data:revision}
0.1 - Draft proposal
{zone-data}

{zone-data:overview}
Zend_Console_Getopt is an object-oriented component to parse command-line options for PHP scripts. This is not typically required for web applications, but it can be useful for scripts called at the command-line.
{zone-data}

{zone-data:references}
* [GNU Getopt|http://www.gnu.org/software/libc/manual/html_node/Getopt.html]
* [Pear Console_Getopt|http://www.go-pear.org/manual/en/package.console.console-getopt.php]
{zone-data}

{zone-data:requirements}
* Support short, single-letter options, e.g. "{{-a}}".
* Support clusters of short options, e.g. "{{-abc}}".
* Support long, multi-letter options, e.g. "{{--apple}}".
* Support parameters for options, e.g. "{{-a param}}".
* Support simple validation of parameters as words or integers.
* Support parameters as separate argument or combines with option, e.g. "{{--apple=param}}".
* Support option synonyms.
* Generate usage help message.
* Specify valid options in a declarative syntax.
* Support GNU Getopt syntax.
* Support more extensive syntax to declare synonyms, parameter types, and help messages.
* Signify end of parsable options with "{{--}}" argument.
* Allow extension to let users define their own syntax parser.
{zone-data}

{zone-data:dependencies}
* Zend_Exception
{zone-data}

{zone-data:operation}
Provide an object-oriented interface to allow application developers to specify options for a given application, and arguments from the command-line of the current invocation of the application. Presence and value of individual options are provided as magic object attributes, e.g. "{{$opts->_optionname_}}".

The result of this attribute is the value of the option's parameter, if any. Otherwise a true value is returned if the option takes no parameter but was given on the command-line.

Specifying options is done with a declarative syntax that defines one or more synonyms for an option, any parameters that may be given to the option, and a help string for the option. For example:

{code}
$opts = new Zend_Console_Getopt(array(
'apple|a' => 'Apple option',
'banana|b' => 'Banana option',
'pear|p=s' => 'Pear option with required parameter'
));
{code}

This means that {{\-\-apple}} and {{\-a}} are synonyms, and take no parameter. {{\-\-banana}} and {{\-b}} are synonyms, and take no parameter. {{\-\-pear}} and {{\-p}} are synonyms, and require ({{=}}) a string ({{s}}) parameter. Each of these rules is a key in an associative array, the values of which are the help strings for the respective option.

Any of the synonyms can be used as the magic object attributes. "{{$opts->apple}}" and "{{$opts->a}}" return the same result.

A shorter declarative syntax compatible with GNU getopt is supported. The GNU getopt short syntax supports only single-letter option names, only required string parameters, and no support for declaring help strings (though help strings can be added).

{code}
$opts = new Zend_Console_Getopt('abp:');
{code}

The object generates a usage text message, formatted for text output in case the user gives incorrect option arguments, or requests the usage help for reference. Help messages can be added to the GNU getopt short syntax with the {{addHelp()}} method (see use case later in this proposal).

Resolving the parsing of command-line arguments and validating them against the option rules declaration is done in a "lazy" fashion. That is, the parsing is not done until an object attribute is requested, or alternatively when the object method parse() is called directly. The lazy parsing step allows the application programmer to add more option rules, more arguments, and more help strings before the parsing is done (the parsing may generate exceptions, so it's useful to delay it until all rules, argument data, and help strings have been established).
{zone-data}

{zone-data:milestones}
Milestone 1: Working prototype checked into incubator
Milestone 2: Community & Zend Core team review
Milestone 3: Code & test review
Milestone 4: Write full documentation
Milestone 5: Approve and move to core library
{zone-data}

{zone-data:class-list}
* Zend_Console_Getopt
* Zend_Console_Getopt_Exception
{zone-data}

{zone-data:use-cases}

In these use-cases, an artificial ARGV array is passed to the constructor of Zend_Console_Getopt. In practice, the arguments come from the script's command-line argument array.

h3. Parsing short options

{code}
$argv = array('-a', '-p', 'p_arg');
$opts = new Zend_Console_Getopt('abp:', $argv);
echo $opts->a; // returns true
echo $opts->p; // returns 'p_arg'
{code}

h3. Parsing long options

{code}
$argv = array('-a', '-p', 'p_arg');
$opts = new Zend_Console_Getopt(array(
'apple|a' => 'Apple option',
'banana|b' => 'Banana option',
'pear|p=s' => 'Pear option with required parameter'
), $argv);
echo $opts->apple; // returns true
echo $opts->pear; // returns 'p_arg'
{code}

h3. Handling user errors

{code}
$argv = array('-a', '-p');
$opts = new Zend_Console_Getopt(array(
'apple|a' => 'Apple option',
'banana|b' => 'Banana option',
'pear|p=s' => 'Pear option with required parameter'
), $argv);
try {
echo $opts->apple;
} catch (Zend_Console_Getopt_Exception $e) {
echo $e->getMessage();
echo $e->getUsageMessage();
}

Returns:
Option "--pear" requires a string parameter.
Usage: <progname> [ options ]
--apple|a Apple option
--banana|b Banana option
--pear|p <string> Pear option with required parameter
{code}

Notice in the above example that querying the 'apple' option caused all options to be parsed, thus generating the exception regarding the incorrect usage of the 'pear' option.

h3. Adding option rules

{code}
$argv = array('--pear', 'pear_arg');
$opts = new Zend_Console_Getopt(
array(
'apple|a' => 'Apple option',
'banana|b' => 'Banana option'
), $argv);
echo $opts->pear; // throws exception, no such option

$opts->addRules(array('pear|p=s' => 'Pear option'));
echo $opts->pear; // returns 'pear_arg'
{code}

h3. Adding arguments

{code}
$argv = array('-a');
$opts = new Zend_Console_Getopt('abp:', $argv);
echo $opts->p; // returns NULL

$opts->addArguments(array('-p', 'p_arg'));
echo $opts->p; // returns 'p_arg'
{code}

h3. Adding help messages and getting the usage message

{code}
$argv = array('-a');
$opts = new Zend_Console_Getopt('abp:', $argv);
$opts->setHelp(array(
'a' => 'Apple option',
'b' => 'Banana option',
'p' => 'Pear option'));
echo $opts->getUsageMessage();

Returns:
Usage: <progname> [ options ]
-a Apple option
-b Banana option
-p <string> Pear option
{code}

h3. Adding synonyms (aliases)

{code}
$argv = array('--apple');
$opts = new Zend_Console_Getopt('abp:', $argv);
$opts->setAliases(array('a' => 'apple'));
echo $opts->a; // returns true
{code}

h3. Dumping options as a string

{code}
$argv = array('-a', '-p', 'p_arg');
$opts = new Zend_Console_Getopt('abp:', $argv);
echo $opts->dumpString();

Returns:
a=true p=p_arg
{code}

h3. Dumping options as Json

{code}
$argv = array('-a', '-p', 'p_arg');
$opts = new Zend_Console_Getopt('abp:', $argv);
echo $opts->dumpJson();

Returns:
{
"options": {
"option": [
{ "flag": "a" },
{ "flag": "p", "parameter": "p_arg" }
]
}
}
{code}

h3. Dumping options as XML

{code}
$argv = array('-a', '-p', 'p_arg');
$opts = new Zend_Console_Getopt('abp:', $argv);
echo $opts->dumpXml();

Returns:
<options>
<option flag="a" />
<option flag="p" parameter="p_arg" />
</options>
{code}

{zone-data}

{zone-data:skeletons}
{code}
<?php

class Zend_Console_Getopt
{
/**
* The constructor takes one to three parameters.
*
* The first parameter is $rules, which may be a string for
* gnu-style format, or a structured array for Zend-style format.
*
* The second parameter is $argv, and it is optional. If not
* specified, $argv is inferred from the global argv.
*
* The third parameter is an array of configuration parameters
* to control the behavior of this instance of Getopt; it is optional.
*
* @param array $rules
* @param array $argv
* @param array $getoptConfig
* @throws Zend_Console_Getopt_Exception
* @return Zend_Console_Getopt
*/
public function __construct($rules, $argv = NULL, $getoptConfig = array());

/**
* Return the state of the option seen on the command line of the
* current application invocation. This function returns true, or the
* parameter to the option, if any. If the option was not given,
* this function returns NULL.
*
* The magic __get method works in the context of naming the option
* as a virtual member of this class.
*
* @param string $key
* @return string
*/
protected function __get($key);

/**
* Test whether a given option has been seen.
*
* @param string $key
* @return bool
*/
protected function __isset($key);

/**
* Set the value for a given option.
*
* @param string $key
* @param string $value
*/
protected function __set($key, $value);

/**
* Return the current set of options and parameters seen as a string.
*
* @return string
*/
public function __toString();

/**
* Unset an option.
*
* @param string $key
*/
public function __unset($key);

/**
* Define additional command-line arguments.
* These are appended to those defined when the constructor was called.
*
* @param array $argv
*/
public function addArguments($argv);

/**
* Define full set of command-line arguments.
* These replace any currently defined.
*
* @param array $argv
*/
public function setArguments($argv);

/**
* Define additional option rules.
* These are appended to the rules defined when the constructor was called.
*
* @param array $rules
* @throws Zend_Console_Getopt_Exception
*/
public function addRules($rules);

/**
* Return the current set of options and parameters seen as a string.
*
* @throws Zend_Console_Getopt_Exception
* @return string
*/
public function dumpString();

/**
* Return the current set of options and parameters seen
* as an array of canonical options and parameters.
*
* Clusters have been expanded, and option aliases
* have been mapped to their primary option names.
*
* @throws Zend_Console_Getopt_Exception
* @return array
*/
public function dumpOptions();

/**
* Return the current set of options and parameters seen in Json format.
*
* @throws Zend_Console_Getopt_Exception
* @return string
*/
public function dumpJson();

/**
* Return the current set of options and parameters seen in XML format.
*
* @throws Zend_Console_Getopt_Exception
* @return string
*/
public function dumpXml();

/**
* Return a list of options that have been seen in the current argv.
*
* @throws Zend_Console_Getopt_Exception
* @return array
*/
public function getOptions();

/**
* Return the state of the option seen on the command line of the
* current application invocation.
*
* This function returns true, or the parameter value to the option, if any.
* If the option was not given, this function returns false.
*
* @param string $key
* @throws Zend_Console_Getopt_Exception
* @return mixed
*/
public function getOption($flag);

/**
* Return the arguments from the command-line following all options found.
*
* @throws Zend_Console_Getopt_Exception
* @return array
*/
public function getRemainingArgs();

/**
* Return a useful option reference, formatted for display in an
* error message.
*
* Note that this usage information is provided in most Exceptions
* generated by this class.
*
* @return string
*/
public function getUsageMessage();

/**
* Define aliases for options.
*
* The parameter $aliasMap is an associative array
* mapping option name (short or long) to an alias.
*
* @param array $aliasMap
* @throws Zend_Console_Getopt_Exception
*/
public function setAliases($aliasMap);

/**
* Define help messages for options.
*
* The parameter $help_map is an associative array
* mapping option name (short or long) to the help string.
*
* @param array $helpMap
*/
public function setHelp($helpMap);

/**
* Parse command-line arguments and find both long and short
* options.
*
* Also find option parameters, and remaining arguments after
* all options have been parsed.
*
* @throws Zend_Console_Getopt_Exception
*/
public function parse();

/**
* Parse command-line arguments for a single long option.
* A long option is preceded by a double '--' character.
* Long options may not be clustered.
*
* @param mixed &$argv
* @throws Zend_Console_Getopt_Exception
*/
protected function parseLongOption(&$argv);

/**
* Parse command-line arguments for short options.
* Short options are those preceded by a single '-' character.
* Short options may be clustered.
*
* @param mixed &$argv
* @throws Zend_Console_Getopt_Exception
*/
protected function parseShortOptionCluster(&$argv);

/**
* Parse command-line arguments for a single option.
*
* @param string $flag
* @param mixed $argv
* @throws Zend_Console_Getopt_Exception
*/
protected function parseSingleOption($flag, &$argv);

/**
* Return true if the parameter is in a valid format for
* the option $flag.
* Throw an exception in most other cases.
*
* @param string $flag
* @param string $param
* @throws Zend_Console_Getopt_Exception
*/
protected function checkParameterType($flag, $param);

/**
* Define legal options using the gnu-style format.
*
* @param string $rules
*/
protected function addRulesModeGnu($rules);

/**
* Define legal options using the Zend-style format.
*
* @param array $rules
* @throws Zend_Console_Getopt_Exception
*/
protected function addRulesModeZend($rules);

}

class Zend_Console_Getopt_Exception extends Zend_Exception
{
public function __construct($message, $usage = '');

public function getUsageMessage();
}
{code}

{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>