Подтвердить что ты не робот

После использования PHP getopt(), как я могу определить, какие аргументы остаются?

ОК, поэтому у PHP есть встроенная функция getopt(), которая возвращает информацию о том, какие параметры программы предоставил пользователь. Только, если я что-то не упустил, он полностью разорвался! Из руководства:

Анализ синтаксического разбора завершится с первой найденной опцией, все последующее отброшено.

Итак, getopt() возвращает массив только с действительными и разборными параметрами. Вы все еще можете увидеть всю исходную командную строку, посмотрев на $argv, которая остается неизменной, но как вы определяете, где в этой командной строке getopt() перестали разбираться в аргументах? Очень важно знать это, если вы хотите рассматривать остальную часть командной строки как другой материал (например, имена файлов).

Вот пример...

Предположим, что я хочу настроить script для принятия следующих аргументов:

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

Options:
  -a  something
  -b  something
  -c  something

Тогда я мог бы называть getopt() следующим образом:

$args = getopt( 'abc' );

И, если я запустил script следующим образом:

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

Я должен ожидать, что для меня вернется следующий массив:

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

Итак, вопрос заключается в следующем: как на Земле я должен был знать, что три аргумента без аргумента, без опций FILE начинаются с $argv[ 3 ]???

4b9b3361

Ответ 1

Начиная с PHP 7.1, getopt поддерживает необязательный параметр ref-ref, &$optind, который содержит индекс, где аргумент parsing остановлен. Это полезно для смешивания флагов с позиционными аргументами. Например:.

[email protected]:~$ 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
)

Ответ 2

Никто не сказал, что вы не используете getopt. Вы можете сделать это любым способом:

$arg_a = null; // -a=YOUR_OPTION_A_VALUE
$arg_b = null; // -b=YOUR_OPTION_A_VALUE
$arg_c = null; // -c=YOUR_OPTION_A_VALUE

$arg_file = null;  // -file=YOUR_OPTION_FILE_VALUE

foreach ( $argv as $arg )
{
    unset( $matches );

    if ( preg_match( '/^-a=(.*)$/', $arg, $matches ) )
    {
        $arg_a = $matches[1];
    }
    else if ( preg_match( '/^-b=(.*)$/', $arg, $matches ) )
    {
        $arg_b = $matches[1];
    }
    else if ( preg_match( '/^-c=(.*)$/', $arg, $matches ) )
    {
        $arg_c = $matches[1];
    }
    else if ( preg_match( '/^-file=(.*)$/', $arg, $matches ) )
    {
        $arg_file = $matches[1];
    }
    else
    {
        // all the unrecognized stuff
    }
}//foreach

if ( $arg_a === null )    { /* missing a - do sth here */ }
if ( $arg_b === null )    { /* missing b - do sth here */ }
if ( $arg_c === null )    { /* missing c - do sth here */ }
if ( $arg_file === null ) { /* missing file - do sth here */ }

echo "a=[$arg_a]\n";
echo "b=[$arg_b]\n";
echo "c=[$arg_c]\n";
echo "file=[$arg_file]\n";

Я всегда так делаю, и это работает. Более того, я могу делать все, что захочу.

Ответ 3

Для получения любых аргументов, следующих за параметрами командной строки, можно использовать следующие. Он может использоваться до или после вызова PHP getopt() без изменения результата:

# $options = getopt('cdeh');

$argx = 0;

while (++$argx < $argc && preg_match('/^-/', $argv[$argx])); # (no loop body)

$arguments = array_slice($argv, $argx);

$arguments теперь содержит любые аргументы, следующие за любыми ведущими опциями. В качестве альтернативы, если вы не хотите аргумент в отдельном массиве, то $argx является индексом первого фактического аргумента: $argv[$argx].

Если аргументов нет, после каких-либо ведущих опций:

  • $arguments - пустой массив [] и
  • count($arguments) == 0 и
  • $argx == $argc.

Ответ 4

Взгляните на GetOptionKit, чтобы избавиться от разбора флага.

http://github.com/c9s/GetOptionKit

GetOptionKit может быть легко интегрирован в вашу командную строку script. Он поддерживает ограничение типов, валидацию значений и т.д.