PHP 选项/信息 函数
在线手册:中文  英文

getopt

(PHP 4 >= 4.3.0, PHP 5)

getopt从命令行参数列表中获取选项

说明

array getopt ( string $options [, array $longopts ] )

解析传入脚本的选项。

参数

options
该字符串中的每个字符会被当做选项字符,匹配传入脚本的选项以单个连字符(-)开头。 比如,一个选项字符串 "x" 识别了一个选项 -x 只允许 a-z、A-Z 和 0-9。
longopts
选项数组。此数组中的每个元素会被作为选项字符串,匹配了以两个连字符(--)传入到脚本的选项。 例如,长选项元素 "opt" 识别了一个选项 --opt

options 可能包含了以下元素:

选项的值是字符串后的第一个参数。它不介意值之前是否有空格。

Note: 选项的值不接受空格(" ")作为分隔符。

Note:

optionslongopts 的格式几乎是一样的,唯一的不同之处是 longopts 需要是选项的数组(每个元素为一个选项),而 options 需要一个字符串(每个字符是个选项)。

返回值

此函数会返回选项/参数对,失败时返回 FALSE

Note:

选项的解析会终止于找到的第一个非选项,之后的任何东西都会被丢弃。

更新日志

版本 说明
5.3.0 支持 "=" 作为 参数和值的分隔符。
5.3.0 增加了可选值的支持(用"::"指定)。
5.3.0 参数 longopts 在所有系统平台上均可用。
5.3.0 此函数不再依赖于操作系统,现在也能够在 Windows 上运行。

范例

Example #1 getopt() 例子

<?php
$options 
getopt("f:hp:");
var_dump($options);
?>

通过 php script.php -fvalue -h 运行以上脚本会输出:

array(2) {
  ["f"]=>
  string(5) "value"
  ["h"]=>
  bool(false)
}

Example #2 getopt() 例子#2

<?php
$shortopts  
"";
$shortopts .= "f:";  // Required value
$shortopts .= "v::"// Optional value
$shortopts .= "abc"// These options do not accept values

$longopts  = array(
    
"required:",     // Required value
    
"optional::",    // Optional value
    
"option",        // No value
    
"opt",           // No value
);
$options getopt($shortopts$longopts);
var_dump($options);
?>

通过 php script.php -f "value for f" -v -a --required value --optional="optional value" --option 运行以上脚本会输出:

array(6) {
  ["f"]=>
  string(11) "value for f"
  ["v"]=>
  bool(false)
  ["a"]=>
  bool(false)
  ["required"]=>
  string(5) "value"
  ["optional"]=>
  string(14) "optional value"
  ["option"]=>
  bool(false)
}

Example #3 getopt() 例子#3

传递同一多个选项

<?php
$options 
getopt("abc");
var_dump($options);
?>

使用 php script.php -aaac 运行以上脚本会输出:

array(2) {
  ["a"]=>
  array(3) {
    [0]=>
    bool(false)
    [1]=>
    bool(false)
    [2]=>
    bool(false)
  }
  ["c"]=>
  bool(false)
}

参见


PHP 选项/信息 函数
在线手册:中文  英文

用户评论:

tsuliuchao at sina dot com (2013-06-25 03:36:13)

a.php
<?php
$shortopts  
"";
$shortopts .= "f:";  // Required value
$shortopts .= "v::"// Optional value
$shortopts .= "abc"// These options do not accept values

$longopts  = array(
    
"required:",     // Required value
    
"optional::",    // Optional value
    
"option",        // No value
    
"opt",           // No value
);
$options getopt($shortopts$longopts);
var_dump($options);
?> 

php a.php -f "value for f" -v -a --required value --optional="optional value"    
执行结果是:  
array(3) {
  ["f"]=>
  string(11) "value for f"
  ["v"]=>
  array(2) {
    [0]=>
    bool(false)
    [1]=>
    string(4) "alue"
  }
  ["a"]=>
  array(3) {
    [0]=>
    bool(false)
    [1]=>
    bool(false)
    [2]=>
    bool(false)
  }
}

php at richardneil dot org (2013-04-09 13:50:58)

A repeated option will be converted into an array. So:
#myscript.php -a -b -c1 -Dfruit=apple -Dcolor=green
$options = getopt ("abc:D:");
print_r($options);
Array
(
[a] => //value === false
[b] =>
[c] => 1
[D] => Array
(
[0] => fruit=apple
[1] => color=green
)
)

lynch at php dot net (2012-03-16 17:01:35)

In PHP < 5.3.0 you can "simulate" the "optional v::" by using this: "vv:"

#!/usr/bin/php
<?php
    $short 
"vv:";
    
$opts getopt($short);
    
var_dump($opts);
?>

./test_opt.php -v
array(1) {
  ["v"]=>
  bool(false)
}

./test_opt.php -vv
array(1) {
  ["v"]=>
  array(2) {
    [0]=>
    bool(false)
    [1]=>
    bool(false)
  }
}

./test_opt.php -vvv
array(1) {
  ["v"]=>
  array(3) {
    [0]=>
    bool(false)
    [1]=>
    bool(false)
    [2]=>
    bool(false)
  }
}

./test_opt.php -vvvv
array(1) {
  ["v"]=>
  array(4) {
    [0]=>
    bool(false)
    [1]=>
    bool(false)
    [2]=>
    bool(false)
    [3]=>
    bool(false)
  }
}

I'm not sure if that's a Bug or a Feature, as it's not documented as such, but it works for me.

I also have not tested if it works with other opts, nor if you need vv: in that exact order, or even consecutive...
"v:v" or "vav:" (with -a being something else) etc may also work.  Or not. I leave that as an exercise for the reader.

Anonymous (2011-02-02 16:33:57)

getopt() only returns the options specified if they were listed in the options.
So you cant make a switch() use default: to complain of an unknown option. :(

mpartap at gmx dot net (2010-10-24 13:39:42)

Here's another way of removing options found by getopt() from the argv[] array. It handles the different kind of parameters without eating chunks that do not belong to an --option. (-nr foo param1 param2 foo)
<?php
$parameters 
= array(
  
'n' => 'noparam',
  
'r:' => 'required:',
  
'o::' => 'optional::',
);

$options getopt(implode(''array_keys($parameters)), $parameters);
$pruneargv = array();
foreach (
$options as $option => $value) {
  foreach (
$argv as $key => $chunk) {
    
$regex '/^'. (isset($option[1]) ? '--' '-') . $option '/';
    if (
$chunk == $value && $argv[$key-1][0] == '-' || preg_match($regex$chunk)) {
      
array_push($pruneargv$key);
    }
  }
}
while (
$key array_pop($pruneargv)) unset($argv[$key]);
?>

geoff at gosquared dot com (2010-05-08 05:05:52)

It seems under PHP 5.3.2, getopt() makes a script fail to load if called via HTTP without any conditions. You'll need something like if(isset($_SERVER['argc'])) $args = getopt(); to prevent that.

m at ttcarter dot com (2009-03-15 03:36:02)

I wrote a library some time ago to counter some of the missing features of the rather limited 'getopt' function. The library as well documentation can be found on my website at http://hash-bang.net/2008/12/missing-php-functions-getopts/
It provides functionality for long switches (e.g. '--delete'), incrementing switches (e.g. '-v -v -v' or '-vvv' for very, very verbose), long values (e.g. '--exclude this.file') and lots more.

suichengw at gmail dot com (2008-08-16 10:28:11)

I really need long options but it's not supported in 5.2.6 on my Solaris box so I wrote an _getopt() to simulate getopt().

An example

======== a.php ========
#!/usr/local/bin/php
<?php
include "getopt.inc";

$shortopts  "f:v::abc:hp";  

$longopts  = array(
    
"required:",     // Required value
    
"optional::",    // Optional value
    
"option",        // No value
    
"opt",           // No value
);

$options _getopt$shortopts$longopts);

var_dump($options);
?>
====== end of a.php ======

then run the file a.php,

# ./a.php -f "test 2" -ab --required "test 1" --optional="test 3" --option -v "test 4" -k
array(7) {
  ["f"]=>
  string(6) "test 2"
  ["a"]=>
  bool(false)
  ["b"]=>
  bool(false)
  ["required"]=>
  string(6) "test 1"
  ["optional"]=>
  string(6) "test 3"
  ["option"]=>
  bool(false)
  ["v"]=>
  string(6) "test 4"
}

Source code is a bit longer and not allowed by this site. Please go to my page http://www.ntu.beautifulworldco.com/weblog/?p=526 for it.

mbirth at webwriters dot de (2008-05-24 13:41:49)

After getopt() of PHP5.3.0 (on Windows) ignored some parameters if there was a syntactical problem, I decided to code my own generic parameter parser.

<?php
    
/**
     * Parses $GLOBALS['argv'] for parameters and assigns them to an array.
     *
     * Supports:
     * -e
     * -e <value>
     * --long-param
     * --long-param=<value>
     * --long-param <value>
     * <value>
     *
     * @param array $noopt List of parameters without values
     */
    
function parseParameters($noopt = array()) {
        
$result = array();
        
$params $GLOBALS['argv'];
        
// could use getopt() here (since PHP 5.3.0), but it doesn't work relyingly
        
reset($params);
        while (list(
$tmp$p) = each($params)) {
            if (
$p{0} == '-') {
                
$pname substr($p1);
                
$value true;
                if (
$pname{0} == '-') {
                    
// long-opt (--<param>)
                    
$pname substr($pname1);
                    if (
strpos($p'=') !== false) {
                        
// value specified inline (--<param>=<value>)
                        
list($pname$value) = explode('='substr($p2), 2);
                    }
                }
                
// check if next parameter is a descriptor or a value
                
$nextparm current($params);
                if (!
in_array($pname$noopt) && $value === true && $nextparm !== false && $nextparm{0} != '-') list($tmp$value) = each($params);
                
$result[$pname] = $value;
            } else {
                
// param doesn't belong to any option
                
$result[] = $p;
            }
        }
        return 
$result;
    }
?>

A call like: php.exe -f test.php -- alfons -a 1 -b2 -c --d 2 --e=3=4 --f "alber t" hans wurst

and an in-program call parseParameters(array('f')); would yield in a resulting array:

Array
(
    [0] => alfons
    [a] => 1
    [b2] => 1
    [c] => 1
    [d] => 2
    [e] => 3=4
    [f] => 1
    [1] => alber t
    [2] => hans
    [3] => wurst
)

As you can see, values without an identifier are stored with numeric indexes. Existing identifiers without values get "true".

uberlinuxguy at tulg dot org (2008-04-25 13:26:03)

One thing of important note would be that getopt() actually respects the '--' option to end an option list.  Thus given the code:

test.php:
<?php
    $options 
getopt("m:g:h:");
    if (!
is_array($options) ) {
        print 
"There was a problem reading in the options.\n\n";
        exit(
1);
    }
    
$errors = array();
    
print_r($options);
?> 

And running:

# ./test.php ./run_vfs  -h test1 -g test2 -m test3 -- this is a test -m green

Will return: 

Array
(
    [h] => test1
    [g] => test2
    [m] => test3
)

Whereas running:
# /test.php ./run_vfs  -h test1 -g test2 -m test3 this is a test -m green

Will return:

Array
(
    [h] => test1
    [g] => test2
    [m] => Array
        (
            [0] => test3
            [1] => green
        )

)

Francois Hill (2007-11-19 12:44:42)

Although very interesting, koenbollen at gnospamail dot com's update of the argv array fails when option values follow the option with no space :
Indeed 
    php MyScript.php5 -t5 
and
    php MyScript.php5 -t 5
with $options="t:" are treated as the same by getopt.

This upgraded function should take care of it :

File : shift_test.php5
<?php
    
function shift($options_array)
    {
        foreach( 
$options_array as $o => $a )
        {
            
// Look for all occurrences of option in argv and remove if found :
            // ----------------------------------------------------------------
            // Look for occurrences of -o (simple option with no value) or -o<val> (no space in between):
            
while($k=array_search("-".$o.$a,$GLOBALS['argv']))
            {    
// If found remove from argv:
                
if($k)
                    unset(
$GLOBALS['argv'][$k]);
            }
            
// Look for remaining occurrences of -o <val> (space in between):
            
while($k=array_search("-".$o,$GLOBALS['argv']))
            {    
// If found remove both option and value from argv:
                
if($k)
                {    unset(
$GLOBALS['argv'][$k]);
                    unset(
$GLOBALS['argv'][$k+1]);
                }
            }
        }
        
// Reindex :
        
$GLOBALS['argv']=array_merge($GLOBALS['argv']);
    }

    
