PHP 命令行参数解析工具类

Posted 落叶成冰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP 命令行参数解析工具类相关的知识,希望对你有一定的参考价值。

<?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.';
});

命令行测试:



以上是关于PHP 命令行参数解析工具类的主要内容,如果未能解决你的问题,请参考以下文章

PHP 命令行参数解析工具类

go语言 从命令行获取参数解析

Java Main参数解析(Args4j)

片段(Java) | 机试题+算法思路+考点+代码解析 2023

Python 中最好用的命令行参数解析工具

Python中最好用的命令行解析工具:argparse