Search code examples
phpgetopt

After using PHP's getopt(), how can I tell what arguments remain?


OK, So PHP has a built-in getopt() function which returns information about what program options the user has provided. Only, unless I'm missing something, it's completely borked! From the manual:

The parsing of options will end at the first non-option found, anything that follows is discarded.

So getopt() returns an array with the valid and parsed options only. You can still see the entire original command-line by looking at $argv, which remains unmodified, but how do you tell where in that command-line getopt() stopped parsing arguments? It is essential to know this if you want treat the remainder of a command-line as other stuff (like, e.g., file names).

Here's an example...

Suppose I want to set up a script to accept the following arguments:

Usage: test [OPTION]... [FILE]...

Options:
  -a  something
  -b  something
  -c  something

Then I might call getopt() like this:

$args = getopt( 'abc' );

And, if I ran the script like this:

$ ./test.php -a -bccc file1 file2 file3

I should expect to have the following array returned to me:

Array
(
    [a] =>
    [b] =>
    [c] => Array
        (
            [0] =>
            [1] =>
            [2] =>
        )
)

So the question is this: How on Earth am I supposed to know that the three unparsed, non-option FILE arguments start at $argv[ 3 ]???


Solution

  • Starting with PHP 7.1, getopt supports an optional by-ref param, &$optind, that contains the index where argument parsing stopped. This is useful for mixing flags with positional arguments. E.g.:

    user@host:~$ php -r '$i = 0; getopt("a:b:", [], $i); print_r(array_slice($argv, $i));' -- -a 1 -b 2 hello1 hello2
    Array
    (
        [0] => hello1
        [1] => hello2
    )