print_r($argv);
    
$options_array=getopt('t:h');
    
shift($options_array);
    
print_r($argv);
?>

>php shift_test.php5 -h -t4 param1 param2
will ouptut :
Array
(
    [0] => test.php5
    [1] => -h
    [2] => -t4
    [3] => param1
    [4] => param2
)
Array
(
    [0] => test.php5
    [1] => param1
    [2] => param2
)

>php shift_test.php5 -h -t 4 param1 param2
will ouptut :
Array
(
    [0] => test.php5
    [1] => -h
    [2] => -t
    [3] => 4
    [4] => param1
    [5] => param2
)
Array
(
    [0] => test.php5
    [1] => param1
    [2] => param2
)

Damien B. (2007-11-07 22:47:16)

This is how I handle arguments with getopt: I use switch within a foreach at the beginning of a program.

<?php

$opts 
getopt('hs:');

// Handle command line arguments
foreach (array_keys($opts) as $opt) switch ($opt) {
  case 
's':
    
// Do something with s parameter
    
$something $opts['s'];
    break;

  case 
'h':
    
print_help_message();
    exit(
1);
}

print 
"$something\n";

?>

Gu1ll4um3r0m41n at nospam dot xx (2007-04-23 11:40:20)

<?php
function getopt_($opts$argv) {
    
$opts_array explode(':'$opts);
    foreach(
$opts_array as $opt) {
        
$key array_search($opt$argv);
        if(
$key && !in_array($argv[$key+1], $opts_array)) {
            
$result[$opt] = trim($argv[$key+1]);
        } elseif(
$key) {
            
$result[$opt] = '';
        }
    }
    return 
$result;
}
$result getopt('-h:-o:--help'$argv);
?>

koenbollen at gnospamail dot com (2007-03-29 00:51:44)

After you use the getopt function you can use the following script to update the $argv array:
<?php
  $options 
"c:ho:s:t:uvV";
  
$opts getopt$options );
  foreach( 
$opts as $o => $a )
  {
    while( 
$k array_search"-" $o$argv ) )
    {
      if( 
$k )
        unset( 
$argv[$k] );
      if( 
preg_match"/^.*".$o.":.*$/i"$options ) )
        unset( 
$argv[$k+1] );
    }
  }
  
$argv array_merge$argv );
?>
Note: I used the array_merge function to reindex the array's keys.

Cheers, Koen Bollen

(2007-01-17 11:59:56)

About getopt(String):
Parses the command-line arguments into an associative array, using the function's String parameter to specify arguments and options, thus:
* arguments are specified as any letter followed by a colon, e.g. "h:".
* arguments are returned as "h" => "value".
* options are specified as any letter not followed by a colon, e.g. "r".
* options are returned as "r" => (boolean) false.
Also note that:
1) Options or arguments not passed in the command-line parameters are not set in the returned associative array.
2) Options or arguments present in the command-line arguments multiple times are returned as an enumerated array within the returned associative array.

yarco dot w at gmail dot com (2006-10-24 19:08:23)

You cant use this function twice or more.

For example:
<?php
print_r
(getopt('a:b:c:'));
print_r(getopt('d:e:f:'));
?>

You would be confused by the result.
[yarco@localhost ~]$ php test3.php -a love -b love -d love
Array
(
    [a] => love
    [b] => love
)
Array
(
    [e] => love
    [d] => love
)

joey at alegria dot co dot jp (2006-04-30 09:57:45)

