An object-oriented option parser library for PHP, which supports type constraints, flag, multiple flag, multiple values, required value checking

Overview

GetOptionKit

Code Quality

Build Status Coverage Status

Versions & Stats

Latest Stable Version Latest Unstable Version Total Downloads Monthly Downloads Daily Downloads License

A powerful option parser toolkit for PHP, supporting type constraints, flag, multiple flag, multiple values and required value checking.

GetOptionKit supports PHP5.3, with fine unit testing with PHPUnit testing framework.

GetOptionKit is object-oriented, it's flexible and extendable.

Powering PHPBrew https://github.com/phpbrew/phpbrew, CLIFramework https://github.com/c9s/CLIFramework and AssetKit https://github.com/c9s/AssetKit

Features

  • Simple format.
  • Type constrant.
  • Multiple value, requried value, optional value checking.
  • Auto-generated help text from defined options.
  • Support app/subcommand option parsing.
  • Option Value Validator
  • Option Suggestions
  • SPL library.
  • HHVM support.

Requirements

  • PHP 5.3+

Install From Composer

composer require corneltek/getoptionkit

Supported Option Formats

simple flags:

program.php -a -b -c
program.php -abc
program.php -vvv   # incremental flag v=3
program.php -a -bc

with multiple values:

program.php -a foo -a bar -a zoo -b -b -b

specify value with equal sign:

program.php -a=foo
program.php --long=foo

with normal arguments:

program.php -a=foo -b=bar arg1 arg2 arg3
program.php arg1 arg2 arg3 -a=foo -b=bar

Option SPEC

v|verbose    flag option (with boolean value true)
d|dir:       option require a value (MUST require)
d|dir+       option with multiple values.
d|dir?       option with optional value
dir:=string  option with type constraint of string
dir:=number  option with type constraint of number
dir:=file    option with type constraint of file
dir:=date    option with type constraint of date
dir:=boolean option with type constraint of boolean
d            single character only option
dir          long option name

Command Line Forms

app [app-opts] [app arguments]

app [app-opts] subcommand [subcommand-opts] [subcommand-args]

app [app-opts] subcmd1 [subcmd-opts1] subcmd2 [subcmd-opts] subcmd3 [subcmd-opts3] [subcommand arguments....]

Documentation

See more details in the documentation

Demo

Please check examples/demo.php.

Run:

% php examples/demo.php -f test -b 123 -b 333

Print:

* Available options:
      -f, --foo 
   
        option requires a value.
     -b, --bar 
    
     +    option with multiple value.
    -z, --zoo [
     
      ]    option with optional value.
          -v, --verbose    verbose message.
            -d, --debug    debug message.
                 --long    long option name only.
                     -s    short option name only.
Enabled options: 
* key:foo      spec:-f, --foo 
      
         desc:option requires a value.
    value => test

* key:bar      spec:-b, --bar 
       
        + desc:option with multiple value. Array ( [0] => 123 [1] => 333 ) 
       
      
     
    
   

Synopsis

parse( $argv ); foreach ($result->keys as $key => $spec) { print_r($spec); } $opt = $result->keys['foo']; // return the option object. $str = $result->keys['foo']->value; // return the option value print_r($opt); var_dump($str); } catch( Exception $e ) { echo $e->getMessage(); }">
use GetOptionKit\OptionCollection;
use GetOptionKit\OptionParser;
use GetOptionKit\OptionPrinter\ConsoleOptionPrinter;

$specs = new OptionCollection;
$specs->add('f|foo:', 'option requires a value.' )
    ->isa('String');

$specs->add('b|bar+', 'option with multiple value.' )
    ->isa('Number');

$specs->add('ip+', 'Ip constraint' )
    ->isa('Ip');

$specs->add('email+', 'Email address constraint' )
    ->isa('Email');

$specs->add('z|zoo?', 'option with optional value.' )
    ->isa('Boolean');

$specs->add('file:', 'option value should be a file.' )
    ->isa('File');

$specs->add('v|verbose', 'verbose message.' );
$specs->add('d|debug', 'debug message.' );
$specs->add('long', 'long option name only.' );
$specs->add('s', 'short option name only.' );

$printer = new ConsoleOptionPrinter();
echo $printer->render($specs);

$parser = new OptionParser($specs);

echo "Enabled options: \n";
try {
    $result = $parser->parse( $argv );
    foreach ($result->keys as $key => $spec) {
        print_r($spec);
    }

    $opt = $result->keys['foo']; // return the option object.
    $str = $result->keys['foo']->value; // return the option value
    
    print_r($opt);
    var_dump($str);
    
} catch( Exception $e ) {
    echo $e->getMessage();
}

Documentation

See https://github.com/c9s/GetOptionKit/wiki for more details.

Option Value Type

The option value type help you validate the input, the following list is the current supported types:

  • string
  • number
  • boolean
  • file
  • date
  • url
  • email
  • ip
  • ipv4
  • ipv6
  • regex

And here is the related sample code:

$opt->add( 'f|foo:' , 'with string type value' )
    ->isa('string');

$opt->add( 'b|bar+' , 'with number type value' )
    ->isa('number');

$opt->add( 'z|zoo?' , 'with boolean type value' )
    ->isa('boolean');

$opt->add( 'file:' , 'with file type value' )
    ->isa('file');

$opt->add( 'date:' , 'with date type value' )
    ->isa('date');

$opt->add( 'url:' , 'with url type value' )
    ->isa('url');

$opt->add( 'email:' , 'with email type value' )
    ->isa('email');

$opt->add( 'ip:' , 'with ip(v4/v6) type value' )
    ->isa('ip');

$opt->add( 'ipv4:' , 'with ipv4 type value' )
    ->isa('ipv4');

$opt->add( 'ipv6:' , 'with ipv6 type value' )
    ->isa('ipv6');

$specs->add('r|regex:', 'with custom regex type value')
      ->isa('Regex', '/^([a-z]+)$/');

Please note that currently only string, number, boolean types can be validated.

ContinuousOptionParser

$specs = new OptionCollection;
$spec_verbose = $specs->add('v|verbose');
$spec_color = $specs->add('c|color');
$spec_debug = $specs->add('d|debug');
$spec_verbose->description = 'verbose flag';

// ContinuousOptionParser
$parser = new ContinuousOptionParser( $specs );
$result = $parser->parse(explode(' ','program -v -d test -a -b -c subcommand -e -f -g subcommand2'));
$result2 = $parser->continueParse();

OptionPrinter

GetOptionKit\OptionPrinter can print options for you:

* Available options:
              -f, --foo   option requires a value.
              -b, --bar   option with multiple value.
              -z, --zoo   option with optional value.
          -v, --verbose   verbose message.
            -d, --debug   debug message.
                 --long   long option name only.
                     -s   short option name only.

Command-line app with subcommands

For application with subcommands is designed by following form:

[app name] [app opts] 
             [subcommand1] [subcommand-opts]
             [subcommand2] [subcommand-opts]
             [subcommand3] [subcommand-opts]
             [arguments]

You can check the tests/GetOptionKit/ContinuousOptionParserTest.php unit test file:

// subcommand stack
$subcommands = array('subcommand1','subcommand2','subcommand3');

// different command has its own options
$subcommandSpecs = array(
    'subcommand1' => $cmdspecs,
    'subcommand2' => $cmdspecs,
    'subcommand3' => $cmdspecs,
);

// for saved options
$subcommandOptions = array();

// command arguments
$arguments = array();

$argv = explode(' ','program -v -d -c subcommand1 -a -b -c subcommand2 -c subcommand3 arg1 arg2 arg3');

// parse application options first
$parser = new ContinuousOptionParser( $appspecs );
$app_options = $parser->parse( $argv );
while (! $parser->isEnd()) {
    if (@$subcommands[0] && $parser->getCurrentArgument() == $subcommands[0]) {
        $parser->advance();
        $subcommand = array_shift( $subcommands );
        $parser->setSpecs( $subcommandSpecs[$subcommand] );
        $subcommandOptions[ $subcommand ] = $parser->continueParse();
    } else {
        $arguments[] = $parser->advance();
    }
}

Todo

  • Option Spec group.
  • option valid value checking.
  • custom command mapping.

Command Line Utility Design Concept

  • main program name should be easy to type, easy to remember.
  • subcommand should be easy to type, easy to remember. length should be shorter than 7 characters.
  • options should always have long descriptive name
  • a program should be easy to check usage.

General command interface

To list usage of all subcommands or the program itself:

$ prog help

To list the subcommand usage

$ prog help subcommand subcommand2 subcommand3

Hacking

Fork this repository and clone it:

$ git clone git://github.com/c9s/GetOptionKit.git
$ cd GetOptionKit
$ composer install

Run PHPUnit to test:

$ phpunit 

License

This project is released under MIT License.

Comments
  • [BUG] ContinuousOptionParser fail to parse multiple  --option=value

    [BUG] ContinuousOptionParser fail to parse multiple --option=value

    Please test using this command, it will fail

    "script.php subcommand --data=thedata --limit=30 --batch=10 --index=theindex argument1 argument2"
    

    The parser only parse data, limit, and batch, and ignoring the rest (index, argument1, argument2 is not parsed

    opened by jeffreycahyono 21
  • Can not enter negative numbers

    Can not enter negative numbers

    If number begins with -, it is treated as an option. Current workaround: use something like: -o " -1" because -o "-1" will not work.

    Bug 
    opened by vasek125 10
  • Passing multiple short options is not working

    Passing multiple short options is not working

    If I have multiple short options in my command and I pass them like -mv I'll just get the first one as a passed option. Using -l -v works.

    Also, using -vm4 does the same, while it should give me the v option as boolean, and m as 4. Doing -m4v gives me m without the value as well, and nothing else.

    Bug 
    opened by igorsantos07 9
  • Quoted string arguments and spaces

    Quoted string arguments and spaces

    The library doesn't appear to support arguments such as

    command --option="foo bar baz"
    

    This becomes

    ['"foo', 'bar', 'baz"']
    

    ...rather than

    ['foo bar baz']
    

    Is this something that you are planning to/want to implement?

    Bug 
    opened by mrchimp 8
  • Enable custom validator on Option

    Enable custom validator on Option

    The customer validator you could set on an Option wasn't triggered during option parsing, this required you to call $option->validate($option->value)) manually, which is cumbersome and counterintuitive.

    Sidenote: I noticed PHPUnit wasn't included as a dependency in composer.json, any reason for that? It's hard to run the unit tests that way ;-)

    opened by ErikBooij 7
  • No documentation on

    No documentation on "normal" arguments

    Read-me mentions ability to mix with normal arguments here:

    https://github.com/c9s/GetOptionKit#supported-option-formats

    However I can't find a way to implement this:

    myapp [ -s <system_id> ] file.txt
    

    I was expecting than parser would remove all arguments from parameter leaving normal arguments inside, but it's not happening.

    opened by romaninsh 7
  • Check for required value is now validates emptiness of next argument

    Check for required value is now validates emptiness of next argument

    Hi. There was an issue with checking required value:

    1. Write in your php script $GetOptionKit->add('t|test:', 'required value');
    2. Run it as follows: ./script --test
    3. There is no exception on parsing args.
    4. There, I fixed it!)

    P.S. If I've misunderstood concept of 'option requires a value.', I'm sorry.

    opened by dlussky 7
  • Validator isn't triggered

    Validator isn't triggered

    Hi! I really like the library you've created for parsing CLI arguments, but I'm running into an issue. I'm probably just using it wrong, but maybe you can clarify.

    I'm trying to add a validator to an option, to make sure the option is an existing and readable file. I was assuming it would work something like this:

    $specs
        ->add('c|candidates:', 'Candidates file')
        ->validator(function($option) {
            return file_exists($option) && is_readable($option);
        });
    

    But it doesn't. The validate function is used nowhere in the entire library (according to PHPStorm), so I figured I needed to trigger it myself, but doing this seems unnecessarily complicated:

    $option->validate($option->value)
    

    If it should actually automatically validate, I'll be more than happy to create a PR and change it, but I wanted to check first if this is not just the intended behaviour.

    opened by ErikBooij 4
  • unclear how to actually get value

    unclear how to actually get value

    Coming from a getopt I expect that calling this:

    shell> php example.php -fvalue -h
    

    and using parse() would give me something like:

    array(2) {
      ["f"]=>
      string(5) "value"
      ["h"]=>
      bool(false)
    }
    

    However parse() responds with spec definitions strings:

    $result = $parser->parse($argv);
    echo 's is '.$result['f']."\n";
    

    While it's handy for a demo, it's unclear how to actually get the value. My final working snippet looks like this:

    $specs = new \GetOptionKit\OptionCollection;
    $specs->add('f:', 'value of f' );
    $parser = new \GetOptionKit\OptionParser($specs);
    $result = $parser->parse($argv)->toArray();
    echo 'f is '.$result['f']."\n";
    

    but it took some poking in the code to arrive at this.

    opened by romaninsh 4
  • isa('Number') is not worknig.

    isa('Number') is not worknig.

    Documentation is inconsistent about 'number' vs 'Number': https://github.com/c9s/GetOptionKit/search?utf8=✓&q=isa

    $specs->add('s|system', 'Select system by ID' )->isa('Number');
    

    Orange-Dream:tools rw$ php importer.php -s 123 -s, --system= Select system by ID

    PHP Fatal error: Uncaught GetOptionKit\InvalidOptionValue: Invalid value for -s, --system. Requires a type Number. in /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/Option.php:264 Stack trace: #0 /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/Option.php(297): GetOptionKit\Option->_preprocessValue(true) #1 /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/OptionParser.php(48): GetOptionKit\Option->setValue(true) #2 /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/OptionParser.php(172): GetOptionKit\OptionParser->consumeOptionToken(Object(GetOptionKit\Option), Object(GetOptionKit\Argument), Object(GetOptionKit\Argument)) #3 /Users/rw/Sites/smbo/old/tools/importer.php(32): GetOptionKit\OptionParser->parse(Array) #4 {main}

    thrown in /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/Option.php on line 264

    Fatal error: Uncaught GetOptionKit\InvalidOptionValue: Invalid value for -s, --system. Requires a type Number. in /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/Option.php on line 264

    GetOptionKit\InvalidOptionValue: Invalid value for -s, --system. Requires a type Number. in /Users/rw/Sites/smbo/old/vendor/corneltek/getoptionkit/src/Option.php on line 264

    opened by romaninsh 4
  • Arguments aren't consumed for

    Arguments aren't consumed for "multiple" options

    When defining a "single" option (e.g. foo:=string), that option's argument will be consumed and not returned with the remaining arguments from getArguments(), but a "multiple" option (e.g. bar+=string) does not consume its argument and leaves it with the rest of the arguments returned by getArguments().

    $specs = new \GetOptionKit\OptionCollection();
    $specs->add('test1+=string', 'Test 1');
    $specs->add('test2:=string', 'Test 2');
    
    $parser = new \GetOptionKit\OptionParser($specs);
    
    $result = $parser->parse(explode(' ', '--test1 opt1 --test2 opt2 arg1 arg2'));
    
    $result->getArguments(); // => ["opt1", "arg1", "arg2"]
    

    Ideally, at least to the best of my knowledge, the arguments to a "multiple" option should be consumed and removed from the list returned by getArguments() so only ["arg1", "arg2"] would be returned in the above example.

    Bug 
    opened by lillesvin 4
  • Cannot install with composer: circular deprecation error

    Cannot install with composer: circular deprecation error

    Firstly, after skipping over dozen of alternatives, i was very happy to find this project - seems like what i was looking for!

    Unfortunately, i could not find a way to install it with composer: composer require c9s/GetOptionKit

    exits with the following error:

    Package c9s/GetOptionKit is abandoned, you should avoid using it. Use corneltek/getoptionkit instead.

    But trying to do that and typing

    composer require corneltek/getoptionkit

    results in the same message. Moreover, it seems like there is no "getoptionkit" repo under https://github.com/corneltek/

    So, i'd like to know whether is this project considered as completely abandoned and so the suggestion would be to not use it in new projects? Or are there any plans to publish a replacement for it or a successor?

    opened by arcijsg 0
  • Changelog

    Changelog

    Hi. I just tried to update from 2.0.3 to 2.0.9 and noticed, that you removed a public method:

    Call to undefined method GetOptionKit\OptionCollection::printOptions()

    Could you please maintain a changelog for breaking changes like this?) I see, that new behavior is reflected in example.php, and i like the new OptionPrinter, but it would be nice to have a brief changelog, at least a one line at release comment)

    opened by dlussky 14
