NOM

CGI - Classe simple pour CGI (Common Gateway Interface)


SYNOPSIS

  # script CGI script pour creer un formulaire
  # puis renvoyer les valeurs fournies.
  use CGI qw/:standard/;
  print header,
        start_html('Un exemple simple'),
        h1('Un exemple simple'),
        start_form,
        "Quel est votre nom ? ",textfield('nom'),p,
        "Quels sont les mots cles ?", p,
        checkbox_group(-name=>'mots',
                       -values=>['eenie','meenie','minie','moe'],
                       -defaults=>['eenie','minie']), p,
        "Quelle est votre couleur favorite ? ",
        popup_menu(-name=>'couleur',
                   -values=>['rouge','vert','bleu','chartreuse']),p,
        submit,
        end_form,
        hr;
   if (param()) {
       print "Votre nom est ",em(param('nom')),p,
             "Les mots cles sont : ",em(join(", ",param('mots'))),p,
             "Votre couleur favorite est :",em(param('couleur')),
             hr;
   }


RÉSUMÉ

Cette bibliothèque perl utilise les objets perl5 pour faciliter la création de formulaires Web et permettre l'analyse de leur contenu. Ce package définit des objets CGI, des entités qui contiennent les valeurs de la requête courante ainsi que d'autres variables d'état. En utilisant le méthode de l'objet CGI, vous pouvez examiner les mots-clé et les paramètres envoyés à votre script et créer un formulaire dont les valeurs initiales sont celles de la requête courante (en préservant donc les informations d'état). Le module propose des fonctions pour produire du HTML propre, permettant ainsi de réduire le code nécessaire et les erreurs sous-jacentes. Il intègre aussi des fonctions pour quelques-unes des fonctionnalités les plus avancées des scripts CGI comme le téléchargement de fichiers, les cookies, les feuilles de styles en cascade (CSS - cascading style sheets), le « SERVER PUSH » et les frames.

CGI.pm accepte aussi le style de programmation orienté fonction pour ceux qui n'ont pas besoin des possibilités de l'orienté objet.

La version courante de CGI.pm est disponible à :

  http://www.genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html
  ftp://ftp-genome.wi.mit.edu/pub/software/WWW/


DESCRIPTION

Style de programmation

CGI.pm propose deux styles de programmation : la programmation orientée objet et la programmation orientée fonction. En programmation orientée objet, vous créez un ou plusieurs objets CGI puis vous utilisez leurs méthodes pour créer les différents éléments de la page. Chaque objet CGI commence avec la liste des paramètres nommés tels qu'ils ont été passés à votre script CGI par le serveur. Vous pouvez modifier ces objets, les sauver dans un fichier ou une base de données et les recréer. Puisque chaque objet correspond à un ``état'' du script CGI et puisque la liste des paramètres de chaque objet est différente de celle des autres, cela vous permet d'enregistrer l'état du script pour le rétablir plus tard.

Par exemple, en utilisant le style de programmation orienté objet, voici comment créer une simple page ``Hello World'' :

   #!/usr/local/bin/perl -w
   use CGI;                             # chargement du module CGI
   $q = new CGI;                        # creation d'un nouvel objet CGI
   print $q->header,                    # creation de l'en-tete HTTP
         $q->start_html('hello world'), # debut du HTML
         $q->h1('hello world'),         # titre de niveau 1
         $q->end_html;                  # fin du HTML

Avec le style de programmation orienté fonction, il existe un objet CGI par défaut avec lequel vous n'aurez que très rarement à interagir. Vous n'aurez qu'à appeler des fonctions pour retrouver les paramètres du CGI, créer des balises HTML, gérer les cookies et ainsi de suite. Cela vous fournit une interface de programmation propre mais limitée à un seul objet CGI à la fois. L'exemple suivant affiche la même page que précédemment mais en utilisant l'interface orientée fonction. Les principales différences sont que vous devez maintenant importer un ensemble de fonctions dans votre espace de nommage (habituellement les fonctions ``standard'') et que vous n'avez pas besoin de créer d'objet CGI.

   #!/usr/local/bin/perl
   use CGI qw/:standard/;           # chargement des fonctions standard de CGI
   print header,                    # creation de l'en-tete HTTP
         start_html('hello world'), # debut du HTML
         h1('hello world'),         # titre de niveau 1
         end_html;                  # fin du HTML

Les exemples dans ce document utilisent principalement le style orienté objet. Regardez COMMENT IMPORTER DES FONCTIONS pour trouver des informations importantes concernant la programmation orientée fonction avec CGI.pm.

Appel des routines de CGI.pm

La plupart des routines de CGI.pm acceptent plusieurs arguments, parfois jusqu'à 20 arguments optionnels ! Pour simplifier l'interface, toutes les routines utilisent un style d'appel par argument nommé qui ressemble à cela :

   print $q->header(-type=>'image/gif',-expires=>'+3d');

Chaque nom d'argument est précédé d'un tiret. Ni la casse (majuscules / minuscules) ni l'ordre n'ont d'importance dans la liste d'arguments. -type, -Type et -TYPE sont acceptables. En fait, seul le premier argument doit commencer par un tiret. Si un tiret est présent en tête du premier argument, CGI.pm l'ajoutera si nécessaire à tous les arguments qui suivent.

Plusieurs routines sont couramment appelées avec un seul argument. Dans ce cas, vous pouvez fournir cet argument sans préciser son nom. header() est l'une de ces routines. Dans son cas, son argument unique est le type de document.

   print $q->header('text/html');

Les autres routines de ce type sont documentées plus loin.

Certains arguments nommés doivent être des scalaires, d'autres des références vers un tableaux et d'autres encore des références à une table de hachage. Parfois, vous pouvez passer n'importe quel type d'argument et la routine en fera ce qui semblera le plus approprié. Par exemple, la routine param() est utilisée pour changer la valeur d'un paramètre CGI à une valeur simple ou multiple. Les deux cas sont présentés ci-dessous :

   $q->param(-name=>'veggie',-value=>'tomato');
   $q->param(-name=>'veggie',-value=>['tomato','tomahto','potato','potahto']);

Un grand nombre de routines dans CGI.pm ne sont pas réellement définies dans le module mais plutôt générées automatiquement si besoin. Ce sont les ``raccourcis HTML'', des routines qui génèrent des balises HTML destinées aux pages générées dynamiquement. Les balises HTML ont à la fois des attributs (les paires attribut=``valeur'' à l'intérieur de la balise elle-même) et un contenu (tout ce qu'il y a entre la balise ouvrante et la balise fermante). Par convention, pour distinguer les attributs du contenu, CGI.pm reçoit les attributs HTML comme un premier argument qui est une référence vers une table de hachage et interprète les autres arguments, s'ils existent, comme le contenu. Cela marche de la manière suivante :

   Code                           HTML produit
   ----                           --------------
   h1()                           <H1>
   h1('some','contents');         <H1>some contents</H1>
   h1({-align=>left});            <H1 ALIGN="LEFT">
   h1({-align=>left},'contents'); <H1 ALIGN="LEFT">contents</H1>

Les balises HTML sont décrites en détails plus loin.

De nombreux nouveaux utilisateurs de CGI.pm restent perplexes devant les différences de convention entre les appels des ``raccourcis HTML'' qui nécessitent des accolades autour des attributs de la balise HTML et les appels des autres routines qui gèrent leurs attributs sans les accolades. Ne vous affolez pas. Pour que ce soit plus pratique, les accolades sont optionnelles pour toutes les routines sauf pour les ``raccourcis HTML''. Si vous voulez, vous pouvez utiliser des accolades à l'appel de n'importe quelle routine qui prend des arguments nommés. Par exemple :

   print $q->header( {-type=>'image/gif',-expires=>'+3d'} );

Si vous utilisez l'option -w, vous récupérerez des messages d'avertissement vous indiquant que certains noms d'arguments de CGI.pm sont en conflit avec les fonctions Perl prédéfinies. Le cas le plus fréquent concerne l'argument -values qui est utilisé pour créer des menus à valeurs multiples, des groupes de boutons radio et autres. Pour contourner cet avertissement, vous avez plusieurs choix :

  1. Utiliser un autre nom pour l'argument, s'il existe. Par exemple, -value est un synonyme pour -values.

  2. Changer la casse, e.g. -Values

  3. Placer des apostrophes autour du nom de l'argument. e.g. '-values'

De nombreuses routines utiliseront tout de même les arguments nommés qu'elles ne reconnaissent pas. Par exemple, vous pouvez produire des champs d'en-tête HTTP non standard en fournissant les arguments nommés suivants :

  print $q->header(-type  =>  'text/html',
                   -cost  =>  'Three smackers',
                   -annoyance_level => 'high',
                   -complaints_to   => 'bit bucket');

Cela produira l'en-tête HTTP non standard suivant :

   HTTP/1.0 200 OK
   Cost: Three smackers
   Annoyance-level: high
   Complaints-to: bit bucket
   Content-type: text/html

Vous remarquerez que le caractère souligné (_) est automatiquement transformé en un tiret (-). Les routines de génération de HTML effectuent un autre type de transformation.

Cette fonctionnalité vous permet de vous adapter facilement aux changements fréquents du ``standard'' HTTP.

Création d'un nouvel objet requête (query en anglais) (style orienté objet)

     $query = new CGI;

Cela analysera l'entrée (à la fois pour les méthodes POST et GET) et stockera le résultat dans un objet perl5 appelé $query.

Création d'un nouvel objet requête à partir d'un fichier

     $query = new CGI(INPUTFILE);

Si vous fournissez un descripteur de fichier (filehandle) à la méthode new(), elle lira les paramètres à partir de ce fichier (ou STDIN ou ce que vous voulez). Ce fichier peut être sous n'importe laquelle des formes décrites plus bas (i.e. une série de paires TAG=VALUE délimitées par des passages à la ligne fonctionnera). Un fichier de ce type est facilement créé par la méthode save() (voir plus bas). Plusieurs enregistrements peuvent être enregistrés et relus.

Les puristes de Perl seront contents d'apprendre que la méthode accepte aussi les références vers un descripteur de fichier ou même les références vers un type universel (typeglob) référençant un descripteur de fichier, qui est le moyen ``officiel'' pour passer un descripteur de fichier :

    $query = new CGI(\*STDIN);

Vous pouvez aussi initialiser l'objet CGI avec un objet Filehandle ou IO::File.

Si vous utilisez l'interface orientée fonction et que vous voulez récupérer l'état de votre objet CGI à partir d'un descripteur de fichier, il vous faudra utiliser restore_parameters(). Cela réinitialisera l'objet CGI à partir du descripteur de fichier fourni.

    open (IN,"test.in") || die;
    restore_parameters(IN);
    close IN;

Vous pouvez aussi initialiser l'objet requête à partir d'une référence à une table de hachage :

    $query = new CGI( {'dinosaur'=>'barney',
                       'song'=>'I love you',
                       'friends'=>[qw/Jessica George Nancy/]}
                    );

ou à partir d'une chaîne de requête formatée correctement en tenant compte du codage des caractères dans les URL :

    $query = new CGI('dinosaur=barney&color=purple');

ou à partir d'un objet CGI préexistant (actuellement cela clonera la liste des paramètres mais aucun des autres champs spécifiques) :

    $old_query = new CGI;
    $new_query = new CGI($old_query);

Pour créer une requête vide, initialisez la à partir d'une chaîne vide ou d'une table de hachage vide :

   $empty_query = new CGI("");
       - ou -
   $empty_query = new CGI({});

Obtenir une liste de mots-clé à partir de la requête

     @keywords = $query->keywords

Si le script est appelé comme résultat d'une recherche <ISINDEX>, les mots-clé demandés peuvent être récupérés sous la forme d'un tableau grâce à la méthode keywords().

Obtenir les noms de tous les paramètres passés à votre script

     @names = $query->param

Si le script est appelé avec une liste de paramètres (e.g. ``name1=value1&name2=value2&name3=value3''), la méthode param() retournera une liste composée des noms des paramètres. Si le script est appelé comme un script <ISINDEX> et contient une chaîne sans esperluette (e.g. ``value1+value2+value3''), il n'y aura qu'un seul paramètre appelé ``keywords'' et contenant les mots-clé séparés par des ``+''.

REMARQUE : à partir de la version 1.5, le tableau des paramètres nommés retourné devrait être dans le même ordre que celui soumis par le navigateur. En général, cet ordre est le même que l'ordre d'apparition des paramètres dans le formulaire (par contre, cela ne fait pas partie des spécifications et ne peut donc être garanti).

Obtenir la valeur ou les valeurs d'un seul paramètre nommé

    @values = $query->param('foo');
              - ou -
    $value = $query->param('foo');

Passer un seul argument à la méthode param() pour obtenir la valeur de ce paramètre nommé. Si le paramètre est multivalué (e.g. une sélection multiple dans une liste déroulante), vous pouvez demander à recevoir un tableau. Sinon la méthode retourne une seule valeur.

Si la valeur n'est pas fournie par la chaîne de requête, comme dans les requêtes ``name1=&name2='' ou ``name1&name2'', elle sera retournée comme une chaîne vide. Cette fonctionnalité existe depuis la version 2.63.

Changer la ou les valeurs d'un paramètre nommé

    $query->param('foo','un','tableau','de','valeurs');

Cela positionne la valeur du paramètre nommé 'foo' à un tableau de valeurs. C'est l'un des moyens de changer la valeur d'un champ APRÈS une première invocation du script. (Un autre moyen consiste à utiliser l'argument nommé -override qui est accepté par toutes les méthodes qui génèrent des éléments de formulaires.)

param() reconnaît aussi un style d'appel par argument nommé décrit plus en détail plus loin :

    $query->param(-name=>'foo',-values=>['un','tableau','de','valeurs']);
                              - ou -
    $query->param(-name=>'foo',-value=>'la valeur');

Ajouter des valeurs supplémentaires à un paramètre nommé

   $query->append(-name=>'foo',-values=>['des','valeurs','en plus']);

Cela ajoute une valeur ou une liste de valeurs au paramètre nommé. Les valeurs sont ajoutées à la fin des valeurs précédentes du paramètre nommé si elles existent déjà. Sinon le paramètre est créé. Notez bien que cette méthode ne reconnaît que la syntaxe d'appel par argument nommé.

Importer tous les paramètres dans un espace de nommage

   $query->import_names('R');

Cela crée une série de variables dans l'espace de nommage 'R'. Par exemple $R::foo, @R::foo. Pour une liste de mots-clé, une variable @R::keywords sera créée. Si aucun espace de nommage n'est spécifié, la méthode utilisera l'espace 'Q'. ATTENTION : n'importez rien dans 'main' ; c'est un énorme trou de sécurité !!!!!

Dans les versions précédentes, cette méthode s'appelait import(). Depuis la version 2.20, ce nom a été complètement supprimé pour éviter un conflit avec l'opérateur prédéfini du module Perl import.

