Last active
February 15, 2019 16:27
-
-
Save moechofe/4225616 to your computer and use it in GitHub Desktop.
Quick and effective command line parser for PHP using getopt().
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Parse the command line and fill variables. | |
* Params: | |
* array $opts = An associated array. Keys are the option names. | |
* Values are the references to variables that receive the values from the command lines. | |
* Nothing is returned but when values of the array $opts are passed by reference, they will contain the | |
* values extracted from the command line. | |
* Keys must be string. | |
* - "verbose" Allow long option. | |
* - "v" Allow short option. | |
* - "verbose|v" Allow long and short option. | |
* - Add the suffix "?" to indiquate that the value is optional. | |
* Values must be passed by reference, otherwise no value can be extracted from the command line. | |
* Values can be Closure. They will be call if the option is present in the command line. | |
* ---- | |
* $verbose = null; // No value need for this argument. | |
* $output = ''; // Wait for a string value. | |
* $inputs = array(); // Can receive more than one value. | |
* qad\arg\parse(array( | |
* 'v' => &$verbose, | |
* 'output|o' => &$output, | |
* 'input|i' => &$input, | |
* 'whatever' => function($val){var_dump($val);} )); | |
* var_dump($verbose, $output, $input); | |
* ---- | |
* array $args = When provided, will be filled by the arguments. Compared to an option, an argument as no name. | |
* Source: https://gist.github.com/4225616 | |
*/ | |
function parse(array $opts,array &$args=null) | |
{ | |
global $argv,$argc; | |
if(is_array($args)) | |
{ | |
for($i=1;$i<count($argv);) | |
{ | |
if(!preg_match('/^--?\w/',$argv[$i])) | |
{ | |
array_push($args,array_splice($argv,$i,1)); | |
$argc--; | |
} | |
else $i++; | |
} | |
} | |
$mapping = array(); | |
// Build the "short" and "long" parameters for the getopt function. | |
list($short, $long) = array_values(array_reduce(array_keys($opts), function($r, $opt) use($opts, &$mapping) | |
{ | |
assert('is_string($opt)'); | |
if (preg_match('/(^[-\w]{2,})?(?:(?:^|\|)(\w))?(\?)?$/', $opt, $match)) | |
{ | |
$require_or_optional = !is_null($opts[$opt]) ? ':'.(!empty($match[3])?':':'') : ''; | |
if (!empty($match[2])) | |
{ | |
$r['short'] .= $match[2] . $require_or_optional; | |
$mapping[$match[2]] = $opt; | |
} | |
if (!empty($match[1])) | |
{ | |
array_push($r['long'], $match[1] . $require_or_optional); | |
$mapping[$match[1]] = $opt; | |
} | |
} | |
return $r; | |
}, array('short'=>'', 'long'=>array()) )); | |
// Parse the arguments and fill the variables. | |
foreach( getopt($short, $long) as $opt => $val ) | |
{ | |
if (array_key_exists($opt, $mapping)) | |
{ | |
$dest = &$opts[$mapping[$opt]]; | |
if (is_array($dest) and is_array($val)) $dest = array_merge($dest, $val); | |
elseif (is_array($dest)) array_push($dest, $val); | |
elseif (is_string($dest) ) $dest = is_array($val) ? current($val) : ($val===false?true:$val); | |
elseif (is_null($dest) or is_bool($dest)) $dest = true; | |
elseif ($dest instanceof Closure) $dest($val); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment