Skip to content

Instantly share code, notes, and snippets.

@jimmysawczuk
Created June 30, 2012 02:42
Show Gist options
  • Save jimmysawczuk/3021941 to your computer and use it in GitHub Desktop.
Save jimmysawczuk/3021941 to your computer and use it in GitHub Desktop.
Command-line flag parsing/HTTP Request parsing class
<?php
// Example use
require('flag.php');
Flag::boolFlag("all", "Whether or not to go back and get all 90 days worth of data", false);
Flag::stringArg("jobID", "ID of the job", "");
Flag::stringArg("groupId", "ID of the group", "");
$backprop = Flag::lookup("all");
$job_name = Flag::lookupArg("job");
$group_name = Flag::lookupArg("group");
<?php
class Flag
{
private static $flags = false;
private static $args = false;
private static $initted = false;
private static $parsed = false;
private static $parsed_flags = false;
private static $parsed_args = false;
private static $unparsed_args = false;
private static $arg_num = 1;
private static function init()
{
self::$flags = array();
self::$initted = true;
}
public static function intFlag($name, $description, $default = 0)
{
if (is_integer($default))
{
self::addFlag("int", $name, $description, $default);
}
else
{
die("Invalid default passed to flag parser for {$name} (expected int).\n");
}
}
public static function doubleFlag($name, $description, $default = 0.0)
{
if (is_double($default))
{
self::addFlag("double", $name, $description, $default);
}
else
{
die("Invalid default passed to flag parser for {$name} (expected double).\n");
}
}
public static function boolFlag($name, $description, $default = false)
{
if ($default === true || $default === false)
{
self::addFlag("bool", $name, $description, $default);
}
else
{
die("Invalid default passed to flag parser for {$name} (expected bool).\n");
}
}
public static function stringFlag($name, $description, $default = "")
{
self::addFlag("string", $name, $description, $default);
}
private static function addFlag($type, $name, $description, $default)
{
if (!self::$initted)
{
self::init();
}
self::$flags[$name] = array(
'name' => $name,
'type' => $type,
'description' => $description,
'default' => $default,
);
if (self::$parsed)
{
self::parse();
}
}
public static function stringArg($name, $description, $default = "", $num = false)
{
self::addArg("string", $name, $description, $default, $num);
}
private static function addArg($type, $name, $description, $default, $num = false)
{
if (!self::$initted)
{
self::init();
}
self::$args[$name] = array(
'name' => $name,
'num' => $num !== false? $num : self::$arg_num++,
'type' => $type,
'description' => $description,
'default' => $default,
);
}
public static function parse()
{
if (!isset($_SERVER['argv']))
{
self::parseRequest();
}
else
{
self::parseCLI();
}
}
public static function parseRequest()
{
global $_GET;
if (!self::$initted)
{
self::init();
}
$parsed_args = array();
foreach (self::$args as $arg)
{
if (isset($_GET[$arg['name']]))
{
$parsed_args[$arg['name']] = $_GET[$arg['name']];
}
}
self::$parsed_args = $parsed_args;
}
public static function parseCLI()
{
global $_SERVER;
if (!self::$initted)
{
self::init();
}
$raw_args = array_slice($_SERVER['argv'], 0);
$matches = array();
$parsed_flags = array();
$parsed_args = array();
$invalid_flags = array();
foreach ($raw_args as $arg)
{
if (preg_match('#^\-\-?([\w|\-]+?)\=(.*)#', $arg, $matches)) // this is a flag
{
$name = $matches[1];
$value = $matches[2];
$parsed_flags[$name] = $value;
}
else
{
$parsed_args []= $arg;
}
}
$parse = array();
foreach (self::$flags as $flag)
{
if (isset($parsed_flags[$flag['name']]))
{
$value = $parsed_flags[$flag['name']];
try
{
switch ($flag['type'])
{
case "int":
$value = (int)$value;
break;
case "double":
$value = (double)$value;
break;
case "bool":
if (in_array(trim(strtolower($value)), array("true", "1", "on", "yes")))
{
$value = true;
}
elseif (in_array(trim(strtolower($value)), array("false", "0", "off", "no")))
{
$value = false;
}
else
{
throw new Exception();
}
break;
case "string":
default:
break;
}
$parse[$flag['name']] = $value;
unset($parsed_flags[$flag['name']]);
}
catch (Exception $e)
{
die("Invalid value passed to command-line flag {$flag['name']}: \"{$parsed_flags[$flag['name']]}\" (expected {$flag['type']}).\n");
}
}
}
if (count($parsed_flags) > 0)
{
die("Unrecognized command-line flag(s): ".implode(", ", array_keys($parsed_flags))."\n");
}
$parse_a = array();
foreach (self::$args as $arg)
{
if (isset($parsed_args[$arg['num']]))
{
$value = $parsed_args[$arg['num']];
try
{
switch ($arg['type'])
{
case "int":
$value = (int)$value;
break;
case "double":
$value = (double)$value;
break;
case "bool":
if (in_array(trim(strtolower($value)), array("true", "1", "on", "yes")))
{
$value = true;
}
elseif (in_array(trim(strtolower($value)), array("false", "0", "off", "no")))
{
$value = false;
}
else
{
throw new Exception();
}
break;
case "string":
default:
break;
}
$parse_a[$arg['name']] = $value;
unset($parsed_args[$arg['name']]);
}
catch (Exception $e)
{
die("Invalid value passed to command-line flag {$flag['name']}: \"{$parsed_flags[$flag['name']]}\" (expected {$flag['type']}).\n");
}
}
}
self::$parsed_flags = $parse;
self::$parsed_args = $parse_a;
self::$unparsed_args = $parsed_args;
self::$parsed = true;
}
public static function lookup($flag_name)
{
if (!self::$parsed)
{
self::parse();
}
if (isset(self::$parsed_flags[$flag_name]))
{
return self::$parsed_flags[$flag_name];
}
elseif (isset(self::$flags[$flag_name]))
{
return self::$flags[$flag_name]['default'];
}
else
{
return false;
}
}
public static function lookupFlag($flag_name)
{
return self::lookup($flag_name);
}
public static function lookupArg($arg_name)
{
if (!self::$parsed)
{
self::parse();
}
if (isset(self::$parsed_args[$arg_name]))
{
return self::$parsed_args[$arg_name];
}
elseif (isset(self::$args[$arg_name]))
{
return self::$args[$arg_name]['default'];
}
else
{
return false;
}
}
public static function getUnparsedArgs()
{
if (!self::$parsed)
{
self::parse();
}
return self::$parsed_args;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment