PHP 5.3 : getopt : Paramètres en ligne de commande
7 novembre 2008 —Les exemples correspondant à ce point se trouvent dans le répertoire "getopt".
Sommaire
Getopt ?
Introduction
La fonction getopt, qui existe depuis PHP 4.3, permet de récupérer dans un script PHP les paramètres qui lui ont été passés en ligne de commande.
Elle a donc son utilité en mode CLI -- par exemple, pour développement de traitements batch -- et non au niveau des sites Web en eux-mêmes.
La fonction getopt
accepte deux types de paramètres :
- Les options << courtes >>, d'une seule lettre :
mon-programme.php -a -b 10 -cde
- Les options << longues >>, de plusieurs lettres :
mon-programme.php --option-longue --option=10
[1]
Mais le support des options longues, en PHP <= 5.2, était limité à seulement quelques systèmes. En particulier, il n'existait pas sous Windows -- et n'était pas forcément actif sous Linux.
Nouveautés en PHP 5.3
PHP 5.3 introduit plusieurs nouvelles fonctionnalités au niveau de la fonction getopt
:
- Elle supporte à présent les options longues, en natif, sous tous OS,
- Elle supporte à présent les options << optionnelles >>,
- Et <<
=
>> a été ajouté comme séparateur nom d'option / valeur.
Options courtes
Commençons par un tour des options courtes.
Une option courte est une option sur une seule lettre précédée d'un tiret ; et il est possible de << raccourcir >> l'écriture, en regroupant plusieurs options courtes et ne les préfixant que d'un seul tiret.
Dans le cas où l'on souhaite travailler avec des options courtes, il convient de fournir en premier paramètre à getopt
une chaîne de caractères décrivant ceux-ci :
- Chacune des lettres de cette chaine sera considérée comme une option attendue par le script,
- Avec la possibilité de spécifier si le paramètre est optionnel ou non :
- Une lettre suivie de <<
:
>> codera pour un paramètre obligatoire, - Et une lettre suivie de <<
::
>> codera -- à partir de PHP 5.3 -- pour un paramètre optionnel.
- Une lettre suivie de <<
Voici un exemple :
$options = getopt('ab:c:d::');
var_dump($options);
Ici, nous souhaitons récupérer depuis les paramètres passés en ligne de commande :
- Une option
a
, - Des options
b
etc
, explicitement déclarées comme obligatoires, - Et un option
d
, déclarée comme optionnelle.
Voyons ce que l'on obtient avec plusieurs appels à notre script :
$ php ./getopt/getopt-1.php -a -b10 -c=10 -d array(4) { ["a"]=> bool(false) ["b"]=> string(2) "10" ["c"]=> string(2) "10" ["d"]=> bool(false) }
Nous n'avons pas spécifié si l'option a
devait être obligatoire ou optionnelle...
a
ne sera jamais récupérée, quoi que nous passions au script : il nous fallait faire suivre a
de :
ou de ::
, au choix.
Nous avons spécifié -b10
en paramètre. getopt
a reconnu cette option et cette syntaxe, et a affecté 10
à l'option b
, comme attendu.
Nous avons ensuite utilisé -c=10
:
- En PHP 5.3,
getopt
reconnait=
comme séparateur nom d'option / valeur, et affecte10
à l'optionc
. - En PHP 5.2,
=
n'est pas admis comme séparateur, et l'optionc
aurait été considérée comme valant=10
!
Et enfin, nous avons spécifié l'option -d
, optionnelle, sans lui fournir de valeur.
getopt
la considère donc comme fausse.
Essayons maintenant de passer le paramètre optionnel :
$ php ./getopt/getopt-1.php -a -b10 -c=10 -d=glop array(4) { ["a"]=> bool(false) ["b"]=> string(2) "10" ["c"]=> string(2) "10" ["d"]=> string(4) "glop" }
Cette fois-ci, la valeur de d
a bien été récupérée : << glop >> !
Encore une fois, notez que le séparateur =
n'est accepté que depuis PHP 5.3 : ici encore, en PHP 5.2, l'option d
aurait eu pour valeur =glop
!
Encore un, en ne passant plus que les deux premiers paramètres :
$ php ./getopt/getopt-1.php -a -b10 array(2) { ["a"]=> bool(false) ["b"]=> string(2) "10" }
L'option d
, qui était déclarée comme optionnel et n'a pas été passée au script, n'est pas présente dans la liste des options retournées par getopt
.
Par contre, on notera que c
, qui n'était pas déclarée comme optionnelle, n'y est pas non plus : c'est toujours à vous de gérer les situations où vos utilisateurs ne font pas ce que vous souhaitiez !
Note : le comportement en PHP 5.2 est strictement identique, à ce niveau.
Et, cette fois, en regroupant nos options courtes :
$ php ./getopt/getopt-1.php -ab10 -c=10 array(3) { ["a"]=> bool(false) ["b"]=> string(2) "10" ["c"]=> string(2) "10" }
Comme nous aurions pu nous y attendre, nous pouvons regrouper les options courtes ^^
Ici encore, nous avons le même comportement qu'en 5.2, pour ce qui est du regroupement des options courtes, du moins.
(J'ai déjà parlé plus haut du séparateur =
non reconnu en 5.2 ; je ne reviendrai pas dessus)
Options longues
Passons à présent aux options longues : la grande nouveauté est qu'elles sont supportées, en natif, sur tous systèmes, et ne sont plus dépendantes des fonctionnalités sous-jacences de l'OS.
Plus simplement, cela signifie qu'il est possible d'utiliser des options longues avec getopt
sur plate-forme Windows.
Comme exemple, je prendrai la portion de code suivante :
$options = getopt(null, array(
'aa',
'bb:',
'cc:',
'dd::',
));
var_dump($options);
Le premier paramètre passé à getopt
est null
: nous ne souhaitons pas travailler avec des options courtes.
Ensuite, nous reprenons les mêmes options que plus haut dans notre exemple d'options courtes, en doublant simplement le nom de chaque option, pour les allonger ^^
Donc :
- Une première option
aa
, - Des options
bb
etcb
, explicitement déclarées comme obligatoires, - Et un option
dd
, déclarée comme optionnelle.
La différence entre la déclaration des options courtes et des options longues est que, dans le premier cas, on les regroupe au sein d'une unique chaine de caractères, alors que, dans le second cas, nous utilisons une liste -- c'est plus simple pour déterminer quels sont les noms des options ^^
Premier exemple d'appel :
$ php ./getopt/getopt-2.php --aa --bb 10 --cc=10 --dd=glop array(4) { ["aa"]=> bool(false) ["bb"]=> string(2) "10" ["cc"]=> string(2) "10" ["dd"]=> string(4) "glop" }
Nous n'avons toujours pas spécifié si aa
devait être obligatoire ou optionnelle...
Comme plus haut avec a
, donc, aa
ne sera jamais récupérée, quoi que nous passions au script : il nous fallait faire suivre aa
de :
ou de ::
, au choix.
Nous avons cette fois-ci spécifié -bb 10
en paramètre. getopt
a reconnu cette option et cette syntaxe, et a affecté 10
à l'option bb
, comme attendu.
Nous avons ensuite utilisé --cc=10
:
- En PHP 5.3,
getopt
reconnait=
comme séparateur nom d'option / valeur, et affecte10
à l'optionc
. - En PHP 5.2, j'aurais aimé tester... Mais la version de PHP 5.2 fournie par Ubuntu ne supporte pas les options longues, et renvoi un warning : -- oui, sous Linux sous non plus, les options longues ne sont pas forcément supportées ^^
$ php ./getopt/getopt-2.php --aa --bb 10 --cc=10 --dd=glop Warning: getopt(): No support for long options in this build in /home/squale/developpement/tests/php53/getopt/getopt-2.php on line 10 Call Stack: 0,0005 60384 1. {main}() /home/squale/developpement/tests/php53/getopt/getopt-2.php:0 0,0005 60960 2. getopt(string(0), array(4)) /home/squale/developpement/tests/php53/getopt/getopt-2.php:10 array(0) { }
Et enfin, nous avons spécifié l'option -dd
, optionnelle, en lui fournissant une valeur, qui a été extraite avec succès : << glop >>.
Second essai, sans passer du tout l'option optionnelle dd
:
$ php ./getopt/getopt-2.php --aa --bb 10 --cc=10 array(3) { ["aa"]=> bool(false) ["bb"]=> string(2) "10" ["cc"]=> string(2) "10" }
Ici encore, si une option non-obligatoire n'est pas passée, elle ne sera pas présente dans la liste retournée par getopt
: à vous de gérer ce type de situation, donc !
Et plus loin, en ne fournissant pas non plus l'option bb
, qui était pourtant obligatoire :
$ php ./getopt/getopt-2.php --cc=10 array(1) { ["cc"]=> string(2) "10" }
C'est toujours à vous de vous débrouiller !
Cela n'aura que peu d'importance pour ceux d'entre nous qui font du développement Web sans avoir de traitement batch évolués derrière, mais PHP 5.3 ajoute enfin à la fonction getopt
-- et au support de la ligne de commande, donc -- les fonctionnalités dont il était difficile de se passer !
Un peu tard, peut-être : devant la faiblesse de getopt
, certains Frameworks ont déjà pris sur eux de fournir des fonctionnalités poussées pour ce qui est du support des options en CLI !
Note
[1] ça y est, je maudis Dotclear et les plugins que j'ai installé, qui convertissent les doubles-tirets soit en mise en forme << barré >> soit en tirets-quadratins ^^ ; Mais heureusement, pas dans les portions de code-source !