Supprimer complètement un paramètre

    $query->delete('foo');

Cela supprimera complètement ce paramètre. Cela est parfois utile pour supprimer certains paramètres que vous ne voulez pas renvoyer entre différents appels du script.

Si vous utilisez l'interface par appel de fonctions, utilisez ``Delete()'' à la place pour éviter un conflit avec l'opérateur Perl prédéfini delete.

Supprimer tous les paramètres

   $query->delete_all();

Cela effacera complètement tous les paramètres de l'objet CGI. C'est pratique pour s'assurer que ce sont les valeurs par défaut qui seront utilisées lorsque vous créerez votre formulaire.

Utilisez Delete_all() à la place si vous utilisez l'interface par appel de fonctions.

Accès direct à la liste des valeurs d'un paramètre

   $q->param_fetch('address')->[1] = '1313 Mockingbird Lane';
   unshift @{$q->param_fetch(-name=>'address')},'George Munster';

Si vous avez besoin d'accéder à la liste des valeurs d'un paramètre d'une manière non prévue par les méthodes précédentes, vous pouvez obtenir une référence directe vers elle en appelant la méthode param_fetch() avec le nom du paramètre. Cela vous renverra un référence vers le tableau des valeurs de ce paramètre que vous pourrez manipuler à votre guise.

Vous pouvez aussi utiliser l'argument nommé -name.

Accéder à la liste des paramètres via une table de hachage

    $params = $q->Vars;
    print $params->{'address'};
    @foo = split("\0",$params->{'foo'});
    %params = $q->Vars;
    use CGI ':cgi-lib';
    $params = Vars;

De nombreuses personnes veulent pouvoir accéder à l'ensemble des paramètres comme si c'était une table de hachage dont les clés sont les noms des paramètres CGI et dont les valeurs sont les valeurs des paramètres. La méthode Vars() fait cela. Appelée dans un contexte scalaire, elle retourne la liste des paramètres sous la forme d'une référence vers une table de hachage liée (par tie()). Changer la valeur attachée à une clé changera la valeur du paramètre CGI qui lui est lié. Appelée dans un contexte de liste, elle retourne la liste des paramètres comme une table de hachage ordinaire. Cela vous permet de lire le contenu de la liste des paramètres mais pas d'en changer les valeurs.

Quand vous utilisez ceci, vous devez faire attention aux paramètres CGI multivalués. Puisqu'une table de hachage ne peut distinguer le contexte (scalaire ou liste), les valeurs des paramètres multivalués sont retournées comme une chaîne compacte où les différentes valeurs sont séparées par le caractère ``\0'' (null). Vous devez découper (par split()) cette chaîne compacte pour récupérer les valeurs individuellement. C'est une convention qui a été introduite il y a bien longtemps par Steve Brenner dans son module cgi-lib.pl conçu pour Perl version 4.

Si vous voulez utiliser Vars() comme une fonction, importez l'ensemble de fonctions :cgi-lib (voir aussi la section concernant la compatibilité CGI-LIB).

Enregistrer l'état du script dans un fichier

    $query->save(FILEHANDLE)

Cela écrira l'état courant du formulaire dans le descripteur de fichier fourni en argument. Vous pouvez le relire en fournissant le même descripteur de fichier à la méthode new(). Remarquez que le descripteur de fichier peut être un fichier, un tube ou n'importe quoi d'autre !

Le format du fichier enregistré est :

        NAME1=VALUE1
        NAME1=VALUE1'
        NAME2=VALUE2
        NAME3=VALUE3
        =

Le nom comme la valeur utilisent le codage des caractères utilisé dans les URL. Les paramètres CGI multivalués sont représentés par un nom répété. Un enregistrement de session est délimité par un symbole = seul. Vous pouvez écrire plusieurs enregistrements successifs puis les relire par plusieurs appels à new. Vous pouvez faire cela dans plusieurs sessions successives en ouvrant le fichier en mode ajout (append). Vous créerez ainsi une espèce de livre d'or simpliste ou un historique des requêtes des utilisateurs. Voici un petit exemple de création d'enregistrement de multiples sessions :

   use CGI;
   open (OUT,">>test.out") || die;
   $records = 5;
   foreach (0..$records) {
       my $q = new CGI;
       $q->param(-name=>'counter',-value=>$_);
       $q->save(OUT);
   }
   close OUT;
   # reopen for reading
   open (IN,"test.out") || die;
   while (!eof(IN)) {
       my $q = new CGI(IN);
       print $q->param('counter'),"\n";
   }

Le format utilisé pour ce fichier est identique au format d'échange de données ``Boulderio'' du Whitehead Genome Center et peut donc être manipulé et même intégré dans une base de données grâce aux utilitaires de ``Boulderio''. Voir :

  http://stein.cshl.org/boulder/

pour des plus amples informations.

Si vous voulez utiliser cette méthode en style orienté fonction (non OO), le nom exporté pour cette méthode est save_parameters().

Gestion des erreurs CGI

Des erreurs peuvent survenir durant le traitement des entrées utilisateur, en particulier lorsqu'on traite les fichiers en téléchargement. Lorsque ces erreurs surviennent, CGI stoppe le traitement et retourne une liste de paramètres vide. Vous pouvez tester l'existence et la nature des éventuelles erreurs en utilisant la fonction cgi_error(). Les messages d'erreurs sont formatés comme des codes de Status HTTP. Vous pouvez soit incorporer le texte de l'erreur dans une page HTML soit l'utiliser comme valeur de Status HTTP :

    my $error = $q->cgi_error;
    if ($error) {
        print $q->header(-status=>$error),
              $q->start_html('Problems'),
              $q->h2('Request not processed'),
              $q->strong($error);
        exit 0;
    }

Quand vous utilisez l'interface orientée fonction (voir la section suivante), les erreurs n'ont lieu qu'au premier appel à param().

Utilisation de l'interface orientée fonction

Pour utiliser l'interface orientée fonction, vous devez spécifier les routines ou l'ensemble des routines de CGI.pm que vous voulez importer dans l'espace de nommage de votre script. Cette importation implique un coût supplémentaire mais il reste petit.

   use CGI <liste de routines>;

Les méthodes listées seront importées dans le package courant ; vous pourrez les appeler directement sans créer d'objet CGI. L'exemple suivant montre comment importer les méthodes param() et header() et comment les utiliser directement :

   use CGI 'param','header';
   print header('text/plain');
   $zipcode = param('zipcode');

De manière générale, vous importerez plutôt un ensemble prédéfini de routines en vous référant à son nom. Tous les noms d'ensembles de fonctions sont précédés par le caractère ``:'' comme dans ``:html3'' (pour les balises définies par le standard HTML 3).

Voici une liste des ensembles de fonctions qui vous pouvez importer :

:cgi
Importe toutes les méthodes de manipulation de CGI telles que param(), path_info() et autres.

:form
Importe toutes les méthodes permettant de générer des formulaires comme textfield().

:html2
Importe toutes les méthodes permettant de générer du HTML 2 standard.

:html3
Importe toutes les méthodes permettant de générer du HTML 3.0 (tel que <table>, <super> et <sub>).

:netscape
Importe toutes les méthodes permettant de générer les extensions de HTML spécifiques à Netscape.

:html
Importe toutes les fonctions permettant de générer du HTML (i.e. 'html2' + 'html3' + 'netscape')...

:standard
Importe toutes les fonctions standard : 'html2', 'html3', 'form' et 'cgi'.

:all
Importe toutes les fonctions disponibles. Pour la liste complète, regardez dans le code de CGI.pm à l'endroit où est définie la variable %EXPORT_TAGS.

Si vous importez un nom de fonction qui ne fait pas partie de CGI.pm, le module traite ce nom comme une nouvelle balise HTML et génère les subroutines appropriées. Vous pouvez alors les utiliser comme n'importe quelle autre balise HTML. Cela permet de suivre le ``standard'' HTML dont l'évolution est très rapide. Par exemple, supposons que Microsoft sorte une nouvelle balise appelée <GRADIENT> (qui provoque un remplissage de l'écran par un dégradé circulaire jusqu'au redémarrage de la machine). Vous n'avez pas à attendre une nouvelle version de CGI.pm pour pouvoir l'utiliser :

   use CGI qw/:standard :html3 gradient/;
   print gradient({-start=>'red',-end=>'blue'});

Remarquez que pour améliorer la vitesse d'exécution, CGI.pm n'utilise pas la syntaxe standard de Exporter pour spécifier les symboles à charger. Cela pourrait changer plus tard.

Si vous importez l'une des méthodes permettant de sauvegarder l'état du CGI ou permettant de générer des formulaires, un objet CGI par défaut sera créé et initialisé automatiquement la première fois que vous ferez appel à l'une des méthodes qui nécessite sa présence. Cela inclut param(), textfield(), submit() et autres. (Si vous avez besoin d'accéder directement à cet objet CGI, vous pouvez le trouver dans la variable globale $CGI::Q). En important le méthode de CGI.pm, vous pouvez créer des scripts visuellement élégants :

   use CGI qw/:standard/;
   print 
       header,
       start_html('Simple Script'),
       h1('Simple Script'),
       start_form,
       "What's your name? ",textfield('name'),p,
       "What's the combination?",
       checkbox_group(-name=>'words',
                      -values=>['eenie','meenie','minie','moe'],
                      -defaults=>['eenie','moe']),p,
       "What's your favorite color?",
       popup_menu(-name=>'color',
                  -values=>['red','green','blue','chartreuse']),p,
       submit,
       end_form,
       hr,"\n";
    if (param) {
       print 
           "Your name is ",em(param('name')),p,
           "The keywords are: ",em(join(", ",param('words'))),p,
           "Your favorite color is ",em(param('color')),".\n";
    }
    print end_html;

Directives (pragmas)

En plus des ensembles de fonctions, il y a un certain nombre de directives que vous pouvez importer. Ces directives, dont le nom est toujours précédé d'un tiret, modifie la manière dont fonctionnent certaines fonctions de CGI.pm. Les directives, les ensembles de fonctions et les fonctions individuelles peuvent tous être importés par la même ligne use(). Par exemple, l'instruction use suivante importe l'ensemble des fonctions standard et active le mode debug (directive -debug) :

   use CGI qw/:standard -debug/;

Voici liste des directives reconnues :

-any
Quand vous spécifiez la directive -any, n'importe quel nom de méthode que l'objet requête ne reconnaît pas sera interprété comme le nom d'une nouvelle balise HTML. Cela vous permet d'utiliser les prochaines extensions ad hoc de Netscape ou Microsoft. Cela vous permet d'utiliser des balises nouvelles ou non supportées :
   use CGI qw(-any);
   $q=new CGI;
   print $q->gradient({speed=>'fast',start=>'red',end=>'blue'});

Comme l'utilisation de la directive any transforme n'importe quelle faute de frappe dans un nom de méthode en une nouvelle balise HTML, il faut l'utiliser avec beaucoup de précautions voir même ne pas l'utiliser du tout.

-compile
Cette directive indique que les méthodes autochargées doivent être compilées immédiatement plutôt que le plus tard possible. C'est utile pour les scripts qui tournent durant une longue période sous FastCGI ou mod_perl ou pour ceux destinés à être traités par le compilateur Perl de Malcom Beattie. Utilisez cette directive en même temps que les méthodes ou les familles de méthodes que vous comptez utiliser.
   use CGI qw(-compile :standard :html3);

ou même :

   use CGI qw(-compile :all);

Notez que l'utilisation de la directive -compile aura toujours pour effet d'importer les fonctions compilées dans l'espace de nommage courant. Si vous voulez compiler sans importation, utilisez plutôt la méthode compile() (voir plus bas).

-nosticky
Cette directive empêche la génération par CGI.pm des champs cachés .submit et .cgifields. C'est utile si vous ne voulez pas voir apparaître ces champs cachés dans la chaîne de requête d'une méthode GET. Par exemple, un script de recherche généré en utilisant cette directive produira un très joli URL, avec uniquement les paramètres de recherche, prêt à être ajouté comme signet.

