├── .gitignore ├── CommandLine.php ├── LICENSE ├── README.md ├── composer.json ├── parseArgs.php ├── phpunit.xml.dist └── tests ├── CommandLineTest.php └── bootstrap.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | -------------------------------------------------------------------------------- /CommandLine.php: -------------------------------------------------------------------------------- 1 | 8 | * @since August 21, 2009 9 | * @see https://github.com/pwfisher/CommandLine.php 10 | */ 11 | class CommandLine 12 | { 13 | public static $args; 14 | 15 | /** 16 | * PARSE ARGUMENTS 17 | * 18 | * This command line option parser supports any combination of three types of options 19 | * [single character options (`-a -b` or `-ab` or `-c -d=dog` or `-cd dog`), 20 | * long options (`--foo` or `--bar=baz` or `--bar baz`) 21 | * and arguments (`arg1 arg2`)] and returns a simple array. 22 | * 23 | * [pfisher ~]$ php test.php --foo --bar=baz --spam eggs 24 | * ["foo"] => true 25 | * ["bar"] => "baz" 26 | * ["spam"] => "eggs" 27 | * 28 | * [pfisher ~]$ php test.php -abc foo 29 | * ["a"] => true 30 | * ["b"] => true 31 | * ["c"] => "foo" 32 | * 33 | * [pfisher ~]$ php test.php arg1 arg2 arg3 34 | * [0] => "arg1" 35 | * [1] => "arg2" 36 | * [2] => "arg3" 37 | * 38 | * [pfisher ~]$ php test.php plain-arg --foo --bar=baz --funny="spam=eggs" --also-funny=spam=eggs \ 39 | * > 'plain arg 2' -abc -k=value "plain arg 3" --s="original" --s='overwrite' --s 40 | * [0] => "plain-arg" 41 | * ["foo"] => true 42 | * ["bar"] => "baz" 43 | * ["funny"] => "spam=eggs" 44 | * ["also-funny"]=> "spam=eggs" 45 | * [1] => "plain arg 2" 46 | * ["a"] => true 47 | * ["b"] => true 48 | * ["c"] => true 49 | * ["k"] => "value" 50 | * [2] => "plain arg 3" 51 | * ["s"] => "overwrite" 52 | * 53 | * Not supported: `-cd=dog`. 54 | * 55 | * @author Patrick Fisher 56 | * @since August 21, 2009 57 | * @see https://github.com/pwfisher/CommandLine.php 58 | * @see http://www.php.net/manual/en/features.commandline.php 59 | * #81042 function arguments($argv) by technorati at gmail dot com, 12-Feb-2008 60 | * #78651 function getArgs($args) by B Crawford, 22-Oct-2007 61 | * @usage $args = CommandLine::parseArgs($_SERVER['argv']); 62 | */ 63 | public static function parseArgs($argv = null) 64 | { 65 | $argv = $argv ? $argv : $_SERVER['argv']; 66 | 67 | array_shift($argv); 68 | $out = array(); 69 | 70 | for ($i = 0, $j = count($argv); $i < $j; $i++) 71 | { 72 | $arg = $argv[$i]; 73 | 74 | // --foo --bar=baz 75 | if (substr($arg, 0, 2) === '--') 76 | { 77 | $eqPos = strpos($arg, '='); 78 | 79 | // --foo 80 | if ($eqPos === false) 81 | { 82 | $key = substr($arg, 2); 83 | 84 | // --foo value 85 | if ($i + 1 < $j && $argv[$i + 1][0] !== '-') 86 | { 87 | $value = $argv[$i + 1]; 88 | $i++; 89 | } 90 | else 91 | { 92 | $value = isset($out[$key]) ? $out[$key] : true; 93 | } 94 | $out[$key] = $value; 95 | } 96 | 97 | // --bar=baz 98 | else 99 | { 100 | $key = substr($arg, 2, $eqPos - 2); 101 | $value = substr($arg, $eqPos + 1); 102 | $out[$key] = $value; 103 | } 104 | } 105 | 106 | // -k=value -abc 107 | else if (substr($arg, 0, 1) === '-') 108 | { 109 | // -k=value 110 | if (substr($arg, 2, 1) === '=') 111 | { 112 | $key = substr($arg, 1, 1); 113 | $value = substr($arg, 3); 114 | $out[$key] = $value; 115 | } 116 | // -abc 117 | else 118 | { 119 | $chars = str_split(substr($arg, 1)); 120 | foreach ($chars as $char) 121 | { 122 | $key = $char; 123 | $value = isset($out[$key]) ? $out[$key] : true; 124 | $out[$key] = $value; 125 | } 126 | // -a value1 -abc value2 127 | if ($i + 1 < $j && $argv[$i + 1][0] !== '-') 128 | { 129 | $out[$key] = $argv[$i + 1]; 130 | $i++; 131 | } 132 | } 133 | } 134 | 135 | // plain-arg 136 | else 137 | { 138 | $value = $arg; 139 | $out[] = $value; 140 | } 141 | } 142 | 143 | self::$args = $out; 144 | 145 | return $out; 146 | } 147 | 148 | /** 149 | * GET BOOLEAN 150 | */ 151 | public static function getBoolean($key, $default = false) 152 | { 153 | if (!isset(self::$args[$key])) 154 | { 155 | return $default; 156 | } 157 | $value = self::$args[$key]; 158 | 159 | if (is_bool($value)) 160 | { 161 | return $value; 162 | } 163 | 164 | if (is_int($value)) 165 | { 166 | return (bool)$value; 167 | } 168 | 169 | if (is_string($value)) 170 | { 171 | $value = strtolower($value); 172 | $map = array( 173 | 'y' => true, 174 | 'n' => false, 175 | 'yes' => true, 176 | 'no' => false, 177 | 'true' => true, 178 | 'false' => false, 179 | '1' => true, 180 | '0' => false, 181 | 'on' => true, 182 | 'off' => false, 183 | ); 184 | if (isset($map[$value])) 185 | { 186 | return $map[$value]; 187 | } 188 | } 189 | 190 | return $default; 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2009 Patrick Fisher 2 | 3 | This work is licensed under the Creative Commons Attribution License. 4 | http://creativecommons.org/licenses/by/3.0/ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CommandLine.php 2 | =============== 3 | 4 | PHP Command Line interface class. Provides friendly and flexible CLI argument parsing. 5 | 6 | ### Usage 7 | 8 | $args = CommandLine::parseArgs($_SERVER['argv']); 9 | 10 | This command line option parser supports any combination of three types of options 11 | [single character options (`-a -b` or `-ab` or `-c -d=dog` or `-cd dog`), 12 | long options (`--foo` or `--bar=baz` or `--bar baz`) 13 | and arguments (`arg1 arg2`)] and returns a simple array. 14 | 15 | [pfisher ~]$ php test.php --foo --bar=baz --spam eggs 16 | ["foo"] => true 17 | ["bar"] => "baz" 18 | ["spam"] => "eggs" 19 | 20 | [pfisher ~]$ php test.php -abc foo 21 | ["a"] => true 22 | ["b"] => true 23 | ["c"] => "foo" 24 | 25 | [pfisher ~]$ php test.php arg1 arg2 arg3 26 | [0] => "arg1" 27 | [1] => "arg2" 28 | [2] => "arg3" 29 | 30 | [pfisher ~]$ php test.php plain-arg --foo --bar=baz --funny="spam=eggs" --also-funny=spam=eggs \ 31 | > 'plain arg 2' -abc -k=value "plain arg 3" --s="original" --s='overwrite' --s 32 | [0] => "plain-arg" 33 | ["foo"] => true 34 | ["bar"] => "baz" 35 | ["funny"] => "spam=eggs" 36 | ["also-funny"]=> "spam=eggs" 37 | [1] => "plain arg 2" 38 | ["a"] => true 39 | ["b"] => true 40 | ["c"] => true 41 | ["k"] => "value" 42 | [2] => "plain arg 3" 43 | ["s"] => "overwrite" 44 | 45 | Not supported: `-cd=dog`. 46 | 47 | @author Patrick Fisher 48 | 49 | @since August 21, 2009 50 | 51 | @see 52 | * http://www.php.net/manual/en/features.commandline.php 53 | * comment #81042 function arguments($argv) by technorati at gmail dot com, 12-Feb-2008 54 | * comment #78651 function getArgs($args) by B Crawford, 22-Oct-2007 55 | 56 | Note: parseArgs.php contains a "minified" version of the same code, for your copypasta pleasure. 57 | For little scripts for which you want to have a nice interface. 58 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pwfisher/command-line-php", 3 | "type": "library", 4 | "description": "PHP Command Line interface class. Provides friendly and flexible CLI argument parsing.", 5 | "keywords": ["cli", "parsing", "parser"], 6 | "license": ["CC-BY-3.0"], 7 | "authors": [ 8 | { 9 | "name": "Patrick Fisher", 10 | "email": "patrick@pwfisher.com" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=5.3.0" 15 | }, 16 | "autoload": { 17 | "classmap": ["CommandLine.php"] 18 | } 19 | } -------------------------------------------------------------------------------- /parseArgs.php: -------------------------------------------------------------------------------- 1 | 5 | * @see https://github.com/pwfisher/CommandLine.php 6 | */ 7 | function parseArgs($argv = null) { 8 | $argv = $argv ? $argv : $_SERVER['argv']; array_shift($argv); $o = array(); 9 | for ($i = 0, $j = count($argv); $i < $j; $i++) { $a = $argv[$i]; 10 | if (substr($a, 0, 2) == '--') { $eq = strpos($a, '='); 11 | if ($eq !== false) { $o[substr($a, 2, $eq - 2)] = substr($a, $eq + 1); } 12 | else { $k = substr($a, 2); 13 | if ($i + 1 < $j && $argv[$i + 1][0] !== '-') { $o[$k] = $argv[$i + 1]; $i++; } 14 | else if (!isset($o[$k])) { $o[$k] = true; } } } 15 | else if (substr($a, 0, 1) == '-') { 16 | if (substr($a, 2, 1) == '=') { $o[substr($a, 1, 1)] = substr($a, 3); } 17 | else { 18 | foreach (str_split(substr($a, 1)) as $k) { if (!isset($o[$k])) { $o[$k] = true; } } 19 | if ($i + 1 < $j && $argv[$i + 1][0] !== '-') { $o[$k] = $argv[$i + 1]; $i++; } } } 20 | else { $o[] = $a; } } 21 | return $o; 22 | } 23 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tests/ 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/CommandLineTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(0, count($result)); 16 | } 17 | 18 | /** @test */ 19 | public function noArgument() 20 | { 21 | $result = CommandLine::parseArgs(array(self::FILE)); 22 | $this->assertEquals(0, count($result)); 23 | } 24 | 25 | /** @test */ 26 | public function singleArgument() 27 | { 28 | $result = CommandLine::parseArgs(array(self::FILE, 'a')); 29 | $this->assertEquals(1, count($result)); 30 | $this->assertEquals('a', $result[0]); 31 | } 32 | 33 | /** @test */ 34 | public function multiArguments() 35 | { 36 | $result = CommandLine::parseArgs(array(self::FILE, 'a', 'b')); 37 | $this->assertEquals(2, count($result)); 38 | $this->assertEquals('a', $result[0]); 39 | $this->assertEquals('b', $result[1]); 40 | } 41 | 42 | /** @test */ 43 | public function singleSwitch() 44 | { 45 | $result = CommandLine::parseArgs(array(self::FILE, '-a')); 46 | $this->assertEquals(1, count($result)); 47 | $this->assertTrue($result['a']); 48 | } 49 | 50 | /** @test */ 51 | public function singleSwitchWithValue() 52 | { 53 | $result = CommandLine::parseArgs(array(self::FILE, '-a=b')); 54 | $this->assertEquals(1, count($result)); 55 | $this->assertEquals('b', $result['a']); 56 | } 57 | 58 | /** @test */ 59 | public function multiSwitch() 60 | { 61 | $result = CommandLine::parseArgs(array(self::FILE, '-a', '-b')); 62 | $this->assertEquals(2, count($result)); 63 | $this->assertTrue($result['a']); 64 | $this->assertTrue($result['b']); 65 | } 66 | 67 | /** @test */ 68 | public function multiSwitchAsOne() 69 | { 70 | $result = CommandLine::parseArgs(array(self::FILE, '-ab')); 71 | $this->assertEquals(2, count($result)); 72 | $this->assertTrue($result['a']); 73 | $this->assertTrue($result['b']); 74 | } 75 | 76 | /** @test */ 77 | public function singleFlagWithoutValue() 78 | { 79 | $result = CommandLine::parseArgs(array(self::FILE, '--a')); 80 | $this->assertEquals(1, count($result)); 81 | $this->assertTrue($result['a']); 82 | } 83 | 84 | /** @test */ 85 | public function singleFlagWithValue() 86 | { 87 | $result = CommandLine::parseArgs(array(self::FILE, '--a=b')); 88 | $this->assertEquals(1, count($result)); 89 | $this->assertEquals('b', $result['a']); 90 | } 91 | 92 | /** @test */ 93 | public function singleFlagOverwriteValue() 94 | { 95 | $result = CommandLine::parseArgs(array(self::FILE, '--a=original', '--a=overwrite')); 96 | $this->assertEquals(1, count($result)); 97 | $this->assertEquals('overwrite', $result['a']); 98 | } 99 | 100 | /** @test */ 101 | public function singleFlagOverwriteWithoutValue() 102 | { 103 | $result = CommandLine::parseArgs(array(self::FILE, '--a=original', '--a')); 104 | $this->assertEquals(1, count($result)); 105 | $this->assertEquals('original', $result['a']); 106 | } 107 | 108 | /** @test */ 109 | public function singleFlagWithDashInName() 110 | { 111 | $result = CommandLine::parseArgs(array(self::FILE, '--include-path=value')); 112 | $this->assertEquals(1, count($result)); 113 | $this->assertEquals('value', $result['include-path']); 114 | } 115 | 116 | /** @test */ 117 | public function singleFlagWithDashInNameAndInValue() 118 | { 119 | $result = CommandLine::parseArgs(array(self::FILE, '--include-path=my-value')); 120 | $this->assertEquals(1, count($result)); 121 | $this->assertEquals('my-value', $result['include-path']); 122 | } 123 | 124 | /** @test */ 125 | public function singleFlagWithEqualsSignInValue() 126 | { 127 | $result = CommandLine::parseArgs(array(self::FILE, '--funny=spam=eggs')); 128 | $this->assertEquals(1, count($result)); 129 | $this->assertEquals('spam=eggs', $result['funny']); 130 | } 131 | 132 | /** @test */ 133 | public function singleFlagWithDashInNameAndEqualsSignInValue() 134 | { 135 | $result = CommandLine::parseArgs(array(self::FILE, '--also-funny=spam=eggs')); 136 | $this->assertEquals(1, count($result)); 137 | $this->assertEquals('spam=eggs', $result['also-funny']); 138 | } 139 | 140 | /** @test */ 141 | public function singleFlagWithValueWithoutEquation () 142 | { 143 | $result = CommandLine::parseArgs(array(self::FILE, '--a', 'b')); 144 | $this->assertEquals(1, count($result)); 145 | $this->assertEquals('b', $result['a']); 146 | } 147 | 148 | /** @test */ 149 | public function multiSwitchAsOneWithValue() 150 | { 151 | $result = CommandLine::parseArgs(array(self::FILE, '-ab', 'value')); 152 | $this->assertEquals(2, count($result)); 153 | $this->assertTrue($result['a']); 154 | $this->assertEquals('value', $result['b']); 155 | } 156 | 157 | /** @test */ 158 | public function combination() 159 | { 160 | $result = CommandLine::parseArgs(array(self::FILE, '-ab', 'value', 'argument', '-c', '--s=r', '--x')); 161 | $this->assertEquals(6, count($result)); 162 | $this->assertTrue($result['a']); 163 | $this->assertEquals('value', $result['b']); 164 | $this->assertEquals('argument', $result[0]); 165 | $this->assertTrue($result['c']); 166 | $this->assertEquals('r', $result['s']); 167 | $this->assertTrue($result['x']); 168 | } 169 | 170 | /** @test */ 171 | public function parseGlobalServerVariable() 172 | { 173 | $_SERVER['argv'] = array(self::FILE, 'a'); 174 | $result = CommandLine::parseArgs(array()); 175 | $this->assertEquals(1, count($result)); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 |