@@ -22,32 +22,26 @@ final class CommandLine
2222
2323 /**
2424 * Parses $GLOBALS['argv'] for parameters and assigns them to an array.
25- *
2625 * eg:
27- *
2826 * ```
2927 * php cli.php server start name=john city=chengdu -s=test --page=23 -d -rf --debug --task=off -y=false -D -e dev -v vvv
3028 * ```
31- *
3229 * ```php
3330 * $result = CommandLineParse::byArgv($_SERVER['argv']);
3431 * ```
35- *
3632 * Supports args:
3733 * <value>
3834 * arg=<value>
39- *
4035 * Supports opts:
4136 * -e
4237 * -e <value>
4338 * -e=<value>
4439 * --long-opt
4540 * --long-opt <value>
4641 * --long-opt=<value>
47- *
4842 * @link http://php.net/manual/zh/function.getopt.php#83414
4943 * @param array $params
50- * @param array $noValues List of parameters without values(bool option keys)
44+ * @param array $noValues List of parameters without values(bool option keys) noVal
5145 * @param bool $mergeOpts Whether merge short-opts and long-opts
5246 * @return array
5347 */
@@ -62,37 +56,36 @@ public static function parseByArgv(array $params, array $noValues = [], $mergeOp
6256
6357 // is options
6458 if ($ p {0 } === '- ' ) {
65- $ isLong = false ;
59+ $ val = true ;
6660 $ opt = substr ($ p , 1 );
67- $ value = true ;
61+ $ isLong = false ;
6862
6963 // long-opt: (--<opt>)
7064 if ($ opt {0 } === '- ' ) {
71- $ isLong = true ;
7265 $ opt = substr ($ opt , 1 );
66+ $ isLong = true ;
7367
7468 // long-opt: value specified inline (--<opt>=<value>)
7569 if (strpos ($ opt , '= ' ) !== false ) {
76- list ($ opt , $ value ) = explode ('= ' , $ opt , 2 );
70+ list ($ opt , $ val ) = explode ('= ' , $ opt , 2 );
7771 }
7872
7973 // short-opt: value specified inline (-<opt>=<value>)
80- } elseif (\strlen ($ opt) > 2 && $ opt {1 } === '= ' ) {
81- list ($ opt , $ value ) = explode ('= ' , $ opt , 2 );
74+ } elseif (isset ($ opt{ 1 }) && $ opt {1 } === '= ' ) {
75+ list ($ opt , $ val ) = explode ('= ' , $ opt , 2 );
8276 }
8377
8478 // check if next parameter is a descriptor or a value
85- $ nxp = current ($ params );
79+ $ nxt = current ($ params );
8680
87- // fix: allow empty string ''
88- if ($ value === true && $ nxp !== false && (!$ nxp || $ nxp {0 } !== '- ' ) && !\in_array ($ opt , $ noValues ,
89- true )) {
90- // list(,$value) = each($params);
91- $ value = current ($ params );
81+ // next elem is value. fix: allow empty string ''
82+ if ($ val === true && self ::nextIsValue ($ nxt ) && !\in_array ($ opt , $ noValues ,true )) {
83+ // list(,$val) = each($params);
84+ $ val = $ nxt ;
9285 next ($ params );
9386
9487 // short-opt: bool opts. like -e -abc
95- } elseif (!$ isLong && $ value === true ) {
88+ } elseif (!$ isLong && $ val === true ) {
9689 foreach (str_split ($ opt ) as $ char ) {
9790 $ sOpts [$ char ] = true ;
9891 }
@@ -101,17 +94,17 @@ public static function parseByArgv(array $params, array $noValues = [], $mergeOp
10194 }
10295
10396 if ($ isLong ) {
104- $ lOpts [$ opt ] = self ::filterBool ($ value );
97+ $ lOpts [$ opt ] = self ::filterBool ($ val );
10598 } else {
106- $ sOpts [$ opt ] = self ::filterBool ($ value );
99+ $ sOpts [$ opt ] = self ::filterBool ($ val );
107100 }
108101
109102 // arguments: param doesn't belong to any option, define it is args
110103 } else {
111104 // value specified inline (<arg>=<value>)
112105 if (strpos ($ p , '= ' ) !== false ) {
113- list ($ name , $ value ) = explode ('= ' , $ p , 2 );
114- $ args [$ name ] = self ::filterBool ($ value );
106+ list ($ name , $ val ) = explode ('= ' , $ p , 2 );
107+ $ args [$ name ] = self ::filterBool ($ val );
115108 } else {
116109 $ args [] = $ p ;
117110 }
@@ -132,41 +125,38 @@ public static function parseByDefinition(array $tokens, array $allowArray = [],
132125
133126 /**
134127 * parse custom array params
135- *
136128 * ```php
137129 * $result = CommandLine::parseByArray([
138130 * 'arg' => 'val',
139131 * '--lp' => 'val2',
140132 * '--s' => 'val3',
141133 * ]);
142134 * ```
143- *
144135 * @param array $params
145136 * @return array
146137 */
147138 public static function parseByArray (array $ params )
148139 {
149140 $ args = $ sOpts = $ lOpts = [];
150141
151- foreach ($ params as $ key => $ value ) {
142+ foreach ($ params as $ key => $ val ) {
152143 if ($ key === '-- ' || $ key === '- ' ) {
153144 continue ;
154145 }
155146
156147 if (0 === strpos ($ key , '-- ' )) {
157- $ lOpts [substr ($ key , 2 )] = $ value ;
148+ $ lOpts [substr ($ key , 2 )] = $ val ;
158149 } elseif ('- ' === $ key [0 ]) {
159- $ sOpts [substr ($ key , 1 )] = $ value ;
150+ $ sOpts [substr ($ key , 1 )] = $ val ;
160151 } else {
161- $ args [$ key ] = $ value ;
152+ $ args [$ key ] = $ val ;
162153 }
163154 }
164155
165156 return [$ args , $ sOpts , $ lOpts ];
166157 }
167158
168159 /**
169- *
170160 * ```php
171161 * $result = CommandLine::parseByString('foo --bar="foobar"');
172162 * ```
@@ -190,14 +180,12 @@ public static function filterBool($val, $enable = true)
190180 return $ val ;
191181 }
192182
193- $ tVal = strtolower ($ val );
194-
195183 // check it is a bool value.
196- if (false !== strpos (self ::TRUE_WORDS , "| $ tVal | " )) {
184+ if (false !== stripos (self ::TRUE_WORDS , "| $ val | " )) {
197185 return true ;
198186 }
199187
200- if (false !== strpos (self ::FALSE_WORDS , "| $ tVal | " )) {
188+ if (false !== stripos (self ::FALSE_WORDS , "| $ val | " )) {
201189 return false ;
202190 }
203191 }
@@ -207,12 +195,31 @@ public static function filterBool($val, $enable = true)
207195
208196 /**
209197 * Escapes a token through escapeshellarg if it contains unsafe chars.
210- *
211198 * @param string $token
212199 * @return string
213200 */
214201 public static function escapeToken ($ token )
215202 {
216203 return preg_match ('{^[\w-]+$} ' , $ token ) ? $ token : escapeshellarg ($ token );
217204 }
205+
206+ /**
207+ * @param mixed $val
208+ * @return bool
209+ */
210+ public static function nextIsValue ($ val )
211+ {
212+ // current() fetch error, will return FALSE
213+ if ($ val === false ) {
214+ return false ;
215+ }
216+
217+ // if is: '', 0
218+ if (!$ val ) {
219+ return true ;
220+ }
221+
222+ // it isn't option or named argument
223+ return $ val {0 } !== '- ' && false === strpos ($ val , '= ' );
224+ }
218225}
0 commit comments