1. 程式人生 > >PHP 命令列引數解析工具類

PHP 命令列引數解析工具類

<?php
/**
 * 命令列引數解析工具類
 * @author guolinchao
 * @email [email protected]
 */
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 /** * 命令列引數解析工具類 * @author guolinchao * @email [email protected] */ class CommandLine { // store options private stat

gflags(google開源的一套命令引數解析工具)

gflags是google開源的一套命令列引數解析工具,比getopt()函式功能要強大,使用起來更加方便,gflags還支援從環境變數和配置檔案中讀取引數。目前有C++和Python版本。本文就來詳細介紹C++版本gflags的使用,主要分如下兩個部分 Cont

C++ 命令引數解析

文章目錄 說明 短引數之 getopt() 長引數之 getopt_long() 長引數之 getopt_long_only() 說明 主要參考以下部落格: 部落格一:getopt和g

【tensorflow】命令引數解析

1. tf.app.flags,用於支援接受命令列傳遞引數 import tensorflow as tf #第一個是引數名稱,第二個引數是預設值,第三個是引數描述 tf.app.flags.DEFINE_string('str_name', 'def_v_1',"descrip1")

golang命令引數解析

package main import ( "fmt" "os" ) func main(){ s:= os.Args fmt.Println(s) }   直接執行 輸出結果:[C:\Users\Administrator\AppData\Local\Temp\___go_bui

python命令引數解析

一、getopt模組  getopt.getopt(args, options[, long_options]) args為需要解析的命令列引數列表,一般為sys.argv[1:],這是因為argv[0]為指令碼的路徑。 options為希望識別的引數,如果該命令列引數

python 命令引數解析 argparse簡單分析

在python 2.7 後,不推薦使用 optparse, 而推薦使用 argparse. 其它的不多說,簡單的分析下我遇到的問題:我是想用 argparse 來解析不定長的命令列引數 例如: import argparse import sys parser = ar

命令引數解析

對這種主函式形式一直不是很瞭解,今天研究了一下,所得如下: 當我們成功執行一個程式時,在Windows環境下會生成一個exe檔案,我們可以再命令列中開啟並執行這個程式。 比如說如下程式碼。 #

Golang: 使用flag包進行命令引數解析

最近在使用go開發cli(command-line-interface)時,通過對於官方文件以及他人部落格的學習,在此寫下個人認為更適合自己往後回顧的關於flag的使用說明。 工欲善其事必先利其器,先奉上flag官方文件解析 Demo0: pack

ffmpeg 原始碼學習 -- 之命令引數解析

ffmpeg 原始碼學習 -- 之ffmpeg命令列引數解析 大家通過git在安裝好cygwin之後,下載原始碼到(cygwin)home目錄,通過./configure  ...... ,可以新增一堆引數選項,執行可以生成config.mk等編譯使用的檔案,通過命令對工

Tensorflow:tf.app.run()與命令引數解析

首先給出一段常見的程式碼: if __name__ == '__main__': tf.app.run()12 它是函式入口,通過處理flag解析,然後執行main函式(或者接下來提到的xxx())(最後含有tf.app.run()的檔案,在此行之前肯定能找到def main

Python命令引數解析模組argparse

當寫一個Python指令碼時經常會遇到不同引數不同功能的情況,如何做一個更好看的命令幫助資訊以及對命令引數解析呢? 這就需要使用argparse模組 #!/usr/bin/env python # -*- coding: utf-8 -*- import sys import os impor

命令引數解析函式getopt_long() 使用詳解

當一個用C語言編寫的Linux或UNIX程式執行時,它是從main函式開始的。對這些程式而言,main函式的宣告如下所示: int main(int argc, char *argv[]) 其中argc是程式引數的個數(int),argv是一個代表引數自身的

getopt(win32) -- 命令引數解析函式

GNU libc提供了getopt和getopt_long用於解析命令列引數,很好用,想在windows下使用,就google了幾個win32下的C/C++寫得getopt,並作了一些比較。 程式裡往往會有許多開關的,執行時就要傳入許多引數值來開啟或關閉這些開關。以前

命令引數解析函式--getopt

原型: #include <unistd.h> int getopt(int argc, char * const argv[], const char *optstring); 該函式的argc和argv引數通常直接從main()的引數直接傳遞而來。opt

C 語言命令引數解析

C語言原始碼必須有且只有一個的函式是main函式,我們知道函式可以有引數,那麼main函式有沒有引數呢? 顯然是有的,而且它是固定的,只有兩個,第一個是整型變數(argc),第二個是字元型指標陣列(a

一個命令引數解析

    因工作需要寫一個console工具程式,執行引數很多,記得linux下有一個系統函式getopt可以很好得幫助程式設計師解析命令列引數,但是在VC中沒有這個函式,研究了下linux中對該函式的幫助資訊和標頭檔案g

使用Apache commons-cli包進行命令引數解析

Apache的commons-cli包是專門用於解析命令列引數格式的包。 依賴: <dependency> <groupId>commons-cli</groupId> <artifactId&g

linux命令引數解析學習心得

轉載出處:blog.csdn.net/bailyzheng/article/details/8048733 最近用到一個命令列工具,之前也一直說想把命令列引數解析看一下,今天算是做一個小的總結。 命令列引數解析分類:單個字元的引數(-a -b),還有字串引數(--vide

linux命令引數解析函式 getopt

在學習開原始碼過程中,經常遇到命令列解析函式 getopt,網上查閱了一些資料,總結一下。 說到命令列解析,最簡單的方式就是利用c語言main函式的兩個引數argc和argv來實現,當 C 執行時庫程式啟動程式碼呼叫 main() 時,會將命令列的引數傳過來,引數個數放在a