One of my pet peeves is that no language I've used handles command-line arguments well. Everyone falls back to C's original argv indexed array of space-separated strings, even though there's decades-old conventions about the syntax of named arguments. There's some strong third-party libraries that make it easier, and the arcane getopt(), but nothing that's emerged as a standard. Since I'm doing a lot more PHP shell scripts these days, I decided to write a PHP CLI parser that met my requirements:
– Specify the arguments once. Duplication of information is ugly and error-prone, so I wanted to describe the arguments in just one place.
– Automated help. The usage description should be generated from the same specification that the parser uses so it stays up-to-date.
– Syntax checking. I want to be able to say which arguments are required, optional or switches, and have the parser enforce that, and catch any unexpected arguments too.
– Unnamed arguments. Commands like cat take a list of files with no argument name, I wanted those to be easily accessible.
– Optional defaults. It makes life a lot easier if you don't have to check to see if an argument was specified in the main script, so I wanted to ensure you could set defaults for missing optional arguments.
– Human-readable specification. getopt() is close to what I need, but as well as not generating a usage description, the syntax for describing the long and short arguments is a horrible mess of a string. I want the argument specification to make sense to anyone reading the code.
Here's the result, cliargs.php. To use it specify your arguments in the form:
array(
'<long name of argument>' => array(
'short' => '<single letter version of argument>',
'type' => <'switch' | 'optional' | 'required'>,
'description' => '<help text for the argument>',
'default' => '<value if this is an optional argument and it isn't specified>',
),
…
);
There's an example script in the package, and documentation in the readme.txt. The code is freely reusable with no restrictions; I'm just dreaming of a world where no one ever writes another CLI argument parser ever again.