Releases(2.7.0)
Owner
Yo-An Lin
a developer who really loves crafting tools
Yo-An Lin
A PHP parser for TOML

TOML parser for PHP A PHP parser for TOML compatible with TOML v0.4.0. Support: Installation Requires PHP >= 7.1. Use Composer to install this package

Yo! Symfony 175 Dec 26, 2022
Map request on your DTO object with zero configuration.

Map request on your DTO object with zero configuration. Install composer require prugala/symfony-request-dto Usage Create a DTO that implements the in

Piotr Rugala 16 Dec 30, 2022
PHP client library for the Square Connect APIs

Square Connect PHP SDK - RETIRED replaced by square/square-php-sdk NOTICE: Square Connect PHP SDK retired The Square Connect PHP SDK is retired (EOL)

Square 113 Dec 30, 2022
Simple yet expressive schema-based configuration library for PHP apps

league/config helps you define nested configuration arrays with strict schemas and access configuration values with dot notation.

The League of Extraordinary Packages 282 Jan 6, 2023
This library can parse a TypeSchema specification either from a JSON file, or from PHP classes using reflection and annotations.

This library can parse a TypeSchema specification either from a JSON file, or from PHP classes using reflection and annotations. Based on this schema it can generate source code and transform raw JSON data into DTO objects. Through this you can work with fully typed objects in your API for incoming and outgoing data.

