Garden CLI is a PHP command line interface library meant to provide a full set of functionality with a clean and simple api.
PHP's getopt()
provides little functionality and is prone to failure where one typo in your command line options can wreck and entire command call. Garden CLI solves this problem and provides additional functionality.
- Your commands get automatic support for
--help
to print out help for your commands. - Support a single command or multiple commands. (ex. git pull, git push, etc.)
- Have command options parsed and validated with error information automatically printed out.
- A simple, elegant syntax so that even your most basic command line scripts will take little effort to implement robust parsing.
Garden CLI requires PHP 5.4 or higher
Garden CLI is PSR-4 compliant and can be installed using composer. Just add vanilla/garden-cli
to your composer.json.
"require": {
"vanilla/garden-cli": "~1.0"
}
Here is a basic example of a command line script that uses Garden CLI to parse its options. Let's say you are writing a script called dbdump.php
to dump some data from your database.
<?php
// All of the command line classes are in the Garden\Cli namespace.
use Garden\Cli\Cli;
// Require composer's autoloader.
require_once 'vendor/autoload.php';
// Define the cli options.
$cli = new Cli();
$cli->description('Dump some information from your database.')
->opt('host:h', 'Connect to host.', true)
->opt('port:P', 'Port number to use.', false, 'integer')
->opt('user:u', 'User for login if not current user.', true)
->opt('password:p', 'Password to use when connecting to server.')
->opt('database:d', 'The name of the database to dump.', true);
// Parse and return cli args.
$args = $cli->parse($argv, true);
This example returns an Args
object or exits to show help or an error message. Here are some things to note about the example.
- You can throw an exception instead of exiting by passing
false
as the second argument toparse()
. - The
opt()
method has the following parameters:name
,description
,required
, andtype
. Most parameters have sensible defaults. - If you want your option to have a short code then specify in with
name
argument separated by a colon. - If you specify a short code for an option this will act like an alias for the parameter name in
$argv
only. You always access an option by its full name after parsing.
If you were to call the basic example with a --help
option then you'd see the following help printed:
usage: dbdump.php [<options>] Dump some information from your database. OPTIONS --database, -d The name of the database to dump. --help, -? Display this help. --host, -h Connect to host. --password, -p Password to use when connecting to server. --port, -P Port number to use. --user, -u User for login if not current user.
All of the options are printed in a compact table and required options are printed in bold. The table will automatically expand to accommodate longer option names and wrap if you provide extra long descriptions.
Let's say you call the basic example with just -P foo
. What you'd see is the following error message:
The value of --port (-P) is not a valid integer. Missing required option: database Missing required option: user
Once you've successfully parsed the $argv
using Cli->parse($argv)
you can use the various methods on the returned Args
object.
$args = $cli->parse($argv);
$host = $args->getOpt('host', '127.0.0.1'); // get host with default 127.0.0.1
$user = $args->getOpt('user'); // get user
$database = $args['database']; // use the args like an array too
$port = $args->getOpt('port', 123); // get port with default 123
Let's say you are writing a git-like command line utility called nit.php
that pushes and pulls information from a remote repository.
// Define a cli with commands.
$cli = Cli::create()
// Define the first command: push.
->command('push')
->description('Push data to a remote server.')
->opt('force', 'Force an overwrite.', false, 'boolean', 'f')
->opt('set-upstream', 'Add a reference to the upstream repo.', false, 'boolean', 'u')
// Define the second command: pull.
->command('pull')
->description('Pull data from a remote server.')
->opt('commit', 'Perform the merge and commit the result.', false, 'boolean')
// Set some global options.
->command('*')
->opt('verbose', 'Output verbose information.', false, 'boolean', 'v')
->arg('repo', 'The repository to sync with.', true);
$args = $cli->parse($argv);
Like the basic example, parse()
will return a Args
object on a successful parse. Here are some things to note about this example.
- The
Cli::create()
method is provided if you want to have a 100% fluent interface when defining your command schema. - Call the
command()
method to define a new command. - If you call
command('*')
then you can define options that are global to all commands. - The
arg()
method lets you define arguments that go after the options on the command line. More on this below.
Calling a script that has commands with no options or just the --help
option will display a list of commands. Here is the output from the multiple commands example above.
usage: nit.php [<options>] [<args>] COMMANDS push Push data to a remote server. pull Pull data from a remote server.
##Args and Opts
The Args
class differentiates between args and opts. There are methods to access both opts and args on that class.
- Opts are passed by
--name
full name or-s
short code. They are named and can have types. - Args are passed after the options as just strings separated by spaces.
- When calling a script from the command line you can use
--
to separate opts from args if there is ambiguity.