=head1 NOM CGI - Classe simple pour CGI (Common Gateway Interface) =head1 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; } =head1 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/ =head1 DESCRIPTION =head2 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. =head2 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('some','contents');

some contents

h1({-align=>left});

h1({-align=>left},'contents');

contents

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 B<-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 : =over 4 =item 1. Utiliser un autre nom pour l'argument, s'il existe. Par exemple, -value est un synonyme pour -values. =item 2. Changer la casse, e.g. -Values =item 3. Placer des apostrophes autour du nom de l'argument. e.g. '-values' =back 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. =head2 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. =head2 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 B. 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({}); =head2 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 , les mots-clé demandés peuvent être récupérés sous la forme d'un tableau grâce à la méthode keywords(). =head2 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 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). =head2 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. =head2 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'); =head2 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é. =head2 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 B. 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 B. =head2 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. =head2 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. =head2 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 B 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é B<-name>. =head2 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 I<:cgi-lib> (voir aussi la section concernant la compatibilité CGI-LIB). =head2 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 à B. 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 B. =head2 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 I. 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 à I. =head2 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 ; 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 B 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 : =over 4 =item B<:cgi> Importe toutes les méthodes de manipulation de CGI telles que B, B et autres. =item B<:form> Importe toutes les méthodes permettant de générer des formulaires comme B. =item B<:html2> Importe toutes les méthodes permettant de générer du HTML 2 standard. =item B<:html3> Importe toutes les méthodes permettant de générer du HTML 3.0 (tel que , et ). =item B<:netscape> Importe toutes les méthodes permettant de générer les extensions de HTML spécifiques à Netscape. =item B<:html> Importe toutes les fonctions permettant de générer du HTML (i.e. 'html2' + 'html3' + 'netscape')... =item B<:standard> Importe toutes les fonctions standard : 'html2', 'html3', 'form' et 'cgi'. =item B<: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. =back 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 (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 B la syntaxe standard de L 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 B, B, B et autres. (Si vous avez besoin d'accéder directement à cet objet CGI, vous pouvez le trouver dans la variable globale B<$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; =head2 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 : =over 4 =item -any Quand vous spécifiez la directive I<-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 I 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 I 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. =item -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). =item -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. =item -no_xhtml Par défaut, depuis la version 2.69, CGI.pm produit du XHTML (F). La directive -no_xhtml désactive cette fonctionnalité. Merci à Michalis Kabrianis pour cette fonctionnalité. =item -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. =item -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. =item -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. =item -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. I : quand la directive I<-autoload> est active, vous ne pouvez pas utilisez le "mode poète" (les fonctions sans parenthèses). Utilisez plutôt I plutôt que I
ou ajoutez quelque chose comme I au début de votre script. =item -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); =item -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. =item -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 : =over 4 =item 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). =item 2. Si la variable d'environnement TMPDIR existe, on utilise l'emplacement spécifié. =item 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. =back =back =head2 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 :

Level 1 Header

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_I ou end_I comme dans : print start_h1,'Level 1 Header',end_h1; À quelques exceptions près (décrites plus bas), les fonctions start_I et end_I ne sont pas générées automatiquement lorsque vous faites I. En revanche, vous pouvez spécifier les balises pour lesquelles vous voulez générer les fonctions I en plaçant un astérisque devant leur nom ou en demandant explicitement soit la fonction "start_I" soit la fonction "end_I" 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 : =over 4 =item 1. start_table() (génère une balise
) =item 2. end_table() (génère une balise
) =item 3. start_ul() (génère une balise
    ) =item 4. end_ul() (génère une balise
) =back =head1 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. =head2 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'); B 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 B<-type>, B<-status>, B<-expires> et B<-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 B<-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 B<-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 B<-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 B<-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 B<-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 B<-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 B<-type> à "application/octet-stream". =head2 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 B 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); =head2 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 . 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 . Les paramètres supplémentaires doivent être précédés d'un tiret. L'argument B<-xbase> vous permet de choisir pour la balise , 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 B<-target> vous permet de choisir un cadre (frame) cible par défaut pour tous les liens et formulaires de la page. B 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 B<-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 qui ressembleront à quelque chose comme : Pour créer une balise du type HTTP-EQUIV, utilisez B<-head> comme décrit plus bas. L'argument B<-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 B<-lang> est utilisé pour ajouter un attribut de langue dans la balise . 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 grâce à B<-head>. Par exemple, pour ajouter l'élément , 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 , 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 HTTP-EQUIV : print header(-head=>meta({-http_equiv => 'Content-Type', -content => 'text/html'})) JAVASCRIPT : Les paramètres B<-script>, B<-noScript>, B<-onLoad>, B<-onMouseOver>, B<-onMouseOut> et B<-onUnload> sont utilisés pour insérer dans votre page des appels au langage JavaScript de Netscape. B<-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