Apioo 54 Jul 14, 2022
LOAD is a PHP library for configuration loading to APCu

LOAD LOAD is a PHP library for configuration loading to APCu Sources Available sources for configuration loading are: PHP file Consul Environment vari

Beat Labs 4 Jan 18, 2022
The VarDumper component provides mechanisms for walking through any arbitrary PHP variable. It provides a better dump() function that you can use instead of var_dump().

VarDumper Component The VarDumper component provides mechanisms for walking through any arbitrary PHP variable. It provides a better dump() function t

Symfony 7.1k Dec 23, 2022
A beautiful, fully open-source, tunneling service - written in pure PHP

Expose A completely open-source ngrok alternative - written in pure PHP. Documentation For installation instructions, in-depth usage and deployment de

Beyond Code 3.9k Dec 29, 2022
All PHP functions, rewritten to throw exceptions instead of returning false

Safe PHP This project is deprecated Because of how this project needs to be in sync with the official PHP documentation, maintaining a set of function

TheCodingMachine 2.1k Jan 2, 2023
An object-oriented option parser library for PHP, which supports type constraints, flag, multiple flag, multiple values, required value checking

GetOptionKit Code Quality Versions & Stats A powerful option parser toolkit for PHP, supporting type constraints, flag, multiple flag, multiple values

Yo-An Lin 140 Sep 28, 2022
A Symfony Feature Flag Bundle which easily allows you to configure and use your favorite feature flag provider.

Metro Markets FF Metro Markets FF is a Feature Flag Symfony Bundle. It easily allows you to configure and use your favorite feature flag provider. Ins

METRO Markets 14 May 23, 2022
Stop duplicating your Eloquent query scopes and constraints in PHP. This package lets you re-use your query scopes and constraints by adding them as a subquery.

Laravel Eloquent Scope as Select Stop duplicating your Eloquent query scopes and constraints in PHP. This package lets you re-use your query scopes an

Protone Media 75 Dec 7, 2022
WordPress entities creation library (CPT, CT, native option page, ACF option page, user role, block pattern category, block category…)

WordPress entities creation library (CPT, CT, native option page, ACF option page, user role, block pattern category, block category…)

Loïc Antignac 2 Jul 25, 2022
Value Object that represents a monetary value (using a currency's smallest unit).

This project has been abandoned. It was only ever intended to be used as an example for PHPUnit features etc. and not for usage in production. I am so

Sebastian Bergmann 735 Dec 30, 2022
Option Type for PHP

PHP Option Type This package implements the Option type for PHP! Motivation The Option type is intended for cases where you sometimes might return a v

Johannes 2.4k Dec 26, 2022
PHP Unoconv - An Object Oriented library which allow easy to use file conversion with Unoconv.

An Object Oriented library which allow easy to use file conversion with Unoconv. Install The recommended way to install PHP-Unoconv is thr

Alchemy 69 Dec 3, 2022
PHP Kafka client is used in PHP-FPM and Swoole. PHP Kafka client supports 50 APIs, which might be one that supports the most message types ever.

longlang/phpkafka Introduction English | 简体中文 PHP Kafka client is used in PHP-FPM and Swoole. The communication protocol is based on the JSON file in

Swoole Project 235 Dec 31, 2022
Highly-extensible PHP Markdown parser which fully supports the CommonMark and GFM specs.

league/commonmark league/commonmark is a highly-extensible PHP Markdown parser created by Colin O'Dell which supports the full CommonMark spec and Git

The League of Extraordinary Packages 2.4k Jan 1, 2023
Highly-extensible PHP Markdown parser which fully supports the CommonMark and GFM specs.

league/commonmark league/commonmark is a highly-extensible PHP Markdown parser created by Colin O'Dell which supports the full CommonMark spec and Git

The League of Extraordinary Packages 2.4k Dec 29, 2022