[ Index ] |
PHP Cross Reference of phool |
[Summary view] [Print] [Text view]
1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4: */ 3 // +----------------------------------------------------------------------+ 4 // | PHP Version 5 | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 1997-2003 The PHP Group | 7 // +----------------------------------------------------------------------+ 8 // | This source file is subject to version 3.0 of the PHP license, | 9 // | that is bundled with this package in the file LICENSE, and is | 10 // | available through the world-wide-web at the following url: | 11 // | http://www.php.net/license/3_0.txt. | 12 // | If you did not receive a copy of the PHP license and are unable to | 13 // | obtain it through the world-wide-web, please send a note to | 14 // | license@php.net so we can mail you a copy immediately. | 15 // +----------------------------------------------------------------------+ 16 // | Author: Andrei Zmievski <andrei@php.net> | 17 // | Modified by Francois Laupretre <francois@tekwire.net> | 18 // +----------------------------------------------------------------------+ 19 /** 20 * @copyright Francois Laupretre <phool@tekwire.net> 21 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, V 2.0 22 * @category phool 23 * @package phool 24 */ 25 //============================================================================ 26 27 //------------------------------------------------------------------------- 28 // Changes from original version: see class description 29 //------------------------------------------------------------------------- 30 31 namespace Phool\Options; 32 33 /** 34 * Command-line options parsing class. 35 * 36 * @author Andrei Zmievski <andrei@php.net> 37 * 38 */ 39 class Getopt { 40 /** 41 * Parses the command-line options. 42 * 43 * The first parameter to this function should be the list of command-line 44 * arguments without the leading reference to the running program. 45 * 46 * The second parameter is a string of allowed short options. Each of the 47 * option letters can be followed by a colon ':' to specify that the option 48 * requires an argument, or a double colon '::' to specify that the option 49 * takes an optional argument. 50 * 51 * The third argument is an optional array of allowed long options. The 52 * leading '--' should not be included in the option name. Options that 53 * require an argument should be followed by '=', and options that take an 54 * option argument should be followed by '=='. 55 * 56 * The return value is an array of two elements: the list of parsed 57 * options and the list of non-option command-line arguments. Each entry in 58 * the list of parsed options is a pair of elements - the first one 59 * specifies the option, and the second one specifies the option argument, 60 * if there was one. 61 * 62 * Long and short options can be mixed. 63 * 64 * Most of the semantics of this function are based on GNU getopt_long(). 65 * 66 * Changes from original version: 67 * - switch to PHP 5 object syntax 68 * - make independant from PEAR error handling using exceptions 69 * 70 * @param array $args an array of command-line arguments 71 * @param string $short_options specifies the list of allowed short options 72 * @param array $long_options specifies the list of allowed long options 73 * 74 * @return array two-element array containing the list of parsed options and 75 * the non-option arguments 76 * 77 * @throws Exception 78 * 79 */ 80 public static function getopt2($args, $short_options, $long_options = null) 81 { 82 return self::doGetopt(2, $args, $short_options, $long_options); 83 } 84 85 /** 86 * This function expects $args to start with the script name (POSIX-style). 87 * Preserved for backwards compatibility. 88 * @see getopt2() 89 */ 90 public static function getopt($args, $short_options, $long_options = null) 91 { 92 return self::doGetopt(1, $args, $short_options, $long_options); 93 } 94 95 /** 96 * The actual implementation of the argument parsing code. 97 */ 98 private static function doGetopt($version, $args, $short_options, $long_options = null) 99 { 100 if (empty($args)) { 101 return array(array(), array()); 102 } 103 $opts = array(); 104 $non_opts = array(); 105 106 settype($args, 'array'); 107 108 if ($long_options) { 109 sort($long_options); 110 } 111 112 /* 113 * Preserve backwards compatibility with callers that relied on 114 * erroneous POSIX fix. 115 */ 116 if ($version < 2) { 117 if (isset($args[0]{0}) && $args[0]{0} != '-') { 118 array_shift($args); 119 } 120 } 121 122 reset($args); 123 while (list($i, $arg) = each($args)) { 124 125 /* The special element '--' means explicit end of 126 options. Treat the rest of the arguments as non-options 127 and end the loop. */ 128 if ($arg == '--') { 129 $non_opts = array_merge($non_opts, array_slice($args, $i + 1)); 130 break; 131 } 132 133 if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) { 134 $non_opts = array_merge($non_opts, array_slice($args, $i)); 135 break; 136 } elseif (strlen($arg) > 1 && $arg{1} == '-') { 137 self::_parseLongOption(substr($arg, 2), $long_options, $opts, $args); 138 } else { 139 self::_parseShortOption(substr($arg, 1), $short_options, $opts, $args); 140 } 141 } 142 143 return array($opts, $non_opts); 144 } 145 146 private static function _parseShortOption($arg, $short_options, &$opts, &$args) 147 { 148 for ($i = 0; $i < strlen($arg); $i++) { 149 $opt = $arg{$i}; 150 $opt_arg = null; 151 152 /* Try to find the short option in the specifier string. */ 153 if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') 154 { 155 throw new \Exception(__CLASS__.": unrecognized option -- $opt"); 156 } 157 158 if (strlen($spec) > 1 && $spec{1} == ':') { 159 if (strlen($spec) > 2 && $spec{2} == ':') { 160 if ($i + 1 < strlen($arg)) { 161 /* Option takes an optional argument. Use the remainder of 162 the arg string if there is anything left. */ 163 $opts[] = array($opt, substr($arg, $i + 1)); 164 break; 165 } 166 } else { 167 /* Option requires an argument. Use the remainder of the arg 168 string if there is anything left. */ 169 if ($i + 1 < strlen($arg)) { 170 $opts[] = array($opt, substr($arg, $i + 1)); 171 break; 172 } else if (list(, $opt_arg) = each($args)) 173 /* Else use the next argument. */; 174 else 175 throw new \Exception(__CLASS__.": option requires an argument -- $opt"); 176 } 177 } 178 179 $opts[] = array($opt, $opt_arg); 180 } 181 } 182 183 private static function _parseLongOption($arg, $long_options, &$opts, &$args) 184 { 185 @list($opt, $opt_arg) = explode('=', $arg); 186 $opt_len = strlen($opt); 187 188 for ($i = 0; $i < count($long_options); $i++) { 189 $long_opt = $long_options[$i]; 190 $opt_start = substr($long_opt, 0, $opt_len); 191 192 /* Option doesn't match. Go on to the next one. */ 193 if ($opt_start != $opt) 194 continue; 195 196 $opt_rest = substr($long_opt, $opt_len); 197 198 /* Check that the options uniquely matches one of the allowed 199 options. */ 200 if ($opt_rest != '' && $opt{0} != '=' && 201 $i + 1 < count($long_options) && 202 $opt == substr($long_options[$i+1], 0, $opt_len)) { 203 throw new \Exception(__CLASS__.": option --$opt is ambiguous"); 204 } 205 206 if (substr($long_opt, -1) == '=') { 207 if (substr($long_opt, -2) != '==') { 208 /* Long option requires an argument. 209 Take the next argument if one wasn't specified. */; 210 if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) { 211 throw new \Exception(__CLASS__.": option --$opt requires an argument"); 212 } 213 } 214 } else if ($opt_arg) { 215 throw new \Exception(__CLASS__.": option --$opt doesn't allow an argument"); 216 } 217 218 $opts[] = array('--' . $opt, $opt_arg); 219 return; 220 } 221 222 throw new \Exception(__CLASS__.": unrecognized option --$opt"); 223 } 224 225 /** 226 * Safely read the $argv PHP array across different PHP configurations. 227 * Will take care on register_globals and register_argc_argv ini directives 228 * 229 * @return array the $argv PHP array 230 * @throws Exception if not registered 231 */ 232 public static function readPHPArgv() 233 { 234 global $argv; 235 if (!is_array($argv)) { 236 if (!@is_array($_SERVER['argv'])) { 237 if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) { 238 throw new \Exception(__CLASS__.": Could not read cmd args (register_argc_argv=Off?)"); 239 } 240 return $GLOBALS['HTTP_SERVER_VARS']['argv']; 241 } 242 return $_SERVER['argv']; 243 } 244 return $argv; 245 } 246 247 } 248 249 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jun 4 19:17:11 2015 | Cross-referenced by PHPXref 0.7.1 |