<?php
/**
* 命令行参数解析工具类
* @author guolinchao
* @email luoyecb@163.com
*/
class CommandLine
{
// store options
private static $optsArr = [];
// store args
private static $argsArr = [];
// 是否解析过
private static $isParse = false;

public function __construct() {
if(!self::$isParse) {
self::parseArgs();
}
}

/**
* 获取选项值
* @param string|NULL $opt
* @return array|string|NULL
*/
public function getOptVal($opt = NULL) {
if(is_null($opt)) {
return self::$optsArr;
} else if(isset(self::$optsArr[$opt])) {
return self::$optsArr[$opt];
}
return null;
}

/**
* 获取命令行参数值
* @param integer|NULL $index
* @return array|string|NULL
*/
public function getArgVal($index = NULL) {
if(is_null($index)) {
return self::$argsArr;
} else if(isset(self::$argsArr[$index])) {
return self::$argsArr[$index];
}
return null;
}

/**
* 注册选项对应的回调处理函数, $callback 应该有一个参数, 用于接收选项值
* @param string $opt
* @param callable $callback 回调函数
* @throws InvalidArgumentException
*/
public function option($opt, callable $callback) {
// check
if(!is_callable($callback)) {
throw new InvalidArgumentException(sprintf('Not a valid callback <%s>.', $callback));
}
if(isset(self::$optsArr[$opt])) {
call_user_func($callback, self::$optsArr[$opt]);
} else {
throw new InvalidArgumentException(sprintf('Unknown option <%s>.', $opt));
}
}

/**
* 是否是 -s 形式的短选项
* @param string $opt
* @return string|boolean 返回短选项名
*/
public static function isShortOptions($opt) {
if(preg_match('/^\-([a-zA-Z0-9])$/', $opt, $matchs)) {
return $matchs[1];
}
return false;
}

/**
* 是否是 -svalue 形式的短选项
* @param string $opt
* @return array|boolean 返回短选项名以及选项值
*/
public static function isShortOptionsWithValue($opt) {
if(preg_match('/^\-([a-zA-Z0-9])(\S+)$/', $opt, $matchs)) {
return [$matchs[1], $matchs[2]];
}
return false;
}

/**
* 是否是 --longopts 形式的长选项
* @param string $opt
* @return string|boolean 返回长选项名
*/
public static function isLongOptions($opt) {
if(preg_match('/^\-\-([a-zA-Z0-9\-_]{2,})$/', $opt, $matchs)) {
return $matchs[1];
}
return false;
}

/**
* 是否是 --longopts=value 形式的长选项
* @param string $opt
* @return array|boolean 返回长选项名及选项值
*/
public static function isLongOptionsWithValue($opt) {
if(preg_match('/^\-\-([a-zA-Z0-9\-_]{2,})(?:\=(.*?))$/', $opt, $matchs)) {
return [$matchs[1], $matchs[2]];
}
return false;
}

/**
* 是否是命令行参数
* @param string $value
* @return boolean
*/
public static function isArg($value) {
return ! preg_match('/^\-/', $value);
}

/**
* 解析命令行参数
* @return array ['opts'=>[], 'args'=>[]]
*/
public final static function parseArgs() {
global $argv;
if(!self::$isParse) {
// index start from one
$index = 1;
$length = count($argv);
while($index < $length) {
// current value
$curVal = $argv[$index];
// check, short or long options
if( ($key = self::isShortOptions($curVal)) || ($key = self::isLongOptions($curVal)) ) {
// go ahead
$index++;
if( isset($argv[$index]) && self::isArg($argv[$index]) ) {
self::$optsArr[$key] = $argv[$index];
} else {
self::$optsArr[$key] = true;
// back away
$index--;
}
} // check, short or long options with value
else if( ($key = self::isShortOptionsWithValue($curVal))
|| ($key = self::isLongOptionsWithValue($curVal)) ) {
self::$optsArr[$key[0]] = $key[1];
} // args
else if( self::isArg($curVal) ) {
self::$argsArr[] = $curVal;
}
// incr index
$index++;
}
self::$isParse = true; // change status
}
return ['opts'=>self::$optsArr, 'args'=>self::$argsArr];
}
}

// env check
if(PHP_SAPI != 'cli') {
exit('Please run under command line.');
}

用法如下:

<?php
include 'CommandLine.php';

$args = CommandLine::parseArgs();
print_r($args);

// or
$cmd = new CommandLine();
$cmd->option('h', function ($val){
// 处理选项 h
// $val 选项值
// ...
echo 'Option h handler.';
});

————————————————
版权声明:本文为CSDN博主「落叶成冰」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012302539/article/details/62045208

最新文章

  1. Linux Daemon 类程序
  2. PHP中的闭包和匿名函数
  3. checkbox下面的提示框 鼠标移入时显示,移出时隐藏
  4. 如何实现一个malloc
  5. 【转】使用NetBeans和Eclipse开发PHP应用程序
  6. cocos2d-x3.0+Eclipse配置说明
  7. 三大跨平台网盘--google driver
  8. [MSDN] GROUP BY (Transact-SQL)
  9. C Socket初探
  10. 关于9080端口和80端口实现真正意义的WebServer+ApplicationServer结合应用
  11. 201521123112《Java程序设计》第2周学习总结
  12. Beyond Globally Optimal: Focused Learning
  13. kindeditor配合requirejs使用时,ready失效
  14. java发送soapui格式的报文
  15. OSG相关扩展工程
  16. android 获取对权限的选择
  17. 在CentOS 7上使用Tripwire监控和检测修改的文件
  18. Sensor
  19. 【Eclipse】Eclipse常用操作
  20. Win10 虚拟桌面

热门文章

  1. JS案例 - 分页
  2. 第一册:lesson 133.
  3. linux cgroups简介(下)Cgroups 与 Systemd
  4. 逆向破解之160个CrackMe —— 019
  5. nvidia-smi命令执行很慢,如何改进
  6. git分布式版本控制系统的概述和安装
  7. getLog(this.getClass()) 与 getLog(XXX.class) 的区别
  8. Swagger 学习资料
  9. 19、Python标准库: 日期和时间
  10. 【Linux】linux ln文件夹的链接(转)