Easier command-line arguments in PHP

Arguments
Photo by Between a Rock

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.

Leave a comment