There are 2 simpler (and much faster) methods for getting good getopt() operation without creating your own handler.
1. Use the Console_Getopt PEAR class (should be standard in most PHP installations) which lets you specify both short and long form options as well as whether or not arguments supplied to an option are themselves 'optional'. Very simple to use and requires very little code to operate compaired to writing own handler.
2. If you cannot load external PEAR objects, use your shell's getopt() functions (which in BASHs case work very well) to process options and have your shell script then call your PHP script with a rigid argument structure that is very easy for PHP to digest such as:
% myfile.php -a TRUE -b FALSE -c ARGUMENT ...
If the initial arguments are invalid you can have the shell script return an error without calling the PHP script. Sounds convoluted but is a very simple solution and in fact PHP's own % pear command uses this method. /usr/bin/pear is a shell script that does some simle checking before calling pearcmd.php and repassing the arguments on to it.
The second method is by far the best for portability because it allows a single shell script to check a few things like your PHP version and respond acordingly e.g. does it call your PHP4 or PHP5 compatible script? Also, because getopt() is not available on Windows, The second solution allows you to do Windows specific testing as a BAT file (as oposed to BASH, ZSH or Korn on UNIX).

daevid at daevid dot com (2005-05-31 13:11:16)

This is how I parse command line options:

<?php
$OPTION
['debug'] = false;
$OPTION['test'] = false;
$OPTION['force'] = "";

//loop through our arguments and see what the user selected
   
for ($i 1$i $_SERVER["argc"]; $i++)
   {
       switch(
$_SERVER["argv"][$i])
       {
           case 
"-v":
           case 
"--version":
            echo  
$_SERVER['argv'][0]." v07.19.04 06:10 PM\n";
            exit;
               break;
        
           case 
"--debug":
               
$OPTION['debug'] = true;
               break;
        
           case 
"--force":
               
$OPTION['force'] = " --force";
               break;
        
           case 
"--db":
           case 
"--database":
           case 
"--id":
            if ( 
is_numeric($_SERVER['argv'][$i+1]) )
                
$OPTION['CompanyID'] = intval($_SERVER['argv'][++$i]);
            else 
//it must be a database name
                
$OPTION['CompanyDB'] = $_SERVER['argv'][++$i];
               break;

           case 
"--base":
           case 
"--basedir":
           case 
"--dir":
               
$OPTION['basedir'] = $_SERVER["argv"][++$i];
               break;
        
           case 
"--test":
               
$OPTION['test'] = true;
               break;
        
           case 
"-?":
           case 
"-h":
           case 
"--help":
?>
This will print any .txt files, process any .sql files and 
execute any .php files found starting from the base directory
'<?=$OPTION['basedir']?>' in alphabetical order.

 Usage: <?php echo $_SERVER['argv'][0]; ?> <option>

 --help, -help, -h, or -?     to get this help.
 --version                    to return the version of this file.
 --debug                    to turn on output debugging.
 --test                        to fake the SQL and PHP commands.
 --force                    to ignore SQL errors and keep on going.
 --db [CompanyDB]            to apply to only this [CompanyDB].
 --id [CompanyID]            to apply to only this [CompanyID].
 --basedir [directory]        to change base directory from <?=$OPTION['basedir']?>.
 Omitting the CompanyID or CompanyDB will cause ALL Company DB's to be updated.

 There are global files and per-company files. Global files are applied to global
 databases (see list below). Their filename contains a tag that reflects the database
 to apply them against. Per-company files are applied against databases. Their
 filename contains a tag that reads 'COMPANY'. Files should be in <?=$OPTION['basedir']?>;
 Global files that are understood:
<?=$OPTION['basedir']?> 
 <?php foreach ($GLOBAL_SQL_FILES as $sqlFile) echo $sqlFile."   "?>

<?php
               
exit;
               break;
       }
   } 
//parse arguments

//    print_r($OPTION);
?>

chris at tiny dot net (2004-04-23 19:17:18)

"phpnotes at kipu dot co dot uk" and "tim at digicol dot de" are both wrong or misleading.  Sean was correct.  Quoted space-containing strings on the command line are one argument.  It has to do with how the shell handles the command line, more than PHP.  PHP's getopt() is modeled on and probably built upon the Unix/POSIX/C library getopt(3) which treats strings as strings, and does not break them apart on white space.

Here's proof:

$ cat opt.php
#! /usr/local/bin/php
<?php
$options 
getopt("f:");
print_r($options);
?>
$ opt.php -f a b c
Array
(
    [f] => a
)
$ opt.php -f 'a b c'
Array
(
    [f] => a b c
)
$ opt.php -f "a b c"
Array
(
    [f] => a b c
)
$ opt.php -f a\ b\ c
Array
(
    [f] => a b c
)
$

易百教程