cli array argumentos argument arg php getopt

array - Después de usar getopt() de PHP, ¿cómo puedo saber qué argumentos quedan?



php cli arguments array (4)

Comenzando con PHP 7.1, getopt admite un &$optind opcional de referencia, &$optind , que contiene el índice donde se detuvo el análisis de argumentos. Esto es útil para mezclar banderas con argumentos posicionales. P.ej:

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 )

Bien, PHP tiene una función incorporada getopt() que devuelve información sobre las opciones de programa que el usuario ha proporcionado. Solo que, a menos que me esté faltando algo, ¡está completamente borked! Del manual:

El análisis de opciones terminará en la primera no-opción encontrada, todo lo que sigue se descarta.

Por lo tanto, getopt() devuelve una matriz solo con las opciones válidas y analizadas . Aún puede ver toda la línea de comando original mirando $argv , que permanece sin modificar, pero ¿cómo puede saber dónde en la línea de comando getopt() dejó de analizar los argumentos? Es esencial saber esto si desea tratar el resto de una línea de comandos como otras cosas (como, por ejemplo, nombres de archivos).

Aquí hay un ejemplo ...

Supongamos que quiero configurar un script para aceptar los siguientes argumentos:

Usage: test [OPTION]... [FILE]... Options: -a something -b something -c something

Entonces podría llamar a getopt() así:

$args = getopt( ''abc'' );

Y, si ejecuto el guión así:

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

Debería esperar que me devuelvan la siguiente matriz:

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

Entonces, la pregunta es: ¿cómo diablos se supone que debo saber que los tres argumentos de FILE sin opción y sin analizar comienzan en $argv[ 3 ] ?


Echa un vistazo a GetOptionKit para deshacerte del análisis de la bandera.

http://github.com/c9s/GetOptionKit

GetOptionKit se puede integrar fácilmente en su secuencia de comandos de línea de comandos. Es compatible con la restricción de tipo, la validación de valores y así sucesivamente.


Nadie dijo que no tenías que usar Getopt. Puedes hacerlo de la manera que más te guste:

$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";

Siempre lo hago así y funciona. Además puedo hacer lo que quiera con él.


Se puede usar lo siguiente para obtener cualquier argumento después de las opciones de la línea de comando. Puede usarse antes o después de invocar getopt() PHP sin cambios en el resultado:

# $options = getopt(''cdeh''); $argx = 0; while (++$argx < $argc && preg_match(''/^-/'', $argv[$argx])); # (no loop body) $arguments = array_slice($argv, $argx);

$arguments ahora contiene cualquier argumento que siga las opciones iniciales. Alternativamente, si no desea que los argumentos $argx en una matriz separada, $argx es el índice del primer argumento real: $argv[$argx] .

Si no hay argumentos, después de las opciones iniciales, entonces:

  • $arguments es una matriz vacía [] , y
  • count($arguments) == 0 , y
  • $argx == $argc .