En este post te voy a mostrar a leer y a parsear los argumentos de la línea de comandos, los mismos que se le pasan a un script de PHP; para ello veremos la variable $argv
y la función getopt
.
Podemos obtener los argumentos a través de su nombre o a través de su índice en un arreglo; la primera opción es la que nos va a interesar más.
PHP puede ejecutarse en la línea de comandos, y así como cualquier otro programa que se ejecuta por comandos, se le pueden pasar argumentos.
Como sabemos, los archivos de PHP pueden ejecutarse desde la terminal. La sintaxis es:
php archivo.php
Y a ese script le podemos pasar argumentos. Por ejemplo:
php archivo.php --nombre="luis"
O algo como:
php archivo.php luis
El número de argumentos puede variar, y los mismos se usan para indicar opciones del programa que usamos.
Los argumentos están en la variable $argv
en forma de arreglo; y el número de argumentos está en la variable $argc
.
Siempre habrá al menos un argumento incluso si el usuario no lo especifica, y es el nombre del archivo.
Es decir, en $argv[0]
estará el nombre del script. Y para la siguiente ejecución:
php archivo.php
$argv[0]
será igual a archivo.php
.
Si pasamos más argumentos (separados por espacios) los mismos serán colocados en ese orden en el arreglo. Veamos un ejemplo:
<?php
echo "Hay $argc argumentos\n";
foreach ($argv as $argumento) {
echo "Recibido un argumento: $argumento \n";
}
/*
Salida:
Hay 3 argumentos
Recibido un argumento: argumentos.php
Recibido un argumento: Hola
Recibido un argumento: mundo
*/
Así que para validar el número de argumentos podemos usar $argc
. Y para acceder a los argumentos, usar $argv[1]
, $argv[2]
, etcétera.
Hay otra manera más bonita de acceder a los argumentos; y digo bonita porque es más cómoda para nosotros y para quien use nuestro script. Aquí lo explico y dejo ejemplos abajo.
Se trata de la función getopt
, la cual devuelve un arreglo de las opciones, dependiendo de las letras que le pasemos.
Es decir, se invoca así:
$argumentos = getopt("a:b::c");
No te preocupes, te lo explico.
La función va a tomar cada letra y la va a tomar como una opción. Pero esa letra tiene 3 significados.
php archivo.php -a "valor"
php archivo.php -b "otro valor opcional"
sí
y no
, o un booleano. Por ejemplo: php archivo.php -c
, ya que no lleva valor, solo se indica o no su presencia.Por cierto, esta función permite también los argumentos largos en forma de arreglo (podría ser php archivo.php --nombre "Luis Cabrera"
) como segundo argumento, eso lo veremos abajo.
Para saber si el usuario pasó o no pasó los argumentos, usamos isset o empty; es un trabajo con comparaciones y arreglos.
En resumen, las opciones cortas son con un guión y las largas con dos guiones. Ambas opciones soportan la sintaxis de bandera, con valor, o con valor opcional.
Cabe mencionar que en los argumentos con getopt no podemos acceder al nombre del script, pero sí con $argv
y esa variable siempre está disponible (o al menor en un escenario común)
Ahora veamos algunos ejemplos.
Imaginemos un script para enviar un correo electrónico en donde se debe especificar:
La forma de invocar al script podría ser así:
# Sin guardar:
php correo.php -d parzibyte@gmail.com -a Ayuda -m "Necesito un poco de ayuda con este script de PHP"
# Guardar
php correo.php -d parzibyte@gmail.com -a Ayuda -m "Necesito un poco de ayuda con este script de PHP" -g
De esta manera podríamos hacer unos fabulosos scripts con PHP y los argumentos de la línea de comandos.
Ahora veamos el script:
<?php
// Recuerda:
// Si tiene : entonces debe tener un valor
// Si tiene :: entonces su valor es opcional
// Si no tiene : ni :: entonces quiere decir que la opción es una bandera, no un valor
// Las opciones son:
// -d destinatario
// -a Asunto del correo
// -m El mensaje del correo
// -g Si se especifica la opción, el correo será guardado
$argumentos = getopt("d:a:m:g");
// Las opciones deben estar establecidas
// Si no, salimos e indicamos el modo de uso
if (
!isset($argumentos["d"])
||
!isset($argumentos["a"])
||
!isset($argumentos["m"])
) {
exit("Modo de uso:
-d destinatario
-a Asunto del correo
-m El mensaje del correo
-g Si se especifica la opción, el correo será guardado");
}
// Hasta aquí todas las opciones están bien establecidas
$destinatario = $argumentos["d"];
$asunto = $argumentos["a"];
$mensaje = $argumentos["m"];
$guardar = isset($argumentos["g"]);
echo "Enviar correo" . PHP_EOL;
echo "Destinatario: $destinatario" . PHP_EOL;
echo "Asunto: $asunto" . PHP_EOL;
echo "Mensaje: $mensaje" . PHP_EOL;
echo "¿Guardar?: " . ($guardar ? "Sí" : "No") . PHP_EOL;
La mayor parte del script es validación. Si un dato obligatorio no está establecido, salimos del script e indicamos su forma de uso.
Como ves, las opciones del destinatario, mensaje y asunto son obligatorias con valor, en cambio, la opción de guardar es una bandera (no nos importa su valor, solo comprobamos si existe o no con isset
).
Para acceder a los datos accedemos a $argumentos["opción"];
La salida es:
Como lo dije, getopt
acepta un segundo argumento en forma de arreglo que indica los argumentos que se pueden pasar de forma larga usando dos guiones.
De este modo podemos hacer nuestros scripts más bonitos, pues las opciones serán más expresivas.
Veamos otro ejemplo que usa getopt de PHP para leer ambas opciones:
<?php
// Recuerda:
// Si tiene : entonces debe tener un valor
// Si tiene :: entonces su valor es opcional
// Si no tiene : ni :: entonces quiere decir que la opción es una bandera, no un valor
// Las opciones son:
// -d destinatario
// -a Asunto del correo
// -m El mensaje del correo
// -g Si se especifica la opción, el correo será guardado
$argumentos = getopt("d:a:m:g", array(
"destinatario:",
"asunto:",
"mensaje:",
"guardar",
));
// Las opciones deben estar establecidas
// Si no, salimos e indicamos el modo de uso
if (
!(isset($argumentos["d"]) || isset($argumentos["destinatario"]))
||
!(isset($argumentos["a"]) || isset($argumentos["asunto"]))
||
!(isset($argumentos["m"]) || isset($argumentos["mensaje"]))
) {
exit("Modo de uso:
-d --destinatario Correo del destinatario
-a --asunto Asunto del correo
-m --mensaje El mensaje del correo
-g --guardar Si se especifica la opción, el correo será guardado");
}
// Hasta aquí todas las opciones están bien establecidas
$destinatario = isset($argumentos["d"]) ? $argumentos["d"] : $argumentos["destinatario"];
$asunto = isset($argumentos["a"]) ? $argumentos["a"] : $argumentos["asunto"];
$mensaje = isset($argumentos["m"]) ? $argumentos["m"] : $argumentos["mensaje"];
$guardar = isset($argumentos["g"]) || isset($argumentos["guardar"]);
echo "Enviar correo" . PHP_EOL;
echo "Destinatario: $destinatario" . PHP_EOL;
echo "Asunto: $asunto" . PHP_EOL;
echo "Mensaje: $mensaje" . PHP_EOL;
echo "¿Guardar?: " . ($guardar ? "Sí" : "No") . PHP_EOL;
Ahora estamos tomando ambas opciones o tipos de argumentos (si no existe la versión corta, buscamos la larga). Esta manera es más específica y amigable con el usuario final.
La ejecución ahora puede ser usando la opción corta como -d
o --destinatario
, y lo mismo para los otros argumentos.
php correo2.php --destinatario parzibyte@gmail.com -a Ayuda -m "Necesito ayuda con esta app" --guardar
php correo2.php --destinatario=parzibyte@gmail.com -a Ayuda -m "Necesito ayuda con esta app" --guardar
php correo2.php --destinatario=parzibyte@gmail.com --asunto "Ayuda JS" -m "Necesito ayuda con esta app" --guardar
Al llamarlo se ve la siguiente salida:
Como puedes ver, los argumentos largos pueden ser pasados con un signo de igual, separándolos con un espacio y también encerrando el argumento entre comillas, en caso de que este lleve espacios.
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.