Docopt.php
Command line argument parser
Install / Use
/learn @docopt/Docopt.phpREADME
docopt creates beautiful command-line interfaces
.. image:: https://travis-ci.org/docopt/docopt.php.svg?branch=master :target: https://travis-ci.org/docopt/docopt.php
This is a straight PHP transliteration of Vladimir Keleshev's brilliant
docopt <https://github.com/docopt/docopt/>_ Python library. There are a
few artefacts in the code as a result that may seem inefficient and
non-idiomatic to PHP, this has been done to make integrating changes more
efficient.
As a result, unless a bug is present only in the PHP version, pull requests are unlikely to be accepted unless they are themselves direct transliterations of bugfixes in the Python version.
This port has been marked version 1.0. It is based on the Python version at
commit a093f938b7f26564434f3c15a1dcc39e017ad638 <https://github.com/docopt/docopt/commit/a093f938b7f26564434f3c15a1dcc39e017ad638>_
(labelled 0.6.2).
It has been quite stable for a long time and has barely been changed. The Python version receives only occasional bugfixes and keeping the version numbers pinned has been more trouble than it has been worth.
There are also some major backward compatibility breaks. Rather than dwell in 0.x semver hell, the PHP port will liberally bump major numbers henceforth when BC breaks regardless of the reason.
-
The PHP API has changed slightly.
Docopt\docopt()has been renamed toDocopt::handle()to fix autoloader support. Seeissue #3 <https://github.com/docopt/docopt.php/pull/3>_. -
Docopt.py also has a significant BC break. Existing users should read the information below about Usage and Option sections. See
issue 102 <https://github.com/docopt/docopt/issues/102>_ for more info.
Please see the Python version's README <https://github.com/docopt/docopt/blob/master/README.rst>_
for details of any new and breaking changes that are not specific to the PHP version.
There is also at least one significant known issue with the upstream Python version. Due to the porting strategy used for the PHP version, it inherits the bug surface of the Python version (and if it doesn't, that's actually a bug!):
- Issues with multi-word argument and option values (
PHP report <https://github.com/docopt/docopt.php/issues/21>,Upstream report <https://github.com/docopt/docopt/issues/207>)
Isn't it awesome how optparse and argparse generate help
messages based on your code?!
Hell no! You know what's awesome? It's when the option parser is generated based on the beautiful help message that you write yourself! This way you don't need to write this stupid repeatable parser-code, and instead can write only the help message--the way you want it.
docopt helps you create most beautiful command-line interfaces easily:
.. code:: php
<?php
$doc = <<<DOC
Naval Fate.
Usage:
naval_fate.php ship new <name>...
naval_fate.php ship <name> move <x> <y> [--speed=<kn>]
naval_fate.php ship shoot <x> <y>
naval_fate.php mine (set|remove) <x> <y> [--moored | --drifting]
naval_fate.php (-h | --help)
naval_fate.php --version
Options:
-h --help Show this screen.
--version Show version.
--speed=<kn> Speed in knots [default: 10].
--moored Moored (anchored) mine.
--drifting Drifting mine.
DOC;
require('path/to/src/docopt.php');
$args = Docopt::handle($doc, array('version'=>'Naval Fate 2.0'));
foreach ($args as $k=>$v)
echo $k.': '.json_encode($v).PHP_EOL;
Beat that! The option parser is generated based on the docstring above
that is passed to docopt function. docopt parses the usage
pattern ("Usage: ...") and option descriptions (lines starting
with dash "-") and ensures that the program invocation matches the
usage pattern; it parses options, arguments and commands based on
that. The basic idea is that a good help message has all necessary
information in it to make a parser.
Installation
Install docopt.php using Composer <http://getcomposer.org>_::
composer require docopt/docopt
Alternatively, you can just drop docopt.php file into your project--it is
self-contained. Get source on github <http://github.com/docopt/docopt.php>_.
docopt.php is tested with PHP 7; it should still work with PHP 5.3+ but this support
will become increasingly fragile and will at some point cease to be supported at all. You
should update to 7 as soon as you can.
Testing
Configure your repo for running tests::
./dev-setup
You can run unit tests with the following command::
php test.php
This will run the Python language agnostic tests as well as the PHP docopt tests.
API
.. code:: php
<?php
require('/path/to/src/docopt.php');
// short form, simple API
$args = Docopt::handle($doc);
// short form (5.4 or better)
$args = (new \Docopt\Handler)->handle($sdoc);
// long form, simple API (equivalent to short)
$params = array(
'argv'=>array_slice($_SERVER['argv'], 1),
'help'=>true,
'version'=>null,
'optionsFirst'=>false,
);
$args = Docopt::handle($doc, $params);
// long form, full API
$handler = new \Docopt\Handler(array(
'help'=>true,
'optionsFirst'=>false,
));
$handler->handle($doc, $argv);
Docopt::handle() takes 1 required and 1 optional argument:
docis a string that contains a help message that will be parsed to create the option parser. The simple rules of how to write such a help message are given in next sections. Here is a quick example of such a string:
.. code:: php
<?php
$doc = <<<DOC
Usage: my_program.php [-hso FILE] [--quiet | --verbose] [INPUT ...]
Options:
-h --help show this
-s --sorted sorted output
-o FILE specify output file [default: ./test.txt]
--quiet print less text
--verbose print more text
DOC;
-
paramsis an optional array of additional data to influencedocopt. The following keys are supported:-
argvis an optional argument vector; by defaultdocoptuses the argument vector passed to your program ($_SERVER['argv']). Alternatively you can supply a list of strings likearray('--verbose', '-o', 'hai.txt'). -
help, by defaulttrue, specifies whether the parser should automatically print the help message (supplied asdoc) and terminate, in case-hor--helpoption is encountered (options should exist in usage pattern, more on that below). If you want to handle-hor--helpoptions manually (as other options), sethelptofalse. -
version, by defaultnull, is an optional argument that specifies the version of your program. If supplied, then, (assuming--versionoption is mentioned in usage pattern) when parser encounters the--versionoption, it will print the supplied version and terminate.versioncould be any printable object, but most likely a string, e.g."2.1.0rc1".Note, when
docoptis set to automatically handle-h,--helpand--versionoptions, you still need to mention them in usage pattern for this to work. Also, for your users to know about them. -
optionsFirst, by defaultfalse. If set totruewill disallow mixing options and positional argument. I.e. after first positional argument, all arguments will be interpreted as positional even if the look like options. This can be used for strict compatibility with POSIX, or if you want to dispatch your arguments to other programs.
-
Docopt\Handler->handle() takes one required argument:
docis a string that contains a help message that will be parsed to create the option parser. The simple rules of how to write such a help message are given in next sections. Here is a quick example of such a string:
.. code:: php
<?php
$doc = <<<DOC
Usage: my_program.php [-hso FILE] [--quiet | --verbose] [INPUT ...]
-h --help show this
-s --sorted sorted output
-o FILE specify output file [default: ./test.txt]
--quiet print less text
--verbose print more text
DOC;
The return value of handle() is a simple associative array with
options, arguments and commands as keys, spelled exactly like in your
help message. Long versions of options are given priority. For example,
if you invoke the top example as::
naval_fate.php ship Guardian move 100 150 --speed=15
the return dictionary will be:
.. code:: php
<?php
array(
'--drifting'=>false, 'mine'=>false,
'--help'=>false, 'move'=>true,
'--moored'=>false, 'new'=>false,
'--speed'=>'15', 'remove'=>false,
'--version'=>false, 'set'=>false,
'<name>'=>array('Guardian'), 'ship'=>true,
'<x>'=>'100', 'shoot'=>false,
'<y>'=>'150'
);
Help message format
Help message consists of 2 sections:
-
Usage section, starting with
Usage:e.g.::Usage: my_program.php [-hso FILE] [--quiet | --verbose] [INPUT ...]
-
Option section, starting with
Options:e.g.::Options: -h --help show this -s --sorted sorted output -o FILE specify output file [default: ./test.txt] --quiet print less text --verbose print more text
Sections consist of a header and a body. The section b