-no_xhtml
Par défaut, depuis la version 2.69, CGI.pm produit du XHTML (http://www.w3.org/TR/xhtml1/). La directive -no_xhtml désactive cette fonctionnalité. Merci à Michalis Kabrianis <kabrianis@hellug.gr> pour cette fonctionnalité.

-nph
Cette directive demande à CGI.pm de produire un en-tête HTTP correct pour un script NPH (no parsed header - en-tête non analysé). Vous aurez sûrement d'autres réglages à faire pour indiquer à votre serveur que ce script est NPH. Voir plus bas les informations sur les scripts NPH.

-newstyle_urls
Sépare les paires de paramètres nom=valeur de la chaîne de requête CGI par des points-virgules plutôt que des esperluettes (&). Par exemple :
   ?name=fred;age=24;favorite_color=3

Les chaînes de requête dont les valeurs sont séparées par des points-virgules sont toujours reconnues mais elles ne seront émises par self_url() et query_string() que si la directive -newstyle_urls est spécifiée.

C'est devenue le fonctionnement par défaut depuis la version 2.64.

-oldstyle_urls
Sépare les paires de paramètres nom=valeur de la chaîne de requête CGI par des esperluettes (&) plutôt que des points-virgules. C'est n'est plus le fonctionnement par défaut.

-autoload
Avec cette directive, toute fonction non reconnue par votre programme sera passée à CGI.pm pour tenter une évaluation (ce fonctionnement est obtenu en surchargeant l'autoloader). Cela vous permet d'utiliser toutes les fonctions de CGI.pm sans les ajouter à votre table de symboles. Cela peut être très intéressant pour les utilisateurs de mod_perl qui veulent faire attention à la mémoire utilisée. Attention : quand la directive -autoload est active, vous ne pouvez pas utilisez le ``mode poète'' (les fonctions sans parenthèses). Utilisez plutôt hr() plutôt que hr ou ajoutez quelque chose comme use subs qw/hr p header/ au début de votre script.

-no_debug
Cette directive désactive le traitement de la ligne de commande. Si vous voulez utiliser un script CGI.pm à partir d'une ligne de commande pour produire du HTML et que vous ne voulez pas qu'il lise ses paramètres CGI à partir de la ligne de commande ou à partir de STDIN alors utilisez cette directive.
   use CGI qw(-no_debug :standard);

-debug
Cela active le mode debug complet. En plus de lire les paramètres CGI en traitant les arguments de la ligne de commande, CGI.pm s'arrête pour essayer de lire des paramètres à partir de STDIN en affichant le message ``(offline mode: enter name=value pairs on standard input)'' (``mode hors-ligne : saisissez des paires nom=valeur sur l'entrée standard'').

Voir la section concernant le déverminage pour plus de détails.

-private_tempfiles
CGI.pm peut traiter le téléchargement de fichiers. Normalement, il stocke le fichier téléchargé dans un répertoire temporaire puis efface le fichier à la fin. Avec cette méthode, le risque d'une oreille indiscrète existe comme cela est expliqué dans la section concernant le téléchargement de fichier. Un autre auteur de script CGI pourrait lire ces données durant le téléchargement même si ce sont des informations confidentielles. Sur les systèmes Unix, la directive -private_tempfiles provoque l'effacement (par unlink) du fichier juste après son ouverture et avant que la moindre donnée y ait été écrite. Cela réduit (sans l'éliminer complètement) le risque qu'une oreille indiscrète écoute les données enregistrées. Pour compliquer encore le travail de l'attaquant, le programme choisit ses noms de fichiers temporaires en calculant une somme de contrôle sur 32 bits à partir de l'en-tête HTTP reçu.

Pour être sûr que le fichier temporaire ne peut être lu par aucun autre script CGI, utilisez suEXEC ou un wrapper CGI pour faire tourner votre script. Le fichier temporaire est créé avec le mode 0600 (lisible ni par le groupe ni par le reste du monde).

Le répertoire temporaire est choisi en utilisant l'algorithme suivant :

  1. Si l'utilisateur courant (e.g. ``nobody'') possède un répertoire nommé ``tmp'' dans son répertoire home, on l'utilise (système Unix uniquement).

  2. Si la variable d'environnement TMPDIR existe, on utilise l'emplacement spécifié.

  3. Sinon, on essaie les emplacements suivants /usr/tmp, /var/tmp, C:\temp, /tmp, /temp, ::Temporary Items et \WWW_ROOT.

    Pour chaque emplacement, on vérifie que c'est un répertoire et qu'on peut effectivement écrire dedans. Sinon, l'algorithme essaie l'emplacement suivant.

Formes spéciales pour importer des fonctions de balisage HTML

De nombreuses méthodes génèrent des balises HTML. Comme expliqué plus bas, les fonctions de balisage génèrent automatiquement la balise ouvrante et la balise fermante. Par exemple :

  print h1('Level 1 Header');

produit :

  <H1>Level 1 Header</H1>

Il se peut que, parfois, vous vouliez produire la balise ouvrante ou fermante vous-même. Dans ce cas, vous pouvez utiliser l'appel start_balise ou end_balise comme dans :

  print start_h1,'Level 1 Header',end_h1;

À quelques exceptions près (décrites plus bas), les fonctions start_balise et end_balise ne sont pas générées automatiquement lorsque vous faites use CGI. En revanche, vous pouvez spécifier les balises pour lesquelles vous voulez générer les fonctions start/end en plaçant un astérisque devant leur nom ou en demandant explicitement soit la fonction ``start_balise'' soit la fonction ``end_balise'' dans la liste d'import.

Exemple:

  use CGI qw/:standard *table start_ul/;

Dans cet exemple, les fonctions suivantes sont générées en plus des fonctions standards :

  1. start_table() (génère une balise <TABLE>)

  2. end_table() (génère une balise </TABLE>)

  3. start_ul() (génère une balise <UL>)

  4. end_ul() (génère une balise </UL>)


GÉNÉRATION DE DOCUMENTS DYNAMIQUES

La plupart des fonctions CGI.pm permettent la création de documents au vol. En général, vous produirez l'en-tête HTTP suivi du document lui-même. CGI.pm fournit les fonctions pour générer les en-têtes HTTP de tous types ainsi que du HTML. Pour produire des images GIF, regardez le module GD.pm.

Chacune de ces fonctions produit un fragment de HTML ou de HTTP que vous pouvez soit sortir directement pour qu'il soit récupéré par le navigateur, soit ajouter à une chaîne, soit enregistrer dans un fichier pour l'utiliser plus tard.

Création d'un en-tête HTTP

Normalement la première chose que vous avez à faire dans un script CGI est de produire l'en-tête HTTP. Cela indique au navigateur le type du document à recevoir et fournit d'autres informations optionnelles comme la langue, la date d'expiration et s'il faut cacher ce document. L'en-tête peut aussi servir à des fonctions spéciales comme le « server push » ou les pages payées à la consultation (« pay per view »).

        print $query->header;
             -ou-
        print $query->header('image/gif');
             -ou-
        print $query->header('text/html','204 No response');
             -ou-
        print $query->header(-type=>'image/gif',
                             -nph=>1,
                             -status=>'402 Payment required',
                             -expires=>'+3d',
                             -cookie=>$cookie,
                             -charset=>'utf-7',
                             -attachment=>'foo.gif',
                             -Cost=>'$2.00');

header() renvoie l'en-tête ``Content-type:''. Vous pouvez indiquer votre propre type MIME si vous le voulez sinon il est positionné par défaut à text/html. Un second paramètre optionnel spécifie le code de Status et un message lisible. Par exemple, vous pouvez spécifier ``204 No response'' pour créer un script qui dit au navigateur de ne rien faire du tout.

Le dernier exemple montre l'utilisation des arguments nommés pour passer les arguments aux méthodes de CGI. Les arguments reconnus sont -type, -status, -expires et -cookie. Tout autre argument nommé sera transformé en un en-tête après suppression du tiret initial, vous permettant de générer l'en-tête HTTP que vous voulez. Les caractères de soulignement internes sont transformés en tiret :

    print $query->header(-Content_length=>3002);

La plupart des navigateurs ne stockent pas le résultat des scripts CGI. À chaque fois que le navigateur recharge la page, le script est à nouveau appelé. Vous pouvez changer ce comportement grâce au paramètre -expires. Lorsque vous spécifiez une date absolue ou une durée d'expiration par ce paramètre, certains navigateurs et serveurs proxy stockeront dans leur cache le résultat du script jusqu'à la date d'expiration. Toutes les formes suivantes sont valides pour le champ -expires :

        +30s                                dans 30 secondes
        +10m                                dans 10 minutes
        +1h                                 dans une heure
        -1d                                 hier (i.e. "Le plus tôt possible")
        now                                 immédiatement
        +3M                                 dans 3 mois
        +10y                                dans 1 ans
        Thursday, 25-Apr-1999 00:40:33 GMT  au jour et à l'heure indiqués

Le paramètre -cookie génère un en-tête qui indique au navigateur de fournir un ``magic cookie'' durant toutes les transactions à venir avec votre script. Les cookies de Netscape ont un format spécial qui inclut des attributs intéressants comme une date d'expiration. Utilisez la méthode cookie() pour créer et gérer les cookies de sessions.

Le paramètre -nph, si il est positionné à la valeur 'vrai', produira les en-têtes corrects pour fonctionner en tant que script NPH (no-parse-header -- en-tête non analysé). Il vaut mieux l'utiliser avec certains serveurs qui veulent que tous les scripts soient NPH.

Le paramètre -charset permet de spécifier le jeu de caractères envoyé au navigateur. Par défaut, c'est ISO-8859-1. Un effet secondaire est de régler aussi la méthode charset().

La paramètre -attachment peut être utilisé pour transformer une page en un fichier à télécharger. Au lieu d'afficher le document, certains navigateur proposeront à l'utilisateur de l'enregistrer sur disque. La valeur du paramètre est le nom suggéré pour l'enregistrement du fichier. Pour que cela fonctionne, vous devrez positionner le -type à ``application/octet-stream''.

Création d'un en-tête de redirection

   print $query->redirect('http://quelque.part/ailleurs/plus/loin');

Parfois vous ne voulez pas produire vous-même un document mais plutôt rediriger le navigateur ailleurs par exemple en choisissant un URL en vous basant sur l'heure ou l'identité de l'utilisateur.

La fonction redirect() redirige le navigateur vers un URL différent. Si vous utilisez une telle redirection, vous ne devriez pas afficher d'en-tête en plus.

Un truc que je peux donner est que les liens relatifs peuvent ne pas fonctionner correctement lorsque vous générez une redirection vers un autre document de votre site. Cela est dû à une optimisation que certains serveurs utilisent (NdT: en fait ce sont les spécifications du protocole HTTP qui l'interdisent). La solution à cela est d'utiliser un URL complet (incluant la partie http:) vers le document choisi.

Vous pouvez aussi utiliser les arguments nommés :

    print $query->redirect(-uri=>'http://quelque.part/ailleurs/plus/loin',
                           -nph=>1);

Création de l'en-tête d'un document HTML

   print $query->start_html(-title=>'Secrets of the Pyramids',
                            -author=>'fred@capricorn.org',
                            -base=>'true',
                            -target=>'_blank',
                            -meta=>{'keywords'=>'pharaoh secret mummy',
                                    'copyright'=>'copyright 1996 King Tut'},
                            -style=>{'src'=>'/styles/style1.css'},
                            -BGCOLOR=>'blue');

Après avoir créer l'en-tête HTTP, la plupart des scripts CGI continuent en produisant un document HTML. La routine start_html() crée le début du document combiné avec quelques informations optionnelles qui contrôlent l'apparence et le comportement du document.

Cette méthode retourne un en-tête HTML et la balise d'ouverture <BODY>. Tous les paramètres sont optionnels. Sous la forme de paramètres nommés, les paramètres reconnus sont -title, -author, -base, -xbase, -dtd, -lang et -target (voir plus bas pour les explications). Toute autre paramètre que vous fournirez, comme l'attribut non-officiel de Netscape BGCOLOR, sera ajouté à la balise <BODY>. Les paramètres supplémentaires doivent être précédés d'un tiret.

L'argument -xbase vous permet de choisir pour la balise <BASE>, un HREF différent de l'URL courant, comme dans :

    -xbase=>"http://home.mcom.com/";

Tous les liens relatifs seront interprétés relativement à cet URL.

L'argument -target vous permet de choisir un cadre (frame) cible par défaut pour tous les liens et formulaires de la page. C'est une fonctionnalité HTML non-standard qui ne marche qu'avec les navigateurs de Netscape ! Consultez la documentation de Netscape concernant les frames pour les détails concernant cette fonctionnalité.

    -target=>"answer_window"

Vous pouvez ajoutez de la méta-information à l'en-tête grâce à l'argument -meta. Cette argument doit être une référence à un tableau associatif (une table de hachage) contenant des paires nom/valeurs de méta-information. Elles seront transformées en une série de balises d'en-tête <META> qui ressembleront à quelque chose comme :

    <META NAME="keywords" CONTENT="pharaoh secret mummy">
    <META NAME="description" CONTENT="copyright 1996 King Tut">

Pour créer une balise <META> du type HTTP-EQUIV, utilisez -head comme décrit plus bas.

L'argument -style est utilisé pour incorporer une feuille de styles en cascade (CSS) dans votre code. Vois la section FEUILLES DE STYLES EN CASCADE pour plus d'information.

L'argument -lang est utilisé pour ajouter un attribut de langue dans la balise <HTML>. La valeur par défaut est ``en-US'' qui signifie Anglais US. Par exemple :

    print $q->header(-lang=>'fr-CA'); # Francais canadien

Vous pouvez ajouter d'autres éléments HTML arbitraires à la partie <HEAD> grâce à -head. Par exemple, pour ajouter l'élément <LINK>, utilisez cela :

    print start_html(-head=>Link({-rel=>'next',
                                  -href=>'http://www.capricorn.com/s2.html'}));

Pour ajouter plusieurs éléments HTML dans la partie <HEAD>, passez une référence vers un tableau :

    print start_html(-head=>[ 
                             Link({-rel=>'next',
                                   -href=>'http://www.capricorn.com/s2.html'}),
                             Link({-rel=>'previous',
                                   -href=>'http://www.capricorn.com/s1.html'})
                             ]
                     );

Et voici comment créer une balise <META> HTTP-EQUIV :

      print header(-head=>meta({-http_equiv => 'Content-Type',
                                -content    => 'text/html'}))

JAVASCRIPT : Les paramètres -script, -noScript, -onLoad, -onMouseOver, -onMouseOut et -onUnload sont utilisés pour insérer dans votre page des appels au langage JavaScript de Netscape. -script devrait pointer vers un bloc de texte contenant les définitions des fonctions JavaScript. Ce bloc sera placé à l'intérieur d'un bloc <SCRIPT> dans l'en-tête HTML (pas HTTP). Ce bloc est placé dans l'en-tête afin d'être sûr que votre page aura toutes ses fonctions JavaScript définies même si l'utilisateur presse le bouton stop avant le chargement complet de la page. CGI.pm essaie de présenter ce code de manière à ne pas choquer les navigateurs qui ne connaissent pas le JavaScript : malheureusement quelques navigateurs comme Chimera pour Unix ne l'accepteront pas malgré tout.

Les paramètres -onLoad et -onUnload pointent vers des fragments de code JavaScript qui seront exécutés lorsque votre page sera respectivement ouverte puis fermée par le navigateur. Habituellement ces paramètres sont des appels à des fonctions définies dans le champ -script :

      $query = new CGI;
      print $query->header;
      $JSCRIPT=<<END;
      // Ask a silly question
      function riddle_me_this() {
         var r = prompt("What walks on four legs in the morning, " +
                       "two legs in the afternoon, " +
                       "and three legs in the evening?");
         response(r);
      }
      // Get a silly answer
      function response(answer) {
         if (answer == "man")
            alert("Right you are!");
         else
            alert("Wrong!  Guess again.");
      }
      END
      print $query->start_html(-title=>'The Riddle of the Sphinx',
                               -script=>$JSCRIPT);

Utilisez le paramètre -noScript pour passer un texte HTML qui sera affiché par les navigateurs qui n'ont pas d'interpréteur JavaScript (ou dont l'interpréteur JavaScript est désactivé).

Netscape 3.0 reconnaît plusieurs attributs pour la balise <SCRIPT>, entre autres LANGUAGE et SRC. Ce dernier est particulièrement intéressant car il vous permet de garder votre code JavaScript dans un fichier ou un script CGI séparé plutôt que de l'envoyer à chaque fois dans le source de vos pages. Pour utiliser ces attributs, passez au paramètre -script une référence vers une table de hachage contenant au moins une clé parmi -language, -src, ou -code :

    print $q->start_html(-title=>'The Riddle of the Sphinx',
                         -script=>{-language=>'JAVASCRIPT',
                                   -src=>'/javascript/sphinx.js'}
                         );
    print $q->(-title=>'The Riddle of the Sphinx',
               -script=>{-language=>'PERLSCRIPT',
                         -code=>'print "hello world!\n;"'}
               );

Une dernière fonctionnalité vous permet d'inclure plusieurs sections <SCRIPT> dans votre en-tête. Passez juste la liste des sections script comme une référence à un tableau. Cela vous permet de spécifier différents fichiers sources pour différents dialectes de JavaScript. Exemple :

     print $q->start_html(-title=>'The Riddle of the Sphinx',
                          -script=>[
                                    { -language => 'JavaScript1.0',
                                      -src      => '/javascript/utilities10.js'
                                    },
                                    { -language => 'JavaScript1.1',
                                      -src      => '/javascript/utilities11.js'
                                    },
                                    { -language => 'JavaScript1.2',
                                      -src      => '/javascript/utilities12.js'
                                    },
                                    { -language => 'JavaScript28.2',
                                      -src      => '/javascript/utilities219.js'
                                    }
                                 ]
                             );

Voir :

   http://home.netscape.com/eng/mozilla/2.0/handbook/javascript/

pour plus d'informations sur JavaScript.

L'ancien mode d'appel fonctionne comme suit :

Paramètres :

  1. Le titre

  2. L'adresse e-mail de l'auteur (cela créera une balise <LINK REV=``MADE''>).

  3. Un drapeau 'vrai' si vous voulez inclure une balise <BASE> dans l'en-tête. Cela aide à transformer les liens relatifs en liens absolus lorsque le document est déplacé mais rend la hiérarchie de documents non portable. À utiliser avec précautions.

  4. ... et tous les paramètres suivants. Tous les autres paramètres que vous voulez inclure dans la balise <BODY>. C'est un bon endroit pour placer les extensions de Netscape telles que les couleurs ou les images de fond.

Terminaison d'un document HTML

        print $query->end_html

Cela termine un document HTML en affichant les balises </BODY></HTML>.

Création d'un url auto-référencé préservant les informations d'état

    $myself = $query->self_url;
    print q(<A HREF="$myself">I'm talking to myself.</A>);

self_url() retourne un URL qui, lorsqu'il est utilisé, ré-invoquera le script avec toutes ses informations d'état intactes. C'est très pratique lorsque vous voulez naviguer à l'intérieur du document en utilisant de ancres internes sans changer le contenu des formulaires courants. Quelque chose comme ça devrait fonctionner :

     $myself = $query->self_url;
     print "<A HREF=$myself#table1>See table 1</A>";
     print "<A HREF=$myself#table2>See table 2</A>";
     print "<A HREF=$myself#yourself>See for yourself</A>";

Si vous voulez mieux contrôler ce qui est retourné, utilisez plutôt la méthode url().

Vous pouvez aussi retrouver la chaîne de requête avant traitement grâce à query_string() :

    $the_string = $query->query_string;

Retrouver l'URL du script

    $full_url      = $query->url();
    $full_url      = $query->url(-full=>1);  # syntaxe alternative
    $relative_url  = $query->url(-relative=>1);
    $absolute_url  = $query->url(-absolute=>1);
    $url_with_path = $query->url(-path_info=>1);
    $url_with_path_and_query = $query->url(-path_info=>1,-query=>1);

La routine url() renvoie l'URL du script sous différents formats. Appelée sans argument, elle renvoie l'URL complet y compris le nom de la machine et le numéro de port :

    http://your.host.com:80/path/to/script.cgi

Vous pouvez modifier ce format en utilisant les argument nommés suivants :

-absolute
Si vrai, produit un URL absolu, e.g.
    /path/to/script.cgi

-relative
Produit un URL relatif. C'est pratique si vous voulez ré-invoquer votre script avec des paramètres différents. Par exemple :
    script.cgi

-full
Produit l'URL complet, exactement comme si vous aviez appelé la routine sans aucun argument. Supprime l'action des arguments -relative et -absolute.

-path (-path_info)
Ajoute l'information additionnelle de chemin à l'URL. Peut être combiné avec -full, -absolute ou -relative. -path_info est un synonyme.

-query (-query_string)
Ajoute la chaîne de requête à l'URL. Peut être combiné avec -full, -absolute ou -relative. -query_string est un synonyme.

Mélange entre POST et paramètres d'URL

   $color = $query->url_param('color');

Un script CGI peut recevoir des paramètres via son URL en créant un formulaire qui utilise la méthode POST vers un URL contenant une chaîne de requête (un ``?'' suivi par des arguments). La méthode param() ne retournera que le contenu du formulaire POST-é et ignorera la chaîne de requête de l'URL. Pour retrouver les paramètres de l'URL, appelez la méthode url_param(). Elle s'utilise de la même manière que param(). La seule différence est qu'elle ne permet que la lecture des paramètres, pas leur modification.

Dans certaines circonstances, le contenu de la chaîne de requête de l'URL interférera avec des paramètres du formulaire POST-é portant le même nom. Si vous essayez de mélanger une chaîne de requête d'URL avec un formulaire soumis par la méthode GET, le résultat ne sera peut-être pas celui que vous attendez.


CRÉATION DES ÉLÉMENTS HTML STANDARDS

CGI.pm définit de méthodes rapides pour quasiment toutes (si ce n'est toutes) les balises HTML 3 et 4. Les méthodes HTML sont nommées d'après le nom d'un seul élément HTML et renvoient un fragment de texte HTML que vous pouvez afficher ou manipuler comme vous le voulez. Chaque méthode renvoie un fragment de code HTML que vous pouvez ajouter à une chaîne, enregistrer dans un fichier ou, plus couramment, imprimer de manière à être affiché par la fenêtre du navigateur.

Cet exemple illustre l'utilisation des méthodes HTML :

   $q = new CGI;
   print $q->blockquote(
                     "Many years ago on the island of",
                     $q->a({href=>"http://crete.org/";},"Crete"),
                     "there lived a Minotaur named",
                     $q->strong("Fred."),
                    ),
       $q->hr;

Le résultat est le code HTML suivant (des passages à la ligne ont été ajoutés pour améliorer la lisibilité) :

   <blockquote>
   Many years ago on the island of
   <a HREF="http://crete.org/";>Crete</a> there lived
   a minotaur named <strong>Fred.</strong> 
   </blockquote>
   <hr>

Si cette syntaxe d'appel des méthodes HTML vous semble trop lourde, vous pouvez les importer dans votre espace de nommage et vous dispenser ainsi complètement de la syntaxe objet (voir la section suivante pour plus de détails) :

   use CGI ':standard';
   print blockquote(
      "Many years ago on the island of",
      a({href=>"http://crete.org/";},"Crete"),
      "there lived a minotaur named",
      strong("Fred."),
      ),
      hr;

Passer des arguments aux méthodes HTML

Les méthodes HTML acceptent aucun, un ou plusieurs arguments. Si vous ne passez aucun argument, vous obtiendrez une balise seule :

   print hr;    #  <HR>

Si vous passez un ou plusieurs arguments de type chaîne, ils seront concaténés séparés par un espace et placés entre la balise ouvrante et la balise fermante :

   print h1("Chapter","1"); # <H1>Chapter 1</H1>"

Si le premier argument est une référence vers une table de hachage alors les clés et les valeurs associées de cette table deviendront les attributs de la balise HTML :

   print a({-href=>'fred.html',-target=>'_new'},
      "Open a new frame");
            <A HREF="fred.html" TARGET="_new">Open a new frame</A>

Vous pouvez vous dispenser d'ajouter le tiret au début du nom de l'attribut si vous préférez :

   print img {src=>'fred.gif',align=>'LEFT'};
           <IMG ALIGN="LEFT" SRC="fred.gif">

Parfois des attributs de certaines balises HTML n'ont pas d'argument. Par exemple, les listes ordonnées peuvent être marquées comme COMPACT. La syntaxe pour cela est un argument qui pointe sur une valeur indéfinie (undef) :

   print ol({compact=>undef},li('one'),li('two'),li('three'));

Avant la version 2.41 de CGI.pm, fournir une chaîne vide ('') comme valeur d'un argument aboutissait au même résultat. Mais cela a été modifié pour permettre de créer des balises de la forme <IMG ALT=``''>. La différence est illustrée par les deux codes suivants :

   CODE                   RESULTAT
   img({alt=>undef})      <IMG ALT>
   img({alt=>''})         <IMT ALT="">

La distributivité des méthodes HTML

L'une des fonctionnalités sympathiques des méthodes HTML est leur distributivité. Si vous leur fournissez un argument de type référence vers une liste, la balise sera distribuée sur chacun des éléments de la liste. Par exemple, voici un moyen de créer une liste ordonnée :

   print ul(
             li({-type=>'disc'},['Sneezy','Doc','Sleepy','Happy'])
           );

Cette exemple produira le code HTML suivant :

   <UL>
     <LI TYPE="disc">Sneezy</LI>
     <LI TYPE="disc">Doc</LI>
     <LI TYPE="disc">Sleepy</LI>
     <LI TYPE="disc">Happy</LI>
   </UL>

C'est extrêmement pratique pour créer des tableaux. Par exemple :

   print table({-border=>undef},
           caption('When Should You Eat Your Vegetables?'),
           Tr({-align=>CENTER,-valign=>TOP},
           [
              th(['Vegetable', 'Breakfast','Lunch','Dinner']),
              td(['Tomatoes' , 'no', 'yes', 'yes']),
              td(['Broccoli' , 'no', 'no',  'yes']),
              td(['Onions'   , 'yes','yes', 'yes'])
           ]
           )
        );

Méthodes HTML et interpolation de listes

Supposons ce petit bout de code :

   print blockquote(em('Hi'),'mom!'));

Il retournera normalement la chaîne que vous attendez, à savoir :

   <BLOCKQUOTE><EM>Hi</EM> mom!</BLOCKQUOTE>

Vous remarquerez l'espace entre l'élément ``Hi'' et l'élément ``mom!''. CGI.pm ajoute cet espace supplémentaire en utilisant l'interpolation de tableau qui est contrôlé par la variable magique $``. Parfois vous ne voudrez pas de cet espace supplémentaire. Par exemple quand vous essayerez d'aligner une série d'images. Dans ce cas, il vous suffit de donner la chaîne vide comme valeur à la variable $''.

   {
      local($") = '';
      print blockquote(em('Hi'),'mom!'));
    }

Je vous suggère de placer votre code dans un bloc comme ici. Sinon la modification de $`` affectera tous les codes suivants jusqu'à un autre changement de valeur explicite.

Les méthodes HTML non standard

Quelques balises HTML ne suivent pas le modèle standard pour différentes raisons.

comment() génère un commentaire HTML (<!-- comment -->). Appelez-la de la manière suivante :

    print comment('here is my comment');

À cause de conflits avec les fonctions prédéfinies de Perl, les fonctions suivantes commencent par une majuscule :

    Select
    Tr
    Link
    Delete
    Accept
    Sub

De plus, start_html(), end_html(), start_form(), end_form(), start_multipart_form() et toutes les méthodes liées aux balises de création de formulaire sont spéciales. Se reporter à leurs sections respectives.

Auto-encodage du HTML

Par défaut, tout le code HTML émis par les fonctions de génération de formulaires est passé au travers d'une fonction appelée escapeHTML() :

   $escaped_string = escapeHTML("unescaped string");

recode les caractères spéciaux HTML de la chaîne.

En supposant que vous avez spécifié le jeu de caractères ISO-8859-1 (la valeur par défaut), les règles standard d'encodage HTML seront utilisées. Le caractère ``<'' deviendra ``&lt;'', ``>'' deviendra ``&gt;'', ``&'' deviendra ``&amp;'' et les doubles apostrophes deviendront ``&quot;''. De plus, les caractères de codes héxadécimaux 0x8b et 0x9b, que de nombreux navigateurs sous Windows interprètent comme les caractères inférieur et supérieur, seront remplacés par les entités HTML numériques correspondantes (``&#139'' et ``&#155;''). Si vous changez manuellement le jeu de caractères, soit en appelant explicitement la méthode charset() soit en passant un argument -charset à la méthode header(), alors tous les caractères seront remplacés par leur entités HTML numériques correspondantes puisque CGI.pm n'a pas de tables de correspondance pour tous les encodages possibles.

L'encodage automatique ne s'applique pas aux autres méthodes telle que h1(). Vous devez appeler escapeHTML() vous-même surtout sur les données non sûres afin de protéger vos pages contre les mauvaises blagues que des gens pourraient saisir dans les champs d'un formulaire (livre d'or, etc.). Pour changer le jeu de caractères, utilisez la méthode charset(). Pour désactiver complètement l'auto-encodage, utilisez autoEscape() :

$charset = charset([$charset]);
Récupérer ou modifier le jeu de caractères courant.

$flag = autoEscape([$flag]);
Récupérer ou modifier la valeur du drapeau autoescape (auto-encodage)

Générer du joli HTML

Par défaut, tout le HTML produit par ces fonctions arrive comme une seule longue ligne sans aucun passage à la ligne ni indentation. Ce n'est pas joli mais cela réduit la taille des documents de 10 à 20%. Pour obtenir du joli HTML, utilisez le module la page de manuel CGI::Pretty, une sous-classe qui est une contribution de Brian Paulsen.


CRÉATION DE FORMULAIRE PRÉ-REMPLIS

Note générale : toutes les méthodes de création de formulaire renvoient à l'appelant une chaîne de caractères contenant une ou plusieurs balises qui créeront l'élément de formulaire demandé. Vous êtes responsable des chaînes réellement renvoyées. Elles sont faites de telle sorte que vous puissiez mettre des balises autour des éléments de formulaire.

Une autre note : les valeurs par défaut que vous spécifiez pour les formulaires sont uniquement utilisées la première fois que le script est appelé (lorsque la chaîne de requête n'existe pas). Pour les appels ultérieurs au script (quand un chaîne de requête existe), les valeurs de la dernière requête sont utilisées même si elles sont vides.

Si vous voulez changer la valeur d'un champ par rapport à sa valeur précédente, vous avez deux possibilités :

  1. appeler la méthode param() pour la changer.

  2. utiliser le paramètre -override (ou -force) (une nouvelle option dans la version 2.15). Cela oblige l'utilisation de la valeur par défaut, sans tenir compte de la valeur précédente :
        print $query->textfield(-name=>'field_name',
                               -default=>'starting value',
                               -override=>1,
                               -size=>50,
                               -maxlength=>80);

Encore une autre note : par défaut, le texte et les noms des éléments de formulaire sont encodés selon les spécifications HTML. Ce qui veut dire que vous pouvez utiliser en toute sécurité ``<CLICK ME>'' comme nom de bouton. En renvanche, cela gêne votre capacité à incorporer des caractères HTML spéciaux, comme &Aacute;, dans vos champs. Si vous souhaitez désactiver l'encodage automatique, appelez la méthode autoEscape() avec une valeur ``false'' juste après avoir créé l'objet CGI :

    $query = new CGI;
    $query->autoEscape(undef);

Création d'une balise ISINDEX

    print $query->isindex(-action=>$action);
        -ou-
    print $query->isindex($action);

Affiche une balise <ISINDEX>. Pas très intéressant. Le paramètre -action spécifie l'URL du script qui traitera la requête. Par défaut, c'est l'URL du script en cours.

Commencer et finir un formulaire (FORM)

     print $query->start_form(-method=>$method,
                            -action=>$action,
                            -enctype=>$encoding);
       <... divers balises de formulaire ...>
     print $query->endform;
        -ou-
     print $query->start_form($method,$action,$encoding);
       <... divers balises de formulaire ...>
     print $query->endform;

start_form() renverra une balise <FORM> avec les attributs optionnels que vous indiquerez pour la méthode, l'action et l'encodage du formulaire. Par défaut, ces paramètres valent :

     method: POST
     action: this script
     enctype: application/x-www-form-urlencoded

Note : auparavant cette méthode était nommée startform(). startform() est toujours reconnu comme un alias.

endform() renvoie la balise fermante </FORM>.

L'argument enctype de start_form() indique au navigateur comment encoder les différents champs du formulaire avant des les envoyer au serveur. Deux valeurs sont possibles :

application/x-www-form-urlencoded
Il s'agit de l'ancien type d'encodage utilisé par tous les navigateurs antérieurs à Netscape 2.0. Il est compatible avec de nombreux scripts CGI et approprié pour les petits champs contenant des données texte. Pour vous faciliter les choses, CGI.pm stocke le nom de ce type d'encodage dans &CGI::URL_ENCODED.

multipart/form-data
Il s'agit du nouveau type d'encodage, introduit par Netscape 2.0. Il est approprié pour les formulaires qui contiennent des champs très grands ou qui sont destinés à transférer des données binaires. De plus, il active la possibilité de téléchargement de fichier des formulaires Netscape 2.0. Pour vous faciliter les choses, CGI.pm stocke le nom de ce type d'encodage dans &CGI::MULTIPART

Les formulaires qui utilisent ce type d'encodage ne sont pas facilement interprétés par les scripts CGI, sauf si ceux-ci utilisent CGI.pm ou tout autre bibliothèque conçue pour les traiter.

Pour des raisons de compatibilité, la méthode start_form() utilise par défaut l'ancienne version d'encodage. Si vous voulez utiliser la nouvelle version par défaut, vous pouvez appeler la méthode start_multipart_form() à la place de start_form().

JAVASCRIPT : les paramètres -name et -onSubmit sont disponibles pour faire du JavaScript. Le paramètre -name donne un nom au formulaire qui, ainsi, peut être identifié et manipulé par des fonctions JavaScript. -onSubmit devrait pointer vers une fonction JavaScript qui sera exécutée juste avant que le formulaire soit envoyé à votre serveur. Vous pouvez utiliser cette fonction pour vérifier la consistance et la cohérence du contenu du formulaire. Si vous détectez une chose incorrecte, vous pouvez soit afficher une fenêtre d'alerte soit corriger vous-même les données erronées. La soumission du formulaire sera annulée si votre fonction retourne une valeur fausse (false).

D'habitude, le gros des fonctions JavaScript est défini dans un bloc <SCRIPT> dans l'en-tête HTML et -onSubmit ne fait qu'un appel à l'une de ces fonctions. Voir start_html() pour les détails.

Création d'un champ texte (TEXTFIELD)

     print $query->textfield(-name=>'field_name',
                            -default=>'starting value',
                            -size=>50,
                            -maxlength=>80);
        -ou-
     print $query->textfield('field_name','starting value',50,80);

textfield() renverra un champ d'entrée texte.

Paramètres :

  1. Le premier paramètre est le nom donné au champ (-name).

  2. Le deuxième paramètre (optionnel) est la valeur initiale par défaut du contenu du champ (-default).

  3. Le troisième paramètre (optionnel) est la taille du champ en caractères (-size).

  4. Le quatrième paramètre (optionnel) est le nombre maximal de caractères que le champ acceptera (-maxlength).

Comme avec toutes ces méthodes, le champ sera initialisé avec son contenu précédent provenant des appels antérieurs au script. Quand le formulaire est traité, la valeur du champ texte peut être retrouvée par :

        $value = $query->param('foo');

Si vous voulez le réinitialiser à sa valeur initiale après un appel précédent au script, vous pouvez faire comme ça :

        $query->param('foo',"I'm taking over this value!");

NOUVEAU DEPUIS LA VERSION 2.15 : si vous ne voulez pas que le champ conserve sa dernière valeur, vous pouvez forcer sa valeur courante en utilisant le paramètre -override (ou -force) :

     print $query->textfield(-name=>'field_name',
                            -default=>'starting value',
                            -override=>1,
                            -size=>50,
                            -maxlength=>80);

JAVASCRIPT : vous pouvez bien sûr renseigner les paramètres -onChange, -onFocus, -onBlur, -onMouseOver, -onMouseOut et -onSelect pour attacher à ces évènements des routines JavaScript de traitement. La routine attachée à onChange sera appelée à chaque fois que l'utilisateur change le contenu du champ texte. Vous pouvez faire une validation du texte si vous voulez. onFocus et onBlur sont appelés respectivement quand le point d'insertion entre ou sort du champ texte. onSelect est appelé quand l'utilisateur change la portion de texte sélectionnée à l'intérieur du champ.

Création d'un grand champ texte (TEXTAREA)

    print $query->textarea(-name=>'foo',
                          -default=>'starting value',
                          -rows=>10,
                          -columns=>50);
        -ou-
    print $query->textarea('foo','starting value',10,50);

textarea() est similaire à textfield() excepté qu'il vous permet de spécifier le nombre de lignes et de colonnes pour la boite d'entrée de texte multiligne. Vous pouvez renseigner une valeur initiale pour le champ qui peut être longue et contenir plusieurs lignes.

JAVASCRIPT : les paramètres -onChange, -onFocus, -onBlur , -onMouseOver, -onMouseOut, et -onSelect sont reconnus. Voir textfield().

Création d'un champ mot de passe (PASSWORD)

    print $query->password_field(-name=>'secret',
                                -value=>'starting value',
                                -size=>50,
                                -maxlength=>80);
        -ou-
    print $query->password_field('secret','starting value',50,80);

password_field() est identique à textfield(), excepté que son contenu sera affiché sous forme d'étoiles sur la page web.

JAVASCRIPT : Les paramètres -onChange, -onFocus, -onBlur , -onMouseOver, -onMouseOut, et -onSelect sont reconnus. Voir textfield().

Création d'un champ de téléchargement de fichier (FILE UPLOAD)

     print $query->filefield(-name=>'uploaded_file',
                            -default=>'starting value',
                            -size=>50,
                            -maxlength=>80);
        -ou-
     print $query->filefield('uploaded_file','starting value',50,80);

filefield() crée un champ de téléchargement de fichier pour les navigateurs type Netscape 2.0. Afin d'en tirer tous les avantages, vous devez utiliser le nouveau format d'encodage multipart pour ce formulaire. Vous pouvez faire cela en appelant start_form() avec un encodage &CGI::MULTIPART, ou en appelant la nouvelle méthode start_multipart_form() au lieu de start_form().

Paramètres :

  1. Le premier paramètre est le nom requis pour le champ (-name).

  2. Le deuxième paramètre (optionnel) est la valeur initiale du champ. Elle sera utilisée comme nom de fichier par défaut (-default).

    Pour des raisons de sécurité, les navigateurs ne prêtent pas attention à ce champ et la valeur initiale est donc toujours vide. Pire, le champ perd son comportement ``persistant'' et oublie son contenu précédent. Cet attribut spécifiant la valeur initiale existe pourtant dans les spécifications HTML et il est donc possible que certains navigateurs en tiennent compte un jour.

  3. Le troisième paramètre (optionnel) est la taille du champ en caractères (-size).

  4. Le quatrième paramètre (optionnel) est le nombre maximal de caractères que le champ acceptera (-maxlength).

Quand le formulaire est traité, vous pouvez retrouver le nom du fichier téléchargé en appelant la méthode param() :

        $filename = $query->param('uploaded_file');

Des navigateurs différents renverront des choses légèrement différentes pour ce nom. Certains navigateurs renverront uniquement le nom du fichier. D'autres renverront le chemin complet du fichier en utilisant les conventions de chemin de la machine de l'utilisateur. Ceci étant, le nom retourné est toujours le nom du fichier sur la machine de l'utilisateur. Il n'a aucun rapport avec le nom du fichier temporaire que CGI.pm crée pendant le téléchargement (voir ci-dessous).

Le nom du fichier renvoyé est aussi un descripteur de fichier. Vous pouvez lire le contenu du fichier en utilisant les appels standard de lecture de fichier de Perl :

        # Lire un fichier texte et l'afficher
        while (<$filename>) {
           print;
        }
        # Copier un fichier binaire dans un endroit sur
        open (OUTFILE,">>/usr/local/web/users/feedback");
        while ($bytesread=read($filename,$buffer,1024)) {
           print OUTFILE $buffer;
        }

Cependant, il y a des problèmes avec la double nature des champs de téléchargement de fichiers. Si vous utilisez use strict, alors Perl se plaindra quand vous essayerez d'utiliser une chaîne de caractères comme descripteur de fichier. Vous pouvez évidemment contourner ce problème en plaçant le code de lecture du fichier dans un bloc contenant la directive no strict. Plus sérieusement, il est possible pour l'utilisateur distant, de taper n'importe quoi dans le champ de téléchargement, auquel cas, ce que vous récupérerez de param() ne sera pas du tout un descripteur de fichier, mais seulement une chaîne de caractères.

Pour travailler de manière sûre, utilisez la fonction upload() (introduite dans la version 2.47). Lorsqu'elle est appelée avec le nom d'un champ de téléchargement, upload() renvoie un descripteur de fichier, ou undef si le paramètre n'est pas un descripteur de fichier valide.

      $fh = $query->upload('uploaded_file');
      while (<$fh>) {
           print;
      }

C'est l'idiome recommandé.

Lorsqu'un fichier est téléchargé, le navigateur envoie toujours, en accompagnement, des informations le concernant, via différents en-têtes. Ces informations incluent habituellement le type MIME du contenu. Les futurs navigateurs peuvent aussi envoyer d'autres informations (comme la date de modification ou la taille). Pour retrouver ces informations, appelez uploadInfo(). Cette fonction renvoie une référence à un tableau associatif contenant tous les en-têtes du document.

        $filename = $query->param('uploaded_file');
        $type = $query->uploadInfo($filename)->{'Content-Type'};
        unless ($type eq 'text/html') {
          die "HTML FILES ONLY!";
        }

Si vous utilisez une machine qui distingue les types de données ``texte'' et ``binaire'', soyez sûr de comprendre quand et comment les utiliser (voir le Camel book). Sinon, vous pourrez constater que le contenu des fichiers binaires est altéré durant leur téléchargement.

Il y a de temps en temps des problèmes dus à l'analyse des fichiers téléchargés. Cela se produit habituellement quand l'utilisateur presse le bouton ``Stop'' avant la fin du téléchargement. Dans ce cas, CGI.pm renverra undef pour le nom du fichier et renverra ``400 Bad Request (malformed multipart POST)'' dans cgi-error(). Ce message d'erreur est conçu de telle sorte que vous pouvez l'utiliser comme Status dans les en-têtes HTTP à renvoyer au navigateur. Exemple :

    $file = $query->upload('uploaded_file');
    if (!$file && $query->cgi_error) {
       print $query->header(-status=>$query->cgi_error);
       exit 0;
    }

Libre à vous de créer des pages HTML personnalisées à renvoyer en cas d'erreur.

JAVASCRIPT : Les paramètres -onChange, -onFocus, -onBlur , -onMouseOver, -onMouseOut, et -onSelect sont reconnus. Voir textfield().

Création d'un menu déroulant (POPUP)

    print $query->popup_menu('menu_name',
                            ['eenie','meenie','minie'],
                            'meenie');
       -ou-
    %labels = ('eenie'=>'your first choice',
              'meenie'=>'your second choice',
              'minie'=>'your third choice');
    print $query->popup_menu('menu_name',
                            ['eenie','meenie','minie'],
                            'meenie',\%labels);
        -ou (appel par parametres nommes)-
    print $query->popup_menu(-name=>'menu_name',
                            -values=>['eenie','meenie','minie'],
                            -default=>'meenie',
                            -labels=>\%labels);

popup_menu() crée un menu.

  1. Le premier argument (requis) est le nom du menu (-name).

  2. Le deuxième argument (requis) (-values) est une référence à un tableau contenant la liste des items du menu. Vous pouvez passer un tableau anonyme à la méthode, comme dans l'exemple, ou une référence à un tableau nommé, comme ``\@foo''.

  3. Le troisième paramètre (optionnel) (-default) est le nom de l'item sélectionné par défaut. S'il n'est pas spécifié, le premier item sera celui par défaut. La valeur du choix précédent sera conservée à travers les requêtes.

  4. Le quatrième paramètre (optionnel) (-labels) est renseigné par les gens qui veulent utiliser des valeurs différentes pour l'item visible par l'utilisateur et pour la valeur correspondante retournée à votre script. C'est un pointeur vers un tableau associatif qui associe à chaque valeur du menu le texte correspondant visible par l'utilisateur. Si vous laissez ce paramètre vierge, les valeurs du menu seront affichées par défaut. (Vous pouvez bien sûr laisser un item non défini si vous le voulez).

Quand le formulaire est traité, la valeur sélectionnée dans le menu déroulant peut être retrouvée en utilisant :

       $popup_menu_value = $query->param('menu_name');

JAVASCRIPT : popupmenu() reconnaît les attributs suivants : -onChange, -onFocus, -onMouseOver, -onMouseOut, et -onBlur. Voir la section textfield() pour savoir en quelles circonstances il est fait appel à ces attributs.

Création d'une liste déroulante (SCROLLING LIST)

    print $query->scrolling_list('list_name',
                                ['eenie','meenie','minie','moe'],
                                ['eenie','moe'],5,'true');
       -ou-
    print $query->scrolling_list('list_name',
                                ['eenie','meenie','minie','moe'],
                                ['eenie','moe'],5,'true',
                                \%labels);
        -ou-
    print $query->scrolling_list(-name=>'list_name',
                                -values=>['eenie','meenie','minie','moe'],
                                -default=>['eenie','moe'],
                                -size=>5,
                                -multiple=>'true',
                                -labels=>\%labels);

scrolling_list() crée une liste déroulante.

Paramètres :

  1. Les deux premiers arguments sont le nom (-name) et les valeurs (-values) de la liste. Comme pour un menu déroulant, le second argument devrait être une référence à un tableau.

  2. Le troisième argument (optionnel) (-default) peut être soit une référence à une liste contenant les valeurs à sélectionner par défaut, soit une seule valeur à sélectionner. Si cet argument est manquant ou non défini, alors rien n'est sélectionné quand la liste apparaît. En appel par paramètre nommé, vous pouvez utiliser le synonyme ``-defaults'' pour ce paramètre.

  3. Le quatrième argument (optionnel) (-size) est la taille de la partie visible de la liste.

  4. Le cinquième argument (optionnel) (-multiple) doit être mis à vrai (true) pour autoriser les sélections multiples. Sinon une seule sélection à la fois est autorisée.

  5. Le sixième argument (optionnel) (-labels) est un pointeur vers un tableau associatif associant à chaque valeur de la liste, son texte visible par l'utilisateur. S'il n'est pas renseigné, les valeurs elles-mêmes seront affichées.

Quand le formulaire est traité, tous les éléments sélectionnés de la liste sont renvoyés sous forme de liste par le paramètre 'list_name'. Les valeurs des éléments sélectionnés peuvent être retrouvées par :

       @selected = $query->param('list_name');

JAVASCRIPT : scrolling_list() reconnaît les attributs suivants : -onChange, -onFocus, -onMouseOver, -onMouseOut, et -onBlur. Voir la section textfield() pour les détails concernant l'utilisation de ces attributs.

Création d'un groupe de cases à cocher (CHECKBOX)

    print $query->checkbox_group(-name=>'group_name',
                                -values=>['eenie','meenie','minie','moe'],
                                -default=>['eenie','moe'],
                                -linebreak=>'true',
                                -labels=>\%labels);
    print $query->checkbox_group('group_name',
                                ['eenie','meenie','minie','moe'],
                                ['eenie','moe'],'true',\%labels);
    NAVIGATEURS COMPATIBLES HTML3 SEULEMENT :
    print $query->checkbox_group(-name=>'group_name',
                                -values=>['eenie','meenie','minie','moe'],
                                -rows=>2,-columns=>2);

checkbox_group() crée une liste de cases à cocher qui sont regroupées sous le même nom.

Paramètres :

  1. Les deux premiers arguments sont le nom et les valeurs des cases à cocher (respectivement -name et -values). Comme dans un menu déroulant, le second argument devrait être une référence à un tableau. Ces valeurs sont utilisées comme textes lisibles par l'utilisateur affichées à côté des cases à cocher aussi bien que comme valeurs passées à votre script via la chaîne de requête.

  2. Le troisième argument (optionnel) (-default) peut être soit une référence à une liste contenant les valeurs qui doivent être cochées par défaut, soit une seule valeur qui doit être cochée. Si cet argument est manquant ou non défini, alors aucune case n'est cochée quand la liste apparaît.

  3. Le quatrième argument (optionnel) (-linebreak) doit être mis à ``true'' pour placer des séparateurs de ligne entre les cases à cocher pour qu'elles apparaissent comme une liste verticale. Autrement, elles seront mises ensemble sur une seule ligne horizontale.

  4. Le cinquième argument (optionnel) est un pointeur vers un tableau associatif associant les valeurs des cases à cocher aux textes lisibles par l'utilisateur qui seront affichées à côté de celles-ci (-labels). Si elles ne sont pas renseignées, les valeurs seront utilisées comme textes par défaut.

  5. Les navigateurs compatibles HTML3 (comme Netscape) peuvent profiter des paramètres optionnels -rows et -columns. Ces paramètres obligent checkbox_group() à renvoyer un tableau compatible HTML3 contenant le groupe de cases à cocher formaté avec le nombre de lignes et de colonnes spécifié. Vous pouvez renseigner uniquement le paramètre -columns si vous le désirez. checkbox_group() calculera le nombre correct de lignes pour vous.

    Pour ajouter des titres à vos lignes et colonnes dans le tableau renvoyé, vous pouvez utiliser les paramètres -rowheaders et -colheaders. Les deux acceptent un pointeur vers un tableau de titres à utiliser. Les titres sont purement décoratifs. Ils ne modifient pas l'interprétation des données des cases à cocher.

Quand le formulaire est traité, la liste de toutes les cases cochées sera renvoyée dans le paramètre nommé 'group_name'. Les valeurs des cases à cocher ``on'' peuvent être retrouvées par :

       @turned_on = $query->param('group_name');

Les valeurs renvoyées par checkbox_group() sont réellement un tableau de valeurs. Vous pouvez les prendre et les utiliser dans des tableaux, listes ou autres :

     @h = $query->checkbox_group(-name=>'group_name',-values=>\@values);
     &use_in_creative_way(@h);

JAVASCRIPT : checkbox_group() reconnaît le paramètre -onClick. Il permet à un bout de code JavaScript ou un appel de fonction de s'exécuter à chaque fois que l'utilisateur clique sur l'un des boutons du groupe. Vous pouvez rechercher l'identité du bouton cliqué en utilisant la variable ``this''.

Création d'une case à cocher isolée (CHECKBOX)

     print $query->checkbox(-name=>'checkbox_name',
                           -checked=>'checked',
                           -value=>'ON',
                           -label=>'CLICK ME');
        -ou-
     print $query->checkbox('checkbox_name','checked','ON','CLICK ME');

checkbox() est utilisé pour créer une case à cocher isolée qui n'est pas associée à d'autres de façon logique.

Paramètres :

  1. Le premier paramètre est le nom requis pour la case à cocher (-name). Par défaut, il sera aussi utilisé comme texte à afficher à côté de la case à cocher.

  2. Le deuxième paramètre (optionnel) (-checked) précise si la case est cochée par défaut. Les synonymes sont -selected et -on.

  3. Le troisième paramètre (optionnel) (-value) donne la valeur de la case lorsque celle-ci est cochée. S'il n'est pas renseigné, le mot ``on'' est utilisé.

  4. Le quatrième paramètre (optionnel) (-label) est le texte lisible par l'utilisateur qui sera associé à la case à cocher. S'il n'est pas renseigné, le nom de la case à cocher est utilisé.

La valeur de la case à cocher peut être retrouvée en utilisant :

     $turned_on = $query->param('checkbox_name');

JAVASCRIPT : checkbox() reconnaît le paramètre onClick. Voir checkbox_group() pour plus de détails.

Création d'un groupe de boutons radio (RADIO)

    print $query->radio_group(-name=>'group_name',
                             -values=>['eenie','meenie','minie'],
                             -default=>'meenie',
                             -linebreak=>'true',
                             -labels=>\%labels);
        -ou-
    print $query->radio_group('group_name',['eenie','meenie','minie'],
                                          'meenie','true',\%labels);
    NAVIGATEURS COMPATIBLES HTML3 SEULEMENT :
    print $query->radio_group(-name=>'group_name',
                             -values=>['eenie','meenie','minie','moe'],
                             -rows=2,-columns=>2);

radio_group() crée un groupe de boutons radio associés de manière logique. (activer l'un des boutons du groupe désactive les autres)

Paramètres :

  1. Le premier paramètre est le nom du groupe et est obligatoire (-name).

  2. Le deuxième paramètre (-values) est la liste des valeurs pour les boutons radio. Les valeurs et les étiquettes qui apparaissent sur la page sont identiques. Passez une référence vers un tableau dans ce second paramètre, soit en utilisant un tableau anonyme, comme ci-dessus, soit en faisant référence à un tableau nommé, comme dans ``\@foo''.

  3. Le troisième paramètre (optionnel) (-default) est le nom du bouton actif par défaut. S'il n'est pas spécifié, le premier bouton sera celui activé par défaut. Vous pouvez fournir un nom de bouton non-existant, comme ``-'' pour démarrer sans aucun bouton sélectionné.

  4. Le quatrième paramètre (optionnel) (-linebreak) peut être mis à vrai (true) pour insérer des passage à la ligne entre les boutons, créant ainsi une liste verticale.

  5. Le cinquième paramètre (optionnel) (-labels) est une référence vers un tableau associatif associant les valeurs des boutons radio aux étiquettes lisibles par l'utilisateur qui sont utilisées pour l'affichage. Si ce paramètre n'est pas fourni, les valeurs elles-mêmes seront affichées.

  6. Les navigateurs compatibles HTML3 (comme Netscape) peuvent profiter des paramètres optionnels -rows et -columns. Ces paramètres obligent radio_group() à renvoyer un tableau compatible HTML3 contenant le groupe de boutons radio formaté avec les nombres de lignes et de colonnes spécifiés. Vous pouvez renseigner uniquement le paramètre -columns si vous le désirez ; radio_group() calculera le nombre correct de lignes pour vous.

    Pour inclure des titres de lignes et de colonnes dans le tableau renvoyé, vous pouvez utiliser les paramètres -rowheaders et -colheaders. Les deux acceptent un pointeur vers un tableau de titres à utiliser. Les titres sont purement décoratifs. Ils ne modifient pas l'interprétation des données des cases à cocher.

Quand le formulaire est traité, le bouton radio sélectionné peut être retrouvé en utilisant :

       $which_radio_button = $query->param('group_name');

Les valeurs renvoyées par radio_group() sont toujours un tableau de valeurs. Vous pouvez les prendre et les utiliser dans des tableaux, listes ou autres :

     @h = $query->radio_group(-name=>'group_name',-values=>\@values);
     &use_in_creative_way(@h);

Création d'un bouton SUBMIT (BUTTON)

    print $query->submit(-name=>'button_name',
                        -value=>'value');
        -ou-
    print $query->submit('button_name','value');

submit() créera le bouton de soumission de requête. Tous les formulaires devrait en avoir un.

Paramètres :

  1. Le premier paramètre (-name) est optionnel. Vous pouvez donner un nom au bouton si vous avez plusieurs boutons de soumission dans votre formulaire et que vous voulez les distinguer les uns des autres. Le nom sera utilisé comme étiquette visible par l'utilisateur. Faites attention car quelques vieux navigateurs ne l'utilisent pas correctement et ne renvoient jamais la valeur d'un bouton.

  2. Le second paramètre (-value) est optionnel. Il donne au bouton une valeur qui sera passée à votre script dans la chaîne de requête.

Vous pouvez savoir quel bouton a été pressé en utilisant différentes valeurs pour chacun d'eux :

      $which_one = $query->param('button_name');

JAVASCRIPT : submit() reconnaît le paramètre onClick. Voir checkbox_group() pour plus de détails.

Création d'un bouton RESET (BUTTON)

    print $query->reset

reset() crée un bouton ``reset''. Notez qu'il remet les valeurs du formulaire dans l'état où elles étaient la dernière fois que le script a été appelé, PAS obligatoirement à celui par défaut.

Notez qu'il y a conflit avec la fonction de base Perl reset(). Utilisez CORE::reset() pour obtenir la fonction reset() standard.

Création d'un bouton DEFAULT (BUTTON)

    print $query->defaults('button_label')

defaults() crée un bouton qui, lorsqu'on l'utilise, remet tous les champs du formulaire à leur valeur par défaut, enlevant ainsi tous les changements que l'utilisateur aurait pu faire.

Création d'un champ caché (HIDDEN)

        print $query->hidden(-name=>'hidden_name',
                             -default=>['value1','value2'...]);
                -ou-
        print $query->hidden('hidden_name','value1','value2'...);

hidden() construit un champ texte qui ne peut pas être vu par l'utilisateur (NdT: sauf en lisant les sources du document HTML). Il est très pratique pour transmettre une information sur l'état d'une variable d'un appel du script à l'autre.

Paramètres :

  1. Le premier paramètre (requis) donne un nom à ce champ (-name).

  2. Le second paramètre est également requis et précise la valeur du champ (-default). Si vous utilisez les paramètres nommés, vous pouvez donner ici une valeur simple ou une référence à une liste entière.

Retrouvez la valeur d'un champ caché de cette façon :

      $hidden_value = $query->param('hidden_name');

Notez que comme tous les autres éléments de formulaire, la valeur d'un champ caché est ``persistante''. Si vous voulez remplacer la valeur d'un champ caché avec d'autres valeurs après que le script ait été appelé une première fois, vous devrez le faire manuellement :

      $query->param('hidden_name','new','values','here');

Création d'un bouton avec une image cliquable (BUTTON)

      print $query->image_button(-name=>'button_name',
                                -src=>'/source/URL',
                                -align=>'MIDDLE');
        -ou-
      print $query->image_button('button_name','/source/URL','MIDDLE');

image_button() donne une image cliquable. Quand elle est cliquée, la position du clic est renvoyée à votre script dans les deux paramètres ``button_name.x'' et ``button_name.y'', où ``button_name'' est le nom que vous lui avez donné.

Paramètres :

  1. Le premier paramètre (requis) (-name) précise le nom du champ.

  2. Le second paramètre (-src) est également requis et précise l'URL (NdT: de l'image).

  3. Le troisième paramètre (optionnel) (-align) est l'alignement, et peut être TOP, BOTTOM ou MIDDLE.

Retrouvez la valeur du bouton de cette manière :

      $x = $query->param('button_name.x');
      $y = $query->param('button_name.y');

JAVASCRIPT : image_button() reconnaît le paramètre onClick. Voir checkbox_group pour plus de détails.

Création d'un bouton d'action JavaScript (BUTTON)

      print $query->button(-name=>'button_name',
                          -value=>'user visible label',
                          -onClick=>"do_something()");
        -ou-
      print $query->button('button_name',"user label","do_something()");

button() produit un bouton compatible avec le JavaScript de Netscape 2.0. Quand il est pressé, le bout de code JavaScript pointé par par le paramètre onClick sera exécuté. Sur les navigateurs autres que Netscape, cet élément de formulaire ne sera probablement même pas affiché.


COOKIES HTTP

Les versions 1.1 et supérieures de Netscape, ainsi que toutes les versions d'Internet Explorer, supportent la notion de ``cookie'' qui aide au suivi d'une session avec un navigateur. CGI.pm proposent quelques méthodes qui gèrent les cookies.

Un cookie est une paire nom=valeur, un peu comme les paramètres nommés dans une requête CGI. Les scripts CGI créent un ou plusieurs cookies et les envoient au navigateur dans l'entête HTTP. Le navigateur mémorise la liste des cookies qui appartiennent à un serveur Web particulier et les renvoient au script CGI lors d'appels ultérieurs.

En plus de la paire nom=valeur, chaque cookie a quelques attributs optionnels :

  1. une date d'expiration
    C'est un champ date/heure (dans un format GMT spécial) qui indique quand un cookie expire. Le cookie sera mémorisé et renvoyé à votre script jusqu'à ce que sa date d'expiration soit atteinte (NdT: même) si l'utilisateur quitte le navigateur et le relance. Si aucune date d'expiration n'est spécifiée, le cookie sera actif jusqu'à ce que l'utilisateur quitte le navigateur.

  2. un domaine
    C'est un nom de domaine partiel ou complet pour lequel le cookie est valide. Le navigateur renverra le cookie à chaque hôte dont le nom correspond au domaine partiel. Par exemple, si vous spécifiez un nom de domaine tel que ``.capricorn.com'', alors le navigateur renverra le cookie aux serveurs Web fonctionnant sur chacune des machines ``www.capricorn.com'', ``www2.capricorn.com'', ``www.feckless.capricorn.com'', etc... Les noms de domaine doivent contenir au moins deux morceaux pour éviter de rechercher des domaines de plus haut niveau comme ``.edu''. Si aucun domaine n'est spécifié, alors le navigateur ne renverra le cookie qu'aux serveurs de l'hôte dont le cookie provient.

  3. un chemin
    Si vous précisez un attribut chemin (path) au cookie, le navigateur le comparera à l'URL de votre script avant de renvoyer le cookie. Par exemple, si vous donnez le chemin ``/cgi-bin'', alors le cookie sera renvoyé à chacun des scripts ``/cgi-bin/tally.pl'', ``/cgi-bin/order.pl'' et ``/cgi-bin/customer_service/complain.pl'', mais pas au script ``/cgi-private/site_admin.pl''. Par défaut, le chemin est mis à ``/'', ce qui oblige l'envoi du cookie à tous les scripts CGI de votre site.

  4. un indicateur ``secure''
    Si l'attribut ``secure'' est activé, le cookie sera envoyé à votre script uniquement si la requête CGI passe par un canal sécurisé, tel SSL (NdT: HTTPS).

L'accès aux cookies HTTP se fait par la méthode cookie() :

     $cookie = $query->cookie(-name=>'sessionID',
                             -value=>'xyzzy',
                             -expires=>'+1h',
                             -path=>'/cgi-bin/database',
                             -domain=>'.capricorn.org',
                             -secure=>1);
     print $query->header(-cookie=>$cookie);

cookie() crée un nouveau cookie. Ses paramètres sont :

-name
Le nom du cookie (requis). Cela peut être n'importe quelle chaîne. Bien que les navigateurs limitent leurs noms de cookie aux caractères alphanumériques (espaces exclus), CGI.pm supprime cette restriction en encodant et décodant les noms des cookies au vol.

-value
La valeur du cookie. Cela peut-être une valeur scalaire, une référence à un tableau ou même une référence à un tableau associatif. Par exemple, vous pouvez stocker tout un tableau associatif dans un cookie de la manière suivante :
        $cookie=$query->cookie(-name=>'family information',
                               -value=>\%childrens_ages);

-path
La chemin partiel (et optionnel) pour lequel ce cookie est valide comme décrit plus haut.

-domain
Le domaine partiel (et optionnel) pour lequel ce cookie est valide comme décrit plus haut.

-expires
La date d'expiration (optionnelle) de ce cookie. Le format est le même que celui décrit dans la section concernant la méthode header() :
        "+1h"  dans une heure

=item B<-secure>

Si ce paramètre est positionné à vrai (``true''), ce cookie ne sera utilisé qu'à travers une session sécurisée (par SSL).

Le cookie créé par cookie() doit être incorporé aux en-têtes HTTP en passant par la chaîne retournée par le méthode header() :

        print $query->header(-cookie=>$my_cookie);

Pour créer plusieurs cookies, passez à header() une référence à un tableau :

        $cookie1 = $query->cookie(-name=>'riddle_name',
                                  -value=>"The Sphynx's Question");
        $cookie2 = $query->cookie(-name=>'answers',
                                  -value=>\%answers);
        print $query->header(-cookie=>[$cookie1,$cookie2]);

Pour retrouver un cookie, demandez-le par son nom en appelant la méthode cookie() sans paramètre -value :

        use CGI;
        $query = new CGI;
        %answers = $query->cookie(-name=>'answers');
        # $query->cookie('answers') marcherait aussi !

Les espaces de nommage des cookies et des paramètres CGI sont distincts. Si vous avez un paramètre nommé 'answers' et un cookie nommé 'answers', les valeurs retournées par param() et cookie() sont indépendantes l'une de l'autre. Par contre, il est très simple de transformer un paramètre CGI en un cookie et vice-versa :

   # transforme un parametre CGI en un cookie
   $c=$q->cookie(-name=>'answers',-value=>[$q->param('answers')]);
   # vice-versa
   $q->param(-name=>'answers',-value=>[$q->cookie('answers')]);

Voir le script d'exemple cookie.cgi pour avoir quelques idées sur l'utilisation réelle des cookies.


TRAVAILLER AVEC DES CADRES (FRAMES)

Les scripts CGI.pm peuvent écrire dans plusieurs cadres ou fenêtres du navigateur en utilisant les mécanismes de cadres (frames) de HTML 4. Il y a trois techniques pour définir de nouveaux cadres par programmation :

  1. Créer un document <Frameset>
    Après avoir écrit les en-têtes HTTP, au lieu de créer un document HTML standard en utilisant l'appel start_html(), créez un document <FRAMESET> qui définit les cadres de la page. Indiquez votre(vos) script(s) (avec les paramètres appropriés) comme SRC pour chacun de ces cadres (frames).

    Il n'y a rien de prévu pour créer des sections <FRAMESET> dans CGI.pm mais le HTML est très simple à écrire. Lisez la documentation fournie par Netscape pour plus de détails :

      http://home.netscape.com/assist/net_sites/frames.html

  2. Spécifier la destination du document dans l'en-tête HTTP
    Vous pouvez fournir un paramètre -target à la méthode header() :
        print $q->header(-target=>'ResultsWindow');

    Cela dit au navigateur de charger le résultat de votre script dans le cadre nommé ``ResultsWindow''. Si aucun cadre de ce nom n'existe, le navigateur ouvrira une nouvelle fenêtre et y affichera le résultat de votre script. Il y a un certain nombre de noms magiques que vous pouvez utiliser comme cible (target). Lisez la documentation fournie par Netscape pour plus de détails.

  3. Spécifier la destination du document dans la balise <FROM>.
    Vous pouvez spécifier la cadre visé dans la balise FROM elle-même. Avec CGI.pm, ça ressemble à cela :
        print $q->start_form(-target=>'ResultsWindow');

    Lorsque votre script est réinvoqué par le formulaire, sa sortie sera chargée dans le cadre nommé ``ResultsWindow''. Si aucun cadre de ce nom n'existe, il sera créé.

Le script ``frameset.cgi'' dans le répertoire d'exemples montre un moyen de créer des pages dans lesquelles le formulaire et sa réponse sont dans des cadres côte à côte.


SUPPORT LIMITÉ DES FEUILLES DE STYLES EN CASCADE (CSS)

CGI.pm propose un support limité des feuilles de styles en cascade de HTML3 (css). Pour incorporer un feuille de styles dans votre document, passez un paramètre -style à la méthode start_html(). La valeur de ce paramètre peut être un scalaire, auquel cas il est intégré directement dans une section <STYLE>, ou peut être une référence à une table de hachage. Dans ce dernier cas, votre table de hachage devrait contenir une clé -src et/ou une clé -code. La valeur associée à la clé -src doit être un URL désignant une feuille de styles externe. La valeur associée à la clé -code doit être une valeur scalaire qui sera incorporée dans une section <STYLE>. Les définitions présentes dans -code cacheront celles de même nom présentes dans -src. D'où l'appellation ``en cascade''.

Vous pouvez aussi spécifier le type de feuille de styles en ajoutant un paramètre optionnel -type dans la table de hachage pointée par -style. Le style par défaut est 'text/css'.

Pour vous référer à un style dans le corps de votre document, ajoutez le paramètre -class à n'importe quel élément HTML :

    print h1({-class=>'Fancy'},'Welcome to the Party');

Ou définissez le style au vol grâce au paramètre -style :

    print h1({-style=>'Color: red;'},'Welcome to Hell');

Vous pouvez aussi utiliser la nouvelle balise span() pour appliquer un style à toute une portion de texte :

    print span({-style=>'Color: red;'},
               h1('Welcome to Hell'),
               "Where did that handbasket get to?"
               );

Notez que vous devez importer l'ensemble de fonctions ``:html3'' pour avoir accès à la méthode span(). Voici un exemple « vite fait, mal fait » d'utilisation des CSS. Voir les spécifications CSS sur http://www.w3.org/pub/WWW/TR/Wd-css-1.html pour plus d'information.

    use CGI qw/:standard :html3/;
    # ici une feuille de styles directement dans la page
    $newStyle=<<END;
    <!-- 
    P.Tip {
        margin-right: 50pt;
        margin-left: 50pt;
        color: red;
    }
    P.Alert {
        font-size: 30pt;
        font-family: sans-serif;
      color: red;
    }
    -->
    END
    print header();
    print start_html( -title=>'CGI with Style',
                      -style=>{-src=>'http://www.capricorn.com/style/st1.css',
                               -code=>$newStyle}
                     );
    print h1('CGI with Style'),
          p({-class=>'Tip'},
            "Better read the cascading style sheet spec before playing with this!"),
          span({-style=>'color: magenta'},
               "Look Mom, no hands!",
               p(),
               "Whooo wee!"
               );
    print end_html;

En passant une référence à un tableau comme paramètre -style, vous pourrez incorporer plusieurs feuille de styles dans votre document.


DÉVERMINAGE

Si vous utilisez votre script à partir d'une ligne de commande ou dans le debugger Perl, vous pouvez passer au script une liste de mots-clé ou de paires paramètre=valeur sur la ligne de commande ou à partir de l'entrée standard (vous n'avez pas à bidouiller votre script pour qu'il lise les variables d'environnement). Vous pouvez passer les mots-clé ou les paires de la manière suivante :

    your_script.pl keyword1 keyword2 keyword3

ou comme ça :

   your_script.pl keyword1+keyword2+keyword3

ou comme ça :

    your_script.pl name1=value1 name2=value2

ou comme ça :

    your_script.pl name1=value1&name2=value2

Pour désactiver cette fonctionnalité, utilisez la directive (pragma) -no_debug.

Pour tester la méthode POST, vous devez activer le mode déverminage complet grâce à la directive -debug. Cela vous permettra de saisir sur l'entrée standard des paires paramètre=valeur séparées par des passages à la ligne.

Lorsque vous déverminer, vous pouvez utiliser les apostrophes, les guillemets et les barres obliques inversées (backslashes) d'une manière classique pour votre shell afin de vous permettre de saisir des espaces ou autres caractères bizarres dans vos paires paramètre=valeur :

   your_script.pl "name1='I am a long value'" "name2=two\ words"

Afficher toutes les paires nom/valeur

La méthode Dump() produit une chaîne constituée de toutes les paires nom/valeur de la requête sous la forme de listes imbriquées. C'est pratique pour déverminer :

    print $query->Dump

Produit quelque chose tel que :

    <UL>
    <LI>nom1
        <UL>
        <LI>valeur1
        <LI>valeur2
        </UL>
    <LI>nom2
        <UL>
        <LI>valeur1
        </UL>
    </UL>

Comme raccourci, vous pouvez interpoler l'objet CGI complet dans une chaîne et il sera remplacé par un joli code HTML comme ci-dessus :

    $query=new CGI;
    print "<H2>Current Values</H2> $query\n";

(NdT: pour moi, cela n'a jamais marcher...)


ACCÉDER AUX VARIABLES D'ENVIRONNEMENT

Quelques-unes des variables d'environnement les plus utiles peuvent être consultées via cette interface. Les méthodes sont les suivantes :

Accept()
Retourne une liste des types MIME que le navigateur distant acceptent. Si vous donnez à cette méthode un seul argument correspondant à un type MIME, comme dans $query->Accept('text/html'), elle vous retournera une valeur réelle correspondant au degré de préférence du navigateur pour ce type particulier. Ce degré varie de 0.0 (il n'en veux pas) à 1.0. Les types globaux (e.g. text/*) dans la liste des types acceptés par le navigateur sont correctement gérés.

Remarquez la majuscule qui a été ajoutée entre la version 2.43 et la version 2.44 afin d'éviter un conflit avec la fonction Perl accept().

raw_cookie()
Retourne la variable HTTP_COOKIE, une extension HTTP implémentée par les navigateurs Netscape depuis la version 1.1 et par toutes les versions de Internet Explorer. Les cookies ont un format spécial et cette méthode retourne juste les cookies dans leur format brut. Voir la méthode cookie() pour un moyen de positionner et retrouver des cookies tout cuits.

Appelée sans paramètres, raw_cookie() retourne la structure compacte des cookies. Vous pouvez séparer les différents cookies en la découpant (par split) avec comme séparateur la séquence de caractères ``; ''. Appelée avec le nom de l'un des cookies, retrouve ce cookie sous sa forme non décodée. Vous pouvez utiliser la méthode cookie() pour obtenir les noms des cookies ou utiliser la méthode raw_fetch() du module CGI::Cookie.

user_agent()
Retourne la variable HTTP_USER_AGENT. Si vous donnez un seul argument à cette méthode, elle l'utilisera comme motif de correspondance. Cela vous permet de faire quelque chose comme $query->user_agent(netscape);

path_info()
Retourne l'information de chemin additionnel au delà de l'URL du script. E.G. accéder à /cgi-bin/your_script/additional/stuff fera que $query->path_info() retournera ``/additional/stuff''.

Note: Microsoft Internet Information Server est buggué du point de vue des chemins additionnels. Si vous utilisez une bibliothèque DLL Perl, le serveur IIS essayera d'exécuter le chemin additionnel comme un script Perl. Si vous utilisez le fichier ordinaire d'association, l'information de chemin sera présente dans l'environnement mais de manière incorrecte. La meilleurs chose à faire est d'éviter l'utilisation des chemins additionnels dans les scripts CGI utilisés avec IIS.

path_translated()
Comme path_info() sauf que le chemin additionnel est transformé en un chemin d'accès physique, e.g. ``/usr/local/etc/httpd/htdocs/additional/stuff''.

Microsoft IIS est tout aussi buggué pour ce chemin transformé.

remote_host()
Retourne soit le nom de la machine distante soit son adresse IP si le nom n'est pas disponible.

script_name()
Retourne le nom du script sous la forme d'un URL relatif au serveur pour faciliter l'auto-référencement des scripts.

referer()
Retourne l'URL de la page que le navigateur visualisait juste avant d'accéder à votre script. Cette information n'est pas toujours disponible selon les navigateurs.

auth_type()
Retourne la méthode utilisée pour l'autorisation/vérification d'accès à ce script si elle existe.

server_name()
Retourne le nom du serveur. Habituellement le nom de la machine.

virtual_host()
Lorsqu'on utilise des hôtes virtuels, retourne le nom de l'hôte que le navigateur tente de contacter.

server_software()
Retourne le nom du logiciel serveur et son numéro de version.

remote_user()
Retourne le nom d'autorisation/vérification utilisé pour l'accès à ce script si ce script est protégé.

user_name()
Tente d'obtenir le nom de l'utilisateur distant en utilisant différentes techniques. Cela ne fonctionne qu'avec des très vieux navigateurs tels que Mosaic. Les navigateurs récents ne transmettent pas cette information pour des raisons de protection de la vie privée !

request_method()
Retourne la méthode utilisée pour accéder à ce script, habituellement 'POST', 'GET' ou 'HEAD'.

content_type()
Retourne le content_type des données soumises par un POST, généralement multipart/form-data ou application/x-www-form-urlencoded.

http()
Appelée sans arguments, retournera la liste des variables d'environnement HTTP incluant des choses telles que HTTP_USER_AGENT, HTTP_ACCEPT_LANGUAGE, et HTTP_ACCEPT_CHARSET correspondant aux en-têtes HTTP de noms similaires de la requête. Appelée avec comme argument le nom d'un en-tête HTTP, retournera sa valeur. Les majuscules ou l'utilisation de tiret ou de caractères de soulignements ne changent rien.

Par exemple, les trois exemple suivants sont équivalents :

   $requested_language = $q->http('Accept-language');
   $requested_language = $q->http('Accept_language');
   $requested_language = $q->http('HTTP_ACCEPT_LANGUAGE');

https()
La même chose que http() mais travaillera sur les variables d'environnement HTTPS présentes lorsque le protocole SSL est utilisé. Peut-être utilisé pour déterminer si SSL est activé ou non.


UTILISATION DES SCRIPTS NPH

Les scripts NPH ou ``no-parse-header'' (``en-tête non analysé'') shunte complètement le serveur en envoyant directement tous les en-têtes HTTP au navigateur. Cela peut amener un bénéfice en performance mais c'est surtout utilisé pour tirer avantage d'extensions HTTP qui ne seraient pas supportées directement par votre serveur telles que le ``push'' ou les en-têtes ``PICS'' (Platform for Internet Content Selection).

Les serveurs utilisent différentes conventions pour indiquer que des scripts CGI sont NPH. La plupart des serveurs Unix cherche le préfixe ``nph-'' au début du nom du script. Le serveur Macintosh WebSTAR et Microsoft's Internet Information Server, au contraire, décide si un script est NPH en examinant la première ligne produite par le script.

CGI.pm supporte les scripts NPH grâce à un mode NPH spécial. Lorsque ce mode est utilisé, CGI.pm produira les en-têtes supplémentaires nécessaires lorsque les méthodes header() ou redirect() seront appelées.

Microsoft Internet Information Server utilise obligatoirement le mode NPH. Depuis la version 2.30, CGI.pm détecte automatiquement lorsque le script est appelé depuis IIS et se met tout seul dans le mode NPH. Bien que vous n'avyez pas besoin de le faire manuellement, cela n'entraîne rien de fâcheux si vous le faites.

Il y a plusieurs moyens pour passer CGI.pm en mode NPH :

Dans l'instruction use
Ajoutez tout simplement la directive (pragma) ``-nph'' à la liste des symboles à importer dans votre script :
      use CGI qw(:standard -nph)

En appelant la méthode nph()
Appelez nph() avec un paramètre non nul à n'importe quel endroit de votre programme.
      CGI->nph(1)

En utilisant le paramètre -nph dans vos instructions header() ou redirect()
      print $q->header(-nph=>1);


« SERVER PUSH »

CGI.pm propose trois fonctions simples pour produire des documents multipart, le type nécessaire pour implémenter le « server push ». Ces fonctions ont été gracieusement fournies par Ed Jordan <ed@fidalgo.net>. Pour les importer dans votre espace de noms, vous devez importer l'ensemble ``:push''. Vous devez aussi mettre votre script en mode NPH et positionner la variable $| à 1 pour éviter les problèmes de tampon (bufferisation).

Voici un script simple qui illustre le « server push » :

  #!/usr/local/bin/perl
  use CGI qw/:push -nph/;
  $| = 1;
  print multipart_init(-boundary=>'----------------here we go!');
  while (1) {
      print multipart_start(-type=>'text/plain'),
            "The current time is ",scalar(localtime),"\n",
            multipart_end;
      sleep 1;
  }

Ce script initialise le « server push » en appelant multipart_init(). Il rentre ensuite dans une boucle infinie dans laquelle il débute une nouvelle section multipart en appelant multipart_start(), affiche l'heure locale et termine la section multipart en appelant multipart_end(). Il attend alors une seconde et recommence.

multipart_init()
  multipart_init(-boundary=>$boundary);

Initialise le système multipart. L'argument -boundary spécifie quelle chaîne MIME servira de borne pour séparer les différentes parties du document. Si non spécifié, CGI.pm choisira pour vous une borne raisonnable.

multipart_start()
  multipart_start(-type=>$type)

Démarre une nouvelle partie d'un document multipart en utilisant le type MIME spécifié (par -type). Par défaut, c'est le type text/html.

multipart_end()
  multipart_end()

Termine une partie. Souvenez-vous que vous devez appeler multipart_end() pour chaque appel à multipart_start().

Les utilisateurs intéressés par les applications « server push » devrait jeter un oeil au module CGI::Push.


ÉVITER LES ATTAQUES DE DÉNI DE SERVICE

Un problème potentiel avec CGI.pm est que, par défaut, il tente de traiter les formulaires POSTés quel que soit la taille qu'ils ont. Un hackeur rusé pourrait attaquer votre site en envoyant à un script CGI un énorme POST de plusieurs méga-octets. CGI.pm tentera de lire entièrement ce POST dans une variable, gonflant ainsi en taille jusqu'à saturation de la mémoire. Pendant que le script tentera d'allouer la mémoire, le système ralentira dramatiquement. C'est une forme d'attaque par déni de service.

Une autre attaque possible pour un utilisateur distant consiste à contraindre CGI.pm à accepter le téléchargement d'un énorme fichier. CGI.pm acceptera le téléchargement et le stockera dans un répertoire temporaire même si votre script ne s'attend pas du tout à recevoir un fichier téléchargé. CGI.pm effacera automatiquement ce fichier lorsque le script s'arrêtera mais en attendant l'utilisateur distant aura réussi à remplir l'espace disque du serveur causant ainsi des problèmes à d'autres programmes.

Le meilleur moyen d'éviter ces attaques de déni de service est de limiter le quantité de mémoire, de temps CPU et d'espace disque qu'un script CGI peut utiliser. Quelques serveurs WEB possèdent des fonctionnalités intégrées pour accomplir cela. Dans les autres cas, vous pouvez utiliser les commandes shell limit ou ulimit pour plafonner l'utilisation des ressources par les CGI.

CGI.pm propose lui-aussi quelques fonctionnalités simples de protection contre les attaques de type déni de service mais vous devez les activer explicitement. Elles se présentent sous la forme de deux variables globales dans l'espace de nom CGI :

$CGI::POST_MAX
Si sa valeur est un entier non négatif, cette variable constitue un plafond pour la taille en octets d'un POST. Si CGI.pm détecte un POST dont la taille dépasse ce plafond, il s'arrête immédiatement avec un message d'erreur. Cette valeur agit à la fois sur les POST ordinaires et ceux multiparties, limitant ainsi la taille maximale d'un fichier téléchargé. Vous devriez mettre cette valeur à une valeur raisonnable telle que 1 méga-octets.

$CGI::DISABLE_UPLOADS
Si sa valeur est non nulle, cela désactive totalement le téléchargement de fichier. Les autres types de formulaires continuent à fonctionner comme d'habitude.

Vous pouvez utiliser ces variables de deux manières.

Au cas par cas (script par script)
Fixez les valeurs de ces variables au début du script, juste après l'instruction ``use'' :
    use CGI qw/:standard/;
    use CGI::Carp 'fatalsToBrowser';
    $CGI::POST_MAX=1024 * 100;  # max 100K posts
    $CGI::DISABLE_UPLOADS = 1;  # no uploads

Globalement pour tous les scripts
Éditez le fichier CGI.pm et trouvez les définitions de $POST_MAX et de $DISABLE_UPLOADS. Placez les valeurs désirées. Vous trouverez ces variables au début du fichier dans une subroutine appelée initialize_globals().

Une tentative d'envoi d'un POST plus large que $POST_MAX octets aura pour conséquence le retour par la fonction param() d'une liste de paramètres CGI vide. Vous pouvez tester cela en vérifiant cgi_error(), soit après avoir créé l'objet CGI soit, si vous utilisez l'interface orientée fonction, après le premier appel à param(). Si le POST est trop volumineux alors cgi_error() retournera le message ``413 POST too large''.

Ce message est défini par le protocole HTTP et est conçu pour être retourné au navigateur en tant que code d'état (status) du script CGI. Par exemple :

   $uploaded_file = param('upload');
   if (!$uploaded_file && cgi_error()) {
      print header(-status=>cgi_error());
      exit 0;
   }

Par contre, il n'est pas sûr que tous les navigateurs sachent quoi faire de ce code d'état. Il peut être intéressant de créer une page HTML qui informe l'utilisateur de ce problème.


COMPATIBILITÉ AVEC CGI-LIB.PL

Pour faciliter la migration des programmes existant qui utilisent cgi-lib.pl, la routine de compatibilité ``ReadParse'' est fournie. La migration est simple:

 ANCIENNE VERSION
    require "cgi-lib.pl";
    &ReadParse;
    print "The value of the antique is $in{antique}.\n";
 NOUVELLE VERSION
    use CGI;
    CGI::ReadParse
    print "The value of the antique is $in{antique}.\n";

La routine ReadParse() de CGI.pm crée une variable liée (par tie()) nommée %in qui peut être utilisée pour accéder aux paramètres de la requête. Comme avec ReadParse, vous pouvez aussi fournir votre propre variable. Les fonctionnalités très peu utilisées de ReadParse telles que la création de @in ou de $in ne sont pas supportées.

Une fois que vous avez utilisé ReadParse, vous pouvez retrouver l'objet requête lui-même par ce moyen :

    $q = $in{CGI};
    print $q->textfield(-name=>'wow',
                        -value=>'does this really work?');

Cela vous permet de commencer à utiliser les fonctionnalités les plus intéressantes de CGI.pm sans nécessité une réécriture complète de votre vieux script.


INFORMATION SUR LES AUTEURS

Copyright 1995-1998, Lincoln D. Stein. Tous droits réservés.

Cette bibliothèque est un logiciel libre ; vous pouvez la redistribuer et/ou la modifier dans les mêmes conditions que Perl.

Envoyer les rapports de bug et les commentaires (en anglais) à : lstein@cshl.org. Lorsque vous envoyez un rapport de bug, précisez la version de CGI.pm, la version de Perl, le nom et la version de votre serveur Web ainsi que le nom et la version du système d'exploitation que vous utilisez. Si le problème dépend de navigateur utilisé, envoyez aussi les informations concernant ce navigateur.

Copyright 1995-1998, Lincoln D. Stein. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

Address bug reports and comments to: lstein@cshl.org. When sending bug reports, please provide the version of CGI.pm, the version of Perl, the name and version of your Web server, and the name and version of the operating system you are using. If the problem is even remotely browser dependent, please provide information about the affected browers as well.


REMERCIEMENTS

Merci à :

Matt Heffron (heffron@falstaff.css.beckman.com)
James Taylor (james.taylor@srs.gov)
Scott Anguish <sanguish@digifix.com>
Mike Jewell (mlj3u@virginia.edu)
Timothy Shimmin (tes@kbs.citri.edu.au)
Joergen Haegg (jh@axis.se)
Laurent Delfosse (delfosse@delfosse.com)
Richard Resnick (applepi1@aol.com)
Craig Bishop (csb@barwonwater.vic.gov.au)
Tony Curtis (tc@vcpc.univie.ac.at)
Tim Bunce (Tim.Bunce@ig.co.uk)
Tom Christiansen (tchrist@convex.com)
Andreas Koenig (k@franz.ww.TU-Berlin.DE)
Tim MacKenzie (Tim.MacKenzie@fulcrum.com.au)
Kevin B. Hendricks (kbhend@dogwood.tyler.wm.edu)
Stephen Dahmen (joyfire@inxpress.net)
Ed Jordan (ed@fidalgo.net)
David Alan Pisoni (david@cnation.com)
Doug MacEachern (dougm@opengroup.org)
Robin Houston (robin@oneworld.org)
...et tant d'autres encore....
pour leurs suggestions et leurs corrections de bugs.

Traduction française

Paul Gaborit (Paul.Gaborit@enstimac.fr)
Antony Use (a.use@webfutur.com)


UN EXEMPLE COMPLET DE SCRIPT CGI

        #!/usr/local/bin/perl
        use CGI;
        $query = new CGI;
        print $query->header;
        print $query->start_html("Example CGI.pm Form");
        print "<H1> Example CGI.pm Form</H1>\n";
        &print_prompt($query);
        &do_work($query);
        &print_tail;
        print $query->end_html;
        sub print_prompt {
           my($query) = @_;
           print $query->start_form;
           print "<EM>What's your name?</EM><BR>";
           print $query->textfield('name');
           print $query->checkbox('Not my real name');
           print "<P><EM>Where can you find English Sparrows?</EM><BR>";
           print $query->checkbox_group(
                                 -name=>'Sparrow locations',
                                 -values=>[England,France,Spain,Asia,Hoboken],
                                 -linebreak=>'yes',
                                 -defaults=>[England,Asia]);
           print "<P><EM>How far can they fly?</EM><BR>",
                $query->radio_group(
                        -name=>'how far',
                        -values=>['10 ft','1 mile','10 miles','real far'],
                        -default=>'1 mile');
           print "<P><EM>What's your favorite color?</EM>  ";
           print $query->popup_menu(-name=>'Color',
                                    -values=>['black','brown','red','yellow'],
                                    -default=>'red');
           print $query->hidden('Reference','Monty Python and the Holy Grail');
           print "<P><EM>What have you got there?</EM><BR>";
           print $query->scrolling_list(
                         -name=>'possessions',
                         -values=>['A Coconut','A Grail','An Icon',
                                   'A Sword','A Ticket'],
                         -size=>5,
                         -multiple=>'true');
           print "<P><EM>Any parting comments?</EM><BR>";
           print $query->textarea(-name=>'Comments',
                                  -rows=>10,
                                  -columns=>50);
           print "<P>",$query->reset;
           print $query->submit('Action','Shout');
           print $query->submit('Action','Scream');
           print $query->endform;
           print "<HR>\n";
        }
        sub do_work {
           my($query) = @_;
           my(@values,$key);
           print "<H2>Here are the current settings in this form</H2>";
           foreach $key ($query->param) {
              print "<STRONG>$key</STRONG> -> ";
              @values = $query->param($key);
              print join(", ",@values),"<BR>\n";
          }
        }
        sub print_tail {
           print <<END;
        <HR>
        <ADDRESS>Lincoln D. Stein</ADDRESS><BR>
        <A HREF="/">Home Page</A>
        END
        }


BUGS

Ce module est énorme et monolithique. De plus il fait de nombreuses choses telles la manipulation d'URL, l'analyse des entrés CGI, l'écriture du HTML, etc. qui sont aussi faites dans le modules LWP. Il devrait être abandonné en faveur des modules CGI::* mais je continue à travailler dessus.

Remarquez que le code est parfois tordu pour éviter des avertissements inutiles lorsque les programmes utilisent l'option -w.


VOIR AUSSI

la page de manuel CGI::Carp, la page de manuel URI::URL, la page de manuel CGI::Request, la page de manuel CGI::MiniSvr, la page de manuel CGI::Base, la page de manuel CGI::Form, la page de manuel CGI::Push, la page de manuel CGI::Fast, la page de manuel CGI::Pretty