Cours langage Perl pdf

Problème à signaler:

Télécharger



★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

I.          INTRODUCTION .2

A.      QU’EST CE QUE PERL ? ..2 B. QUELLE UTILISATION ? 2

     C.                     DEUX VERSIONS .3

II.       APERÇU ..3

III.        TYPES DE DONNÉES .3

A.      CONSTANTES ..3 B. SCALAIRES 3 C. TABLEAUX, LISTES 4

D.       TABLEAUX INDICÉS (OU ASSOCIATIFS)

..4

E.        REMARQUES 5

IV.        EXPRESSIONS .6

A.      OPÉRATEURS 6

B.      COMPARAISONS .7

V.        SYNTAXE GÉNÉRALE .8

A.      EXPRESSIONS CONDITIONNELLES 9

B.      BOUCLES 10

C.      PROCÉDURES 12

VI.        FONCTIONS PRÉDÉFINIES 13

A.      SYSTÈME 13 B. MATHÉMATIQUE .13 C. CHAÎNES DE CARACTÈRES 14 D. TABLEAUX, LISTES .14

      E.                      TABLEAUX INDICÉS 16

VII.      GESTION DE FICHIERS 17

A.      OUVERTURE .17 B. FERMETURE .18 C. LECTURE 18 D. ECRITURE .18 E. PARCOURS .18

     F.                      FICHIER SPÉCIAL : <> 19

VIII.      EXPRESSIONS RÉGULIÈRES .20

A.      RAPPEL 20

B.      REMPLACEMENT .23 IX. VARIABLES ET TABLEAUX SPÉCIAUX ..24

X.      STRUCTURES COMPLEXES .24

XI.      EXEMPLES .25

A.      PASSAGES DE PARAMÈTRES AU PROGRAMME 25

B.      PARCOURS DE FICHIER ..26 C. PROGRAMMATION OBJET .28 D. PERL ET CGI .31

E.        ACCÈS AUX BASES DE DONNÉES : DBPERL .36

F.        ACCÈS À UNE BASE DE DONNÉES DEPUIS WEB .38

XII.    BIBLIOGRAPHIE ..40

XIII.    INDEX                     42

XIV.    ANNEXES: Installation/utilisation de perl sur Unix / Windows / Mac                     43

I.       INTRODUCTION

                A.        Qu’est ce que PERL ?

P.E.R.L. signifie Practical Extraction and Report Language. Que l'on pourrait (essayer de) traduire par « langage pratique d'extraction et d'édition ».

Créé en 1986 par Larry Wall (ingénieur système). Au départ pour gérer un système de « News » entre deux réseaux.

C'est :

•    Un langage de programmation

•    Un logiciel gratuit (que l'on peut se procurer sur Internet notamment)

•    Un langage interprété :

? pas de compilation

? moins rapide qu'un programme compilé

? chaque « script » (programme Perl) nécessite d'avoir l'interpréteur Perl sur la machine pour s'exécuter.

Pourquoi Perl est devenu populaire :

•    portabilité : Perl existe sur la plupart des plateformes aujourd’hui (Unix, NT, Windows, Mac, VMS, Amiga, Atari )

•    gratuité : disponible sur Internet (ainsi qu'un nombre impressionnant de librairies et d'utilitaires)

•    simplicité : Quelques commandes permettent de faire ce qu’un programme de 500 lignes en C ou en Pascal faisait.

•    robustesse : Pas d’allocation mémoire à manipuler, chaînes, piles, noms de variables illimités

                B.        Quelle utilisation ?

A l'origine Perl a été créé pour :

1)   manipuler des fichiers (notamment pour gérer plusieurs fichiers en même temps),

2)   manipuler des textes (recherche, substitution),

3)   manipuler des processus (notamment à travers le réseau).

=> Perl était essentiellement destiné au monde UNIX

Pourquoi utilise t'on Perl aujourd'hui ?

1) générer, mettre à jour, analyser des fichiers HTML (notamment pour l’écriture de CGI), 2) accès « universel » aux bases de données, 3) conversion de formats de fichiers.

=> Perl n’est plus lié au monde UNIX

Perl n’est pas fait pour :

•   écrire des interfaces interactives (mais il existe maintenant le module tkperl, qui le permet, sur Unix ou Windows),

•   le calcul scientifique (Perl n’est pas compilé : problème de performances).

                C.        Deux versions

Deux versions principales de Perl :

-    Perl 4 : L'ancienne version (encore utilisée)

-    Perl 5 : La nouvelle version qui intègre la programmation objet (actuellement 5.6.1)

 

F est un descripteur de fichier, que l'on peut appeler comme on veut (l'usage veut que l'on note les descripteurs de fichier en majuscules : Fentree, ENTREE, Fichier, FIC …). Chaque instruction Perl se termine par un point-virgule.

III.     Types de données

                A.        Constantes

1, -12345, 0.1415, 1.6E16 (signifie 160 000 000 000 000 000), 'cerise',

'a', 'les fruits du palmier sont les dattes'

                B.        Scalaires

Les scalaires sont précédés du caractère $

$i = 0; $c = 'a';

$mon_fruit_prefere = 'kiwi';

$racine_carree_de_2 = 1.41421; $chaine = '100 grammes de $mon_fruit_prefere';

=> '100 grammes de $mon_fruit_prefere'

$chaine = "100 grammes de $mon_fruit_prefere";

=> '100 grammes de kiwi'

Attention : Pas d'accents ni d'espaces dans les noms de variables (dans les dernières versions de Perl, les noms de variables peuvent être accentués)

Par contre un nom peut être aussi long qu'on le veut.

                C.        Tableaux, listes

En Perl, les tableaux peuvent être utilisés comme des ensembles ou des listes. Toujours précédés du caractère «              @ » :

@chiffres = (1,2,3,4,5,6,7,8,9,0);

@fruits = ('amande','fraise','cerise');

@alphabet = ('a'..'z');     Les deux points signifient de "tant à tant"

@a = ('a'); @nul = ();

@cartes = ('01'..'10','Valet','Dame','Roi');

on fait référence à un élément du tableau selon son indice par : $chiffres[1]  (=> 2)

$fruits[0]   (=> 'amande')

REMARQUE : En Perl (comme en C) les tableaux commencent à   l'indice 0

On peut affecter un tableau à un autre tableau :

@ch = @chiffres;

@alphanum = (@alphabet, '_', @chiffres);

=>  ('a','b,', ,'z','_','1','2','3','4','5','6','7','8','9','0')

@ensemble = (@chiffres, 'datte', 'kiwi', 12.45);

Remarques :

On dispose d'un scalaire spécial : $#tableau qui indique le dernier indice du tableau (et donc sa taille - 1) : $fruits[$#fruits] (=> 'cerise')

Possibilité de référencer une partie d'un tableau

@cartes[6..$#cartes] => ('07','08','09','10','Valet','Dame','Roi')

@fruits[0..1] => ('amande', 'fraise')

                D.        Tableaux indicés (ou associatifs)

Ils sont toujours précédés du caractère «   % » :

%prix = ('amande'=>30, 'fraise'=>9, 'cerise'=>25); ou :

%prix = (amande=>30, fraise=>9, cerise=>25);

En Perl 4 la notation est :

%prix = ('amande',30, 'fraise',9, 'cerise',25);

On référence ensuite un élément du tableau par :       $prix{'cerise'} (=> 25) ( ou $prix{cerise})

Exemples:

%chiffre = ();

$chiffre{'un'} = 1;            => ou $chiffre{un} = 1; print $chiffre{un};

$var = 'un'; print $chiffre{$var};

                E.        Remarques

                               1.         Perl5 autorise les combinaisons, comme un tableau de tableaux :

%saisons = (

'abricot'=>['été'],

'fraise'=> ['printemps','été'],

'pomme'=> ['automne','hiver'],

'orange'=> ['hiver'],

'cerise'=> ['printemps'],

'amande'=> ['printemps','été','automne','hiver']); ou

@departements = (

[ 'Ain', 'Bourg-en-Bresse', 'Rhône-Alpes'],

[ 'Aisne', 'Laon', 'Picardie'],

[ 'Yonne', 'Auxerre', 'Bourgogne']);

Et l’on accédera à la région du Finistère, ou à la préfecture d'Ille et Vilaine par

$departements[29 - 1][2], $departements[35 - 1][1]

( On retranche un car l'indice des tableaux commence toujours à 0)

2.      Pas de booléens (comme en langage C)

On utilise des entiers sachant que 0 est évalué comme étant faux (en fait il s'agit de la chaîne de caractère vide) et 1 comme étant vrai.

$deux_plus_grand_que_un = (2 > 1);

if ($deux_plus_grand_que_un) { print "Ok !";

}

Le programme répondra Ok !

3.      Tableaux à deux dimensions

On peut utiliser les tableaux indicés pour simuler des tableaux à 2 (ou n) dimensions :

%table_multiplication = ('1,1'=>1, '1,2'=>2, , '9,8'=>72,'9,9'=>81);

$traduction{'amande','anglais'} = 'almond';

$traduction{'amande','italien'} = 'amoria';

$traduction{'cerise','anglais'} = 'cherry';

On peut également utiliser les tableaux de tableaux de Perl 5 pour le faire :

@table_multiplication = (

[  0, 0, 0, 0, 0, 0, 0, 0, 0, 0], # Multiplié par 0

[  0, 1, 2, 3, 4, 5, 6, 7, 8, 9], # Multiplié par 1

[  0, 2, 4, 6, 8,10,12,14,16,18], # Multiplié par 2

[  0, 9,18,27,36,45,54,63,72,81]); # Multiplié par 9

On référencera alors 2*6 par $table_mult[6] [2]

IV.     Expressions

                A.        Opérateurs

De nombreux opérateurs existent en Perl (hérités la plupart du temps du langage C). Voici les principaux :

1.        Opérateurs arithmétiques

$a = 1; $b = $a;        les variables a, et b auront pour valeur 1

$c = 53 + 5 - 2*4;   => 50

Plusieurs notations pour incrémenter une variable

$a = $a + 1; ou $a += 1;   ou encore $a++; => addition

Même chose pour * (multiplication), - (soustraction), / (division), ** (exponentielle)

$a *= 3; $a /= 2; $a -= $b;

% : modulo ( 17 % 3 =>2)

2.        Chaînes de caractères . concaténation

$c = 'ce' . 'rise';

(=> $c devient 'cerise')

$c .= 's';                        

x réplique

$b = 'a' x 5;   => 'aaaaa'

(=> $c devient 'cerises')

$b = 'jacqu' . 'adi' x 3   => 'jacquadiadiadi'

$b = 'assez ! '; $b x= 5; => 'assez ! assez ! assez ! assez ! assez ! assez !'

3.        Parenthèses

Comme dans tous les langages de programmation, les parenthèses peuvent être utilisées dans les expressions :

$x = 2 * (56 - 78);

                B.        Comparaisons

1.      de chiffres

Ce sont les opérateurs habituels :

> , >=, <, <=, ==, !=

respectivement : supérieur à, supérieur ou égal, inférieur à, inférieur ou égal, égalité, différent

Attention: = est une affectation, == est une comparaison if ($a = 2)  => sera toujours vrai ! Il  aurait fallu écrire:      if ($a == 2)

2.      de chaînes

gt , ge, lt, le, eq, ne

respectivement            : supérieur à (selon l'ordre alphabétique), supérieur ou égal, inférieur à, inférieur ou égal, égalité, différent

Attention! Ne pas confondre la comparaison de chaînes et d'entiers 'b' == 'a'           => évalué comme étant vrai ! il faut écrire :

'b' eq 'a'  => évalué faux bien-sûr

3.      de booléens

Même si le type booléen n'existe pas en tant que tel, des opérateurs existent : ||     (ou inclusif), && (et), ! (négation)

(!  2 < 1)

=> vrai

(1  < 2) && (2 < 3)

=> vrai

( $a < 2) || ($a == 2)

équivaut à ($a <= 2)

(! $a && !$b)

équivaut à !($a || $b) (règle de Morgan !)

Remarque : depuis Perl5 une notation plus agréable existe : or (au lieu de ||), and (au lieu de &&), not (au lieu de !)

if (not ($trop_cher or $trop_mur)) {print "J'achete !";}

V.      Syntaxe générale

Chaque instruction doit être terminée par un point-virgule. Un passage à la ligne ne signifie pas une fin d'instruction (ce qui est souvent source d'erreurs au début).

 

Ce programme est erroné !

$a = 'Une très longue chaîne de caractère qui ne peut s'écrire

sur une seule ligne';

Ok !

Les commentaires commencent par un #

Tout le reste de la ligne est considéré comme un commentaire.

# voici un commentaire

$a = 3; # Et en voici un autre

Un bloc est un ensemble de commandes entourées par des crochets (           {}), chaque commande étant suivie d'un point-virgule.

                A.        Expressions conditionnelles

Syntaxe

Exemple

if (expression) { bloc; }

if ($prix{'datte'} > 20) { print 'Les dattes sont un peu cheres ';

print 'Achetons plutôt des cerises'; }

if (expression) { bloc;

} else { bloc2;

}

if ($fruit eq 'fraise') {

print 'parfait !';

} else {

print 'Bof!';

print 'Je préfère sans pépin';

}

if (exp1) { bloc1;

} elsif (exp2) { bloc2;

} elsif (exp3) { bloc3;

}

if (($fruit eq 'cerise')or($fruit eq 'fraise')) { print 'rouge';

} elsif ($fruit eq 'banane') { print 'jaune';

} elsif ($fruit eq 'kiwi') { print 'vert';

} else { print 'je ne sais pas '; }

Remarque: il existe une autre notation :

commande  if (condition);

print 'Quand nous chanterons ' if ($fruit eq 'cerise');

Condition inversée:

unless (            condition) { bloc

} ;  

Ou, selon la notation alternative: commande  unless (condition);

print 'Sans sucre SVP ' unless ($fruit eq 'fraise');

                B.        Boucles

1.      « tant que »

Syntaxe

Exemple

while (expression) { bloc;

}

$mon_argent = $porte_monnaie; while ($mon_argent > $prix{'cerise'}) {

$mon_argent -= $prix{'cerise'};

# ou $mon_argent = $mon_argent  - $prix{'cerise'}

print "Et un kilo de cerises !";

}

Remarque:

Là aussi il existe une autre notation

commande  while (condition)

print "Je compte : $i" while ($i++ < 10);

2.      « répéter »

Syntaxe

Exemple

do { bloc;

} while (expression);

# Recherche du premier fruit <= 10 F

$i = 0; do {

$f = $fruits[$i];

$i++;

} while ($prix{$f} > 10);

print "Je prend : $f";

do { bloc;

} until (expression);

$i = 10;

do { print $i;

$i--;

} until ($i == 0);

Autre exemple : recherche du premier fruit par ordre alphabétique :

$min = $fruits[0]; $i=0;# $min contient le premier fruit

do {

# Si on trouve un fruit moins grand (par ordre alphabétique)

if ($fruits[$i] lt  $min) {

$min = $fruits[$i]; # il devient le minimum

}

$i++; # On passe au suivant } until ($i > $#fruits);

3.      « pour »

Syntaxe

Exemple

for (init;condition;cmd) { bloc; }

for ($mon_argent = $porte_monnaie;   $mon_argent > $prix{'cerise'};

$mon_argent -= $prix{'cerise'}) {

print "Et un kilo de cerises !";

}

Plus souvent utilisé pour le parcours de tableaux :

 

for ($i = 0;$i < taille; $i++) { bloc; }

for ($i=0; $i <= $#fruit; $i++) {

print $fruit[$i]; }

 

Attention à bien mettre un point-virgule entre les différents éléments d’un « for »

4.      « pour tout »

Syntaxe

Exemple

foreach élément (tableau) { bloc; }

foreach $f (@fruits) {

print $f; }

 

Très utilisé pour le parcours de tableaux

                C.        Procédures

1.      déclaration

sub ma_procedure {

bloc; }

Appel: &ma_procedure(); ou ma_procedure;

2.      avec paramètre(s)

sub pepin {

my($fruit) = @_;

 

if (($fruit ne 'amande') and ($fruit ne 'fraise')) {

print "ce fruit a des pépins !";

}

}

Appel: &pepin('cerise'); ou pepin('cerise');

Remarque: L’instruction « my » réalise une affectation dans des variables locales à la procédure avec les éléments du tableau. Les paramètres sont placés dans un tableau spécial @_, on peut éventuellement référencer chaque paramètre par $_[0], $_[1]… souvent au détriment de la lisibilité ! Ce type de passage de paramètre est très pratique car le nombre de paramètres n’est pas forcément fixe.

La procédure précédente aurait pu s'écrire :

sub pepin {

print " ce fruit a des pépins !"

     if (($_[0] ne 'amande') and ($_[0] ne 'fraise')); }

3.      fonctions

Une fonction est une procédure qui retourne quelque chose :

sub pluriel {

my($mot) = @_;

$m = $mot.'s'; return($m); }

Appel: $mot_au_pluriel = &pluriel('cerise'); => 'cerises'

Variables locales: Attention au petit piège habituel :

$m = 'Dupont';

$f = &pluriel('cerise'); print "M. $m vend des $f\n";

affichera : M. cerises vend des cerises !

A cause du fait qu'on utilise la variable $m qui est modifiée dans la fonction pluriel

La solution consiste à déclarer toutes les variables utilisées dans les procédures en variables locales à l'aide de « my ».

A la troisième ligne de la procédure « pluriel » on rajoutera : my $m;

VI.     Fonctions prédéfinies

Quelques fonctions offertes par Perl pour manipuler les données. L'inventaire n'est pas exhaustif.

                A.        Système

• print : permet d'afficher un message, ou le contenu de variables.

print 'bonjour';

print 'J\'ai acheté ', $nombre,' kilos de ', $fruit;

print;          => affiche le contenu de la variable spéciale $_ ou encore :

print "J'ai acheté $nombre kilos de ", &pluriel($fruit);

Problèmes courants : les caractères spéciaux (',",$, ), que l'on peut afficher en les précédant d'un « \ »

ex:  print "Il dit alors : \"Non, je n'ai pas 50 \$ !\" ";

Autre solution pour les longs textes :

print <<"FIN"; # Tout ce qui suit jusqu'à FIN en début de ligne

Ceci est un long texte

qui n'est pas perturbé par la présence de "guillemets" ou

d'apostrophes

FIN

Quelques caractères spéciaux affichables avec « print » :

\n => « retour-chariot », \t => tabulation, \b => « bip »

•  exit : permet d'arrêter le programme en cours

if ($erreur) {exit;}

•  die : permet d'arrêter le programme en cours en affichant un message d'erreur.

            if ($fruit eq 'orange') {die 'Je déteste les oranges !'}

•  system : permet de lancer une commande système  system 'mkdir mon_repertoire';

•  sleep n : le programme « dort » pendant n secondes         ex: programme « bip horaire »

 while (1) {sleep 3600; print "\b";} le fait d’écrire « while (1) » permet de faire une boucle infinie (on aurait pu écrire :

« for (;;) »)

                B.        Mathématique

Les fonctions mathématiques habituelles existent aussi en Perl :

sin     , cos, tan, int (partie entière d'un nombre), sqrt, rand (nombre aléatoire entre 0 et n), exp (exponentielle de n), log, abs (valeur absolue).

$s = cos(0);                             => 1

$s = log(exp(1));                 => 1

$i = int(sqrt(8));                => 2

$tirage_loto = int(rand(42)) + 1;

$i = abs(-5.6)                          => 5.6

                C.        Chaînes de caractères

•  chop(ch)     Enlève le dernier caractère de la chaîne

                        $ch='cerises'; chop($ch);    => ch contient 'cerise'

•  chomp(ch) Même chose que « chop » mais enlève uniquement un « retour-chariot »     éventuel en fin de chaîne. Utilisé dans le parcours de fichiers (cf p. 18)

•  length(ch) Retourne la longueur de la chaîne (nombre de caractères)

                        $l = length('cerise')                                => 6

•  uc(ch)         Retourne la chaîne en majuscules (Perl 5)

                        $ch = uc('poire')                               =>  ‘POIRE’

•  lc(ch)          Retourne la chaîne en minuscules (Perl 5)

                        $ch = lc('POIRE')                               =>  ‘poire

•  lcfirst(ch), ucfirst(ch)         Retourne la chaîne avec simplement le premier caractère en minuscule/majuscule (Perl 5)

                        $ch = ucfirst('la poire')                                   =>  ‘La poire

•  split('motif', ch)      Sépare la chaîne en plusieurs éléments (le séparateur étant motif).

                                    Le résultat est un tableau. (Fonction très utilisée)

                        @t = split(' / ', 'amande / fraise / cerise');

=> ('amande','fraise', 'cerise')

•  substr(ch, indicedébut, longueur)

Retourne la chaîne de caractère contenue dans ch, du caractère indicedébut et de longueur longueur (le premier caractère étant à l'indice 0).

                                $ch=substr('dupond', 0, 3)                    => 'dup'

                               $ch=substr('Les fruits', 4)                  => 'fruits'

•  index(ch, recherche)          Retourne la position de recherche dans la chaîne ch

                               $i=index('Le temps des cerises','cerise');      => 13

Remarque:

Par défaut la plupart de ces fonctions travaillent sur la variable spéciale $_

$_ = 'amandes'; chop; print;                           => Affichera 'amande'

                D.        tableaux, listes

•  grep(/expression/, tableau) Recherche d'une expression dans un tableau  if (grep(/poivron/, @fruits)); => faux  if (grep(/$f/, @fruits)) {print 'fruit connu';}  grep retourne un tableau des éléments trouvés :

            @f = grep(/ise$/, @fruits);       => fraise;cerise

•  join(ch, tableau)     Regroupe tous les éléments d'un tableau dans une chaîne de caractères (en spécifiant le séparateur)

            print join(', ', @fruits);   => affiche 'amande, fraise, cerise'

•  pop (tableau)          Retourne le dernier élément du tableau (et l'enlève)              print pop(@fruits); => affiche 'cerise', @fruits devient ('amande','fraise')

•  push (tableau, element) Ajoute un élément en fin de tableau (contraire de pop)  push(@fruits, 'abricot');=> @fruits devient ('amande','fraise','abricot')

•  shift(tableau)          Retourne le premier élément du tableau (et l'enlève)             print shift(@fruits) => Affiche 'amande', @fruits devient ('fraise','abricot')

•  unshift (tableau, element) Ajoute un élément en début de tableau            unshift ('coing', @fruits); => @fruits devient ('coing', 'fraise','abricot')

•  sort (tableau)          Tri le tableau par ordre croissant

            @fruits = sort (@fruits);    => @fruits devient ('abricot', 'coing', 'fraise')

•  reverse (tableau)     Inverse le tableau

            @fruits = reverse(@fruits);=> @fruits devient ('fraise', 'coing', 'abricot')

•  splice (tableau, début, nb) Enlève nb éléments du tableau à partir de l'indice début

            @derniers = splice(@fruits, 1,2);

 => @derniers devient  ('coing', 'abricot')@fruits devient ('fraise') On peut éventuellement remplacer les éléments supprimés :

@fruits=('fraise','pomme');

splice(@fruits, 1,1, ('elstar','golden'));

                =>  @fruits contient  ('fraise', 'elstar','golden')

Exemple : Tirage des 7 chiffres du loto

@c = (1..42); $i=0;

print splice(@c, int(rand($#c+1)),1),"\n" while ($i++ < 7);

On enlève 7 fois un élément (pris au hasard) du tableau des 42 chiffres.

Pour information, l’exemple précédent aurait pu s’écrire :

 @c = (1..42); $i=0;

while ($i < 7) {

$nb = int(rand($#c + 1));

print "$nb\n"; splice (@c, $nb, 1);

$i++; }

                E.        tableaux indicés

Appelés aussi tableaux associatifs

•  each(tabi) Les couples clé/valeurs d'un tableau indicé while (($fruit, $valeur) = each(%prix)) { print "kilo de $fruit : $valeur F";

}

L’utilisation habituelle est d’afficher le contenu d’un tableau Attention : Les clés d'un tableau associatif ne sont pas triées ! ex:

%t=('bernard'=>45, 'albert'=>32, 'raymond'=>2);

while (($n, $s) = each(%t)) {print "$n,$s\n";}

affichera : raymond,2 albert,32 bernard,45

•  values(tabi) Toutes les valeurs d'un tableau indicé (sous la forme d'un tableau) print 'les prix:', join(', ', values(%prix));

•  keys(tabi) Toutes les "clés" d'un tableau indicé

print 'les fruits:', join(', ', keys(%prix));

•  exists(élément) Indique si un élément a été défini if (exists $prix{'kiwi'}) { print $prix{'kiwi'};

} else { print 'Je ne connais pas le prix du kiwi !'; }

•  delete(élément)       Supprimer un élément

delete $prix{'cerise'};

Remarque:

Il n'existe pas de fonction permettant d'ajouter un élément dans un tableau indicé (comme le push des tableaux normaux) car il suffit d'écrire : $tab{nouvel-élément} = nouvelle-valeur;

VII. Gestion de fichiers

                A.        Ouverture

L'ouverture consiste (le plus souvent) à associer un descripteur de fichier (filehandle) à un fichier physique (le fichier physique étant décrit par son chemin d'accès).

1.      en lecture

open (FENT, 'fichier'); ouverture d'un fichier, référencé ensuite par  FENT.

open(FENT, ''); open(FENT, ''); (sur Unix) open(FENT, 'd:\tmp\'); (sous DOS)

open (COM, 'commande|');ouverture d'une commande dont le résultat sera dans COM

open (FDESS, 'ls /users/dess |'); (sur Unix) open (Dirtemp, 'dir c:\Temp |'); (sous DOS)

Un fichier spécial : STDIN, le clavier (entrée standard).

2.      en écriture

open (FSOR, '> fichier');    Ecriture du fichier, si ce fichier existait auparavant : l'ancien contenu est écrasé.

open(FSOR, '> ');

open (FSOR,'>>fichier'); Ecriture à la fin du fichier, Le fichier est créé si besoin open (FSOR, '>> ');

                open (FSOR, '| commande');    Le fichier de sortie sera en fait l'entrée

standard de la commande open (Imprime, '| lpr'); => La sortie sera imprimée open (FMAIL, '| mail -s "Bonjour" lim\');

Deux fichiers spéciaux : STDOUT, STDERR (respectivement: sortie standard, et sortie erreur), par défaut l'écran.

                               3.         Gestion des erreurs (||)

Lorsque l’on ouvre un fichier il se peut qu’il y ait une erreur.

En lecture : le fichier n’existe pas, ou ne peut pas être lu (droits d'accès)

En écriture : Le fichier existe mais on n’a pas le droit d’écrire dessus, pour une commande Unix : la commande est inconnue

Il faut prendre l’habitude, quand on ouvre un fichier, de détecter l’erreur éventuelle. On peut le faire sous la forme suivante : (dérivée du C)

if (! open (F, )) { die "Problème à l'ouverture du fichier";

}

Ou sous la forme plus simple et plus usitée en Perl :

open (F, ) || die "Pb d'ouverture";

On peut, et c'est même conseillé, récupérer le texte de l'erreur contenu dans la variable $!

open (F, ) || die "Pb d'ouverture : $!";

                B.        Fermeture

Commande close close FENT; close FSOR;

                C.        Lecture

$ligne = <FENT>;

ex: $reponse = <STDIN>;   => lecture d'une ligne à l'écran

Remarque :

-   La fin de ligne (retour-chariot) est lue également. Pour enlever cette fin de ligne il suffit d'utiliserla commande chop, ou son équivalent : chomp (enlève le dernier caractère uniquement si c'est un retour-chariot)

-   On peut lire toutes les lignes d'un fichier dans un tableau (en une seule instruction)

@lignes = <FENT>;

                D.        Ecriture

print Fsor ce-que-je-veux;

print FSOR 'DUPONT Jean';

print FMAIL 'Comment fait-on pour se connecter SVP ?';

print STDOUT "Bonjour\n";

print STDERR 'Je déteste les oranges !';

                E.        Parcours

Se fait d'une manière relativement intuitive :

open (F, $fichier) || die "Problème pour ouvrir $fichier: $!";

while ($ligne = <F>) { print $ligne;

} close F;

                F.        Fichier spécial : <>

Perl offre une fonctionnalité bien pratique : l'utilisation d'un fichier spécial en lecture qui contiendra ce qui est lu en entrée standard.

Exemple : le petit programme du début peut s'écrire

#!/bin/perl

$i=0;

while (<>) {

$i++;

}

print "Nombre de lignes : $i";

Remarque: Lorsque, dans une boucle « while », on ne spécifie pas dans quelle variable on lit le fichier : la ligne lue se trouvera dans la variale spéciale « $_ ».

Ainsi ce programme demandera d'écrire quelques lignes et affichera le nombre de lignes qu'il a lues. Mais il permet également de prendre un ou plusieurs fichiers en paramètre. (voir chapitre Passages de paramètres au programme page 25)

VIII. Expressions régulières

Comme la commande "egrep" d'Unix, Perl offre la même puissance de manipulation d'expressions régulières.

On utilise l'opérateur conditionnel =~ qui signifie "ressemble à".

Syntaxe: chaîne =~/expression/

Exemple: if ($nom =~ /^[Dd]upon/) {print "OK !";}

=> Ok si nom est 'dupont', 'dupond', 'Dupont-Lassoeur'

^ signifie « commence par »

On peut rajouter « i » derrière l'expression pour signifier qu'on ne différencie pas les majuscules des minuscules.

Le contraire de l'opérateur =~ est !~ (ne ressemble pas à )

if ($nom !~ /^dupon/i) {print "Non ";}

                A.        Rappel

Une expression régulière (appelée « regexp ») est un motif de recherche, constitué de :

•    Un caractère

•    Un ensemble de caractères :

•    [a-z]       tout caractère alphabétique

•    [aeiouy] toute voyelle

•    . tout caractère sauf fin de ligne

•    [a-zA-Z0-9]       tout caractère alphanumérique

•    le caractère ^ au début d'un ensemble signifie « tout sauf »

 ([^0-9] : tout caractère non numérique)

•    Un caractère spécial: \n, « retour-chariot  », \t : tabulation, ^ : début de ligne, $ : fin de ligne

•    \w signifie « un mot », \s signifie « un espace », \W « tout sauf un mot », \S « tout sauf un espace »

•    Quelques opérateurs : « ? » 0 ou 1 fois, « * » : 0 ou n fois, « + » : 1 ou n fois, « | » : ou

(inclusif)

Il y a même l'opérateur {n,m} qui signifie de n à m fois.

Remarque : Si l'on veut qu'un carcatère spécial apparaisse tel quel, il faut le précéder d'un « antislash » (\), les caractères spéciaux sont :

 « ^ | ( ) [ ] { } \ / $ + * ? . »

ex: if (/\(.*\)/) {print;} qui affiche contenant des parenthèses

Attention :

le caractère spécial « ^ » a deux significations différentes : 1) dans un ensemble il signifie « tout sauf »

2) en dehors il signifie « commence par »

1.      Exemples d’utilisation :

Le traitement d'une réponse de type (Oui/Non) : en fait on teste que la réponse commence par "O"

print ’Etes-vous d\’accord ? ’; $reponse = <STDIN>;

if ($reponse =~ /^O/i) {# commence par O (minus. ou majus.)

print "Alors on continue";

}

Remarque: Le petit piège dans ce programme serait de mettre $reponse =~ /O/ (sans le « ^ ») qui serait reconnu dans ‘NON’ (qui contient un « O ») Recherche des numéros de téléphone dans un fichier :

while ($ligne = <>) {    # Tant qu’on lit une ligne

if ($ligne =~ /([0-9][0-9]\.)+[0-9][0-9]/) {

# si la ligne est de forme 99.45

print $ligne; # Alors on l’affiche

}

}

Remarque:

Par défaut l’expression régulière est appliquée à la variable $_.

Donc écrire if ($_ =~ /exp/) est équivalent à écrire : if (/exp/)

2.      Utilisation avancée :

Le contenu des parenthèses d'une expression régulière est retourné sous la forme d'un tableau.

Exemple: Lister tous les hyperliens d’un document HTML : un hyperlien est noté sous la forme <a href="quelquechose"> (avec quelquechose ne pouvant pas contenir le caractère ". Donc quelquechose sera reconnu par [^\"]+ qui signifie tout caractère autre que ".

while ($ligne = <>) {

if ( ($h) = ($ligne =~ /<a href=\"([^\"]+)\">/)) { print "Hyperlien: $h\n";

} # ce programme ne detecte qu'un hyperlien par ligne

}

 

On peut utiliser cette fonctionnalité pour faire des affectations :

exemple :

On a un fichier annuaire de la forme :

M. Dupont      tel: 99.27.82.67

M. Durant  tel: 99.34.54.56

Mme Larivoisière 99.23.43.21

Et on souhaiterait avoir un programme automatique qui soit capable de retrouver un numéro de téléphone d’après un nom (saisi à l’écran).

print " entrez un nom : ";

$nom = <STDIN>;

chomp($nom); # Enlève le « retour-chariot » en fin de chaîne open (ANNUAIRE, '') ||die "Problème ouverture ";

while ($l = <ANNUAIRE>) {

   if ( ($tel) = ($l =~ /$nom.*(([0-9][0-9]\.)+[0-9][0-9])/)) { print "Le numéro de téléphone de $nom est : $tel\n";

   } }

close ANNUAIRE;

                B.        Remplacement

Comme le fait la commande « sed » en Unix, Perl permet de faire des remplacements sur une chaîne de caractère, en utilisant la syntaxe :

$chaîne =~ s/motif/remplacement/; où motif est une expression régulière et remplacement ce qui remplace. Exemples:

$fruit =~ s/e$/es/;          remplace un « e » final par « es »

$tel =~ s/^02\./00\.33\.2\./; remplace les numéros de téléphone (ouest de la

France) par leur équivalent international

On peux référencer une partie du motif dans le remplacement avec $1 ($1 est une variable spéciale : le contenu de la première parenthèse).

exemple :

$tel =~ s/^0([0-4])\./00\.33\.$1\./;        remplace TOUS les numéros de

téléphone par leur équivalent international

Transformer automatiquement les noms d’arbre par « arbre à fruit »

$texte =~ s/([a-z]+)ier /arbre à $1es /;

‘cerisier’ sera traduit par ‘arbre à cerises’       (contenu de $1 => ‘ceris’) ‘manguier’ => ‘arbre à mangues’

Les options :

s/exp/remp/i; => Indifférenciation minuscules/majuscules s/exp/remp/g; => Remplace toute occurrence (pas seulement la première) Pour remplacer un texte par le même en majuscule (\U):

s/([a-z])/\U$1/g;

Exemple : mettre toutes les balises d’un fichier HTML en majuscule (en fait on met le premier mot de la balise en majuscule). Ne pas oublier les fins de balises (commençant par « / »)

while ($ligne = <>) {

$ligne =~ s/\<(\/?[a-z]+)/\<\U$1/g;

# \U$1 signifie $1 en majuscules

print $ligne; }

Si on appelle ce programme avec le fichier HTML suivant :

<html><body bgcolor="ffffff">

<a

href=";>bonjour</a> </body></html>

Il affichera :

<HTML><BODY bgcolor="ffffff">

<A

href=";>bonjour</A>

</BODY></HTML>

IX.    Variables et tableaux spéciaux

Petit récapitulatif des variables spéciales, ce sont les variables sous la forme $c (avec c un caractère non alphabétique):

$_            La dernière ligne lue (au sein d’une boucle « while »)

$!             La dernière erreur, utilisée dans les détections d’erreurs

open(F,’fichier’) || die "erreur $!"

$$            Le numéro système du programme en cours: parfois utile car il change à chaque fois

$1, $2, Le contenu de la parenthèse numéro n dans la dernière expression régulière

$0             Le nom du programme (à utiliser, cela vous évitera de modifier le programme s’il change de nom)

Tableaux spéciaux

@_                  qui contient les paramètres passés à une procédure.

@ARGV         qui contient les paramètres passés au programme

%ENV            tableau indicé contenant toutes les variables d'environnement

@INC             tous les répertoires Perl contenant les « librairies » (rarement utilisé)

X.      Structures complexes

En Perl (version 5), on utilise la syntaxe des tableaux indicés pour désigner une structure complexe, exemple:

$patient->{nom} = 'Dupont';

$patient->{prenom} = 'Albert';

$patient->{age} = 24;

On peut initialiser la structure comme lorsqu'on initialise un tableau indicé :

$patient = {

nom => 'Dupont', On utilise les accolades plutôt que les prenom => 'Albert', parenthèses (référence vers un tableau indicé) age => 24};

Pour afficher le contenu d'une structure complexe :

print "Nom:$patient->{nom} $patient->{prenom},

âge:$patient->{age}";

ou:

foreach $champ ('nom','prenom','age') {

print "$champ : $patient->{$champ}\n"; }

qui affiche:

nom : Dupont prenom : Albert

      age : 24                                                                        Pour référencer $patient comme un

ou encore : tableau indicé on utilise cette syntaxe foreach $champ (keys %$patient) { print "$champ : $patient->{$champ} ";

}

qui affiche: prenom : Albert

nom : Dupont         Les champs apparaissent dans le "désordre" age : 24 comme dans l'affichage d'un tableau indicé

XI.     Exemples

                A.        Passages de paramètres au programme

En Unix (ou Windows) on peut appeler un programme Perl en lui donnant des paramètres, comme on le fait pour les commandes Unix

Les paramètres sont stockés dans un tableau spécial : @ARGV

Le premier paramètre est donc $ARGV[0] exemple:

#!/bin/perl

$email = $ARGV[0];

open (MAIL, "| mail -s 'Bonjour' $email") # commande unix mail

|| die "Problème : $!";

print MAIL "Bonjour très cher\n";

print MAIL "Nous sommes très heureux de vous envoyer un mail\n"

print MAIL " A bientôt\n"

close MAIL;

L'appel (sous Unix) se fera :

Si on veut traiter plusieurs paramètres il suffit de consulter le tableau @ARGV : ex:

#!/bin/perl

foreach $email (@ARGV) { open (MAIL, "| mail -s '25 decembre' $email")

|| die "Problème : $!"; print MAIL "Joyeux noël\n";

close MAIL;

}

Programme de recherche d’un motif dans plusieurs fichiers, avec affichage du nom du fichier ex:

#!/bin/perl

# recherche un motif dans un ou plusieurs fichiers.

# Le motif est demandé à l'utilisateur print "Entrez votre motif de recherche\n";

$motif = <STDIN>; chomp($motif); # Enlever le retour-chariot foreach $f (@ARGV) { open(F, $f) || die "Impossible de lire le fichier $f : $!";

while ($ligne = <F>) {    if ($ligne =~ /$motif/) { print "On l'a trouvé dans le fichier $f : $ligne";

}

} close F;

}

Remarque : On pourra utiliser ce dernier exemple sur Macintosh, on fera alors glisser les fichiers sur le programme Perl (c'est la seule manière de passer des paramètres sur Macintosh)

                B.        Parcours de fichier

Une des fonctionnalités de Perl est la manipulation de fichiers. Le parcours le plus simple, on l'a vu, est le suivant :

#!/bin/perl

while ($ligne = <>) {

print $ligne;

}

Qui se contente de lire le contenu du (ou des) fichier(s) passé(s) en paramètre pour l’afficher à l'écran.

On peut avoir envie d'écrire le résultat d'une modification dans un fichier, par exemple, enlever tous les tags HTML et les écrire dans un fichier "" (ouvert donc en écriture).

#!/bin/perl

open (ST, '> ') || die "Impossible d'écrire : $!";

while ($ligne = <>) {

$ligne =~ s/<[^>]+>//g;# On remplace < > par rien du tout

print ST $ligne;    # Le résultat est écrit dans le fichier }

close ST;

Par contre le traitement serait relativement complexe pour prendre tous les fichiers un par un, et, à chaque fois, de lui enlever les "tags", Perl a une option (-i) qui permet de renommer le fichier d'origine et le résultat de la transformation sera écrite dans le fichier lui-même.

Cela parait compliqué mais c'est bien utile pour faire des transformations automatique sur plusieurs fichiers en même temps.

Cette option (-iextension) se met dans la première ligne :

#!/bin/perl -i.avectag

while ($ligne = <>) {

$ligne =~ s/<[^>]+>//g;

print $ligne; # Affichage dans un fichier, pas à l’écran

}

Ainsi on peut lui donner en paramètre tous les fichiers HTML d'un répertoire, ils seront tous renommés sous la forme .avectag, et le fichier HTML de départ sera le résultat du programme.

Remarque :

Sous Unix, pour tester une petite commande Perl, on peut appeler Perl sans créer de programme avec la syntaxe :

noemed% perl -e 'commande'

Ou même on peut l’utiliser pour appliquer une commande à chaque ligne :

ls /users/dess | perl –n -e 'print if (! /protdess/);'

=> affiche tous les utilisateurs du DESS sauf protdess

=> Quand on utilise les option « n » et « e », chaque ligne lue se trouve dans la variable spéciale

$_

l'option -e permet de prendre une commande Perl en paramètre l'option -n permet d'appliquer la commande à chaque ligne lue

l’option –iext permet de renommer un fichier avec l’extension ext avant d’appliquer des traitements

Exemple : Supprimer en une seule commande tous les tags HTML de plusieurs fichiers :

perl -n -i.sanstag -e 's/<[^>]+>//g; print;' fichier1 fichier2

Car l'option -i permet de renommer chaque fichier (avec l’extension donnée), ensuite, tout ce qui est lu est lu dans chaque fichier, tout ce qui est écrit est écrit dans chacun des fichiers.

Autre exemple : Enlever toutes les lignes des fichiers qui comporte la chaîne de caractère

« secret »

perl -n -i.sanstag -e 'print unless (/secret/);' fic1 fic2

                C.        Programmation objet

Remarque : Ce paragraphe a été écrit uniquement pour avoir un exemple de programmation objet avec Perl : il ne sera pas développé dans le cadre du DESS TIMH

Pour ceux qui connaissent la programmation objet, Perl (version 5) permet de définir des objets.

En résumé on associe à un « objet » des données et des « méthodes ». Ce qui simplifie l’utilisation ensuite de ces objets.

En Perl objet : un « objet » est une référence, une « méthode » est une procédure, une « classe » d’objet est un package. En pratique :

On crée un fichier Perl (avec le suffixe .pm) qui contient la classe d’objet que l’on veut définir Deux méthodes particulières : new, constructeur, appelée automatiquement à la création de l’objet et DESTROY, destructeur, appelée automatiquement à la destruction de l’objet Notes:

? On déclare les variables avec my plutôt que local en Perl 5

? La fonction bless permet de rendre un objet « visible » de l’extérieur. ex:

#!/bin/perl

package maclasse; # Le nom que l’on donnera à l’objet

sub new { # constructeur, Méthode appelée à la création   my ($classe, ) = @_;# La classe est toujours le 1er

paramètre

     return bless référence;

  # on ne retourne pas une variable, mais sa référence,cf doc

Perl }

sub DESTROY { # destructeur, appelée à la destruction my ($classe) = @_;

}

sub methode1 { # On définit ainsi toutes les méthodes my ($classe, ) = @_;

}

La classe de l’objet étant définie, on peut l’utiliser maintenant dans un programme Perl de la manière suivante :

use maclasse;

$mon_objet = new maclasse(paramètres); # Appel du constructeur $mon_objet->methode1(paramètres); # Appel d’une méthode exit;     # fin du programme, appel du destructeur de l’objet

Comme exemple de programmation Objet nous allons prendre un objet « patient » qui sera défini par son nom et l’unité médicale dans laquelle il se trouve.

Deux méthodes seront attribuées au patient :

transfert => Transfert vers une nouvelle unité médicale

affiche => Affiche le nom du patient ainsi que l’unité médicale dans laquelle il se trouve

#!/bin/perl

package patient;                # Déclaration d'un package

 

# Un nouveau patient consiste à lui donner un nom

# et éventuellement une unité

sub new {      # Constructeur

  my ($class, $nom, $unite) = @_;

  my $patient = {}; # Structure complexe

 

$patient->{nom} = $nom;

  if ($unite) { # Si unité définie

          $patient->{unite} = $unite;

  } else {

          $patient->{unite} = 'Non définie';

  }

  return bless $patient;

}

sub transfert { # Transfert du patient vers nouvelle unité   my ($patient, $nvunite) = @_;

$patient->{unite} = $nvunite;

}

sub affiche { # Affichage de la situation du patient   my ($patient) = @_;

  print "Le patient $patient->{nom} est dans l'unité

$patient->{unite}\n";

}

sub DESTROY { my ($patient) = @_;

  print "Le patient $patient->{nom} est parti !\n";

}

1; # Une classe d'objet se termine toujours par 1;

On peut maintenant utiliser cette classe d’objet dans un programme Perl :

#!/bin/perl

use sih; # Directive pour dire qu'on utilise le package SIH

 

# Déclaration de deux nouveaux patients

$patient1 = new patient('Dupont Pierre');

$patient2 = new patient('Durand Albert', 'urgences');

$patient1->affiche;      # Appel d'une méthode pour patient

$patient2->affiche;      # (affichage de sa situation)

 

$patient1->transfert('cardio');   # transfert vers nelle unite

$patient2->transfert('pneumo');

 

$patient1->affiche; # Affichage de la situation des 2 patients

$patient2->affiche;

# fin du programme, appel des destructeurs

Le résultat de ce programme sera :

Le patient Dupont Pierre est dans l'unité Non définie

Le patient Durand Albert est dans l'unité urgences

Le patient Dupont Pierre est dans l'unité cardio Le patient Durand Albert est dans l'unité pneumo Le patient Durand Albert est parti ! Le patient Dupont Pierre est parti !

                D.        Perl et CGI

Rappel: Les CGI (common gateway interface), sont les programmes exécutés sur un serveur Web et qui produisent (affichent) de l’HTML (dans la plupart des cas, mais un CGI peut produire une image, un texte…).

Remarque: Un CGI est un programme (ici écrit en Perl) qui doit afficher un « header » (ici « Content-type: text/html » suivit d’une ligne vide), et qui ensuite affiche du HTML.

Une alternative aux CGI : Les ASP du serveur Apache, C’est une nouvelle technologie (encore en cours de développement) qui permet d’ « embarquer » des instructions Perl dans un code HTML

Exemple : Affiche 10 fois « Salut »

<html><head><title>Bonjour</title>

</head><body>

<% foreach $i (1..6) { %>

<h2>Salut</h2>

<%} %>

1.      Premier CGI: sans paramètres

Exemple de petit programme CGI :

Il s’agit d’un programme qui affiche les personnes du DESS (commande UNIX ls /users/DESS).

#!/bin/perl

print "Content-type: text/html\n\n"; # Header indispensable

# Corps du programme

open(LISTE, 'ls /users/DESS |')

    || die "Impossible d'executer la commande ls: $!";

print "Liste du DESS: <UL>"; while ($nom = <LISTE>) {     print "<LI>$nom";

}

print "</UL>";

Ce programme affiche un fichier HTML qui ressemble à :

 

Le serveur Web affichera donc un document HTML qui aura l’aspect suivant:

 

2.      Deuxième CGI: associé à un formulaire

Le CGI précédent est un cas particulier relativement rare En général un programme CGI est paramétrable. C’est à dire que l’utilisateur peut entrer des données qui seront analysées par le CGI. Ce qui, sous Web, sous-entend l’utilisation de formulaires.

Le cas général est donc : Un formulaire pour entrer les données, et un CGI pour les exploiter. Rien n’oblige le formulaire à être sur le même serveur que le CGI. Par contre le CGI doit être dans un répertoire spécial du serveur Web (en général /usr/local/httpd/cgi-bin/programme.pl) et sera accessible avec l’URL correspondante (en général http://serveur/cgi-bin/programme.pl).

Exemple: Un petit CGI poli,

#!/bin/perl

use CGI_Lite;                   # Utilisation d'un module CGI

$cgi=new CGI_Lite;              # Nouveau CGI

%in = $cgi->parse_form_data;    # Lecture des parametres print "Content-type: text/html\n\n"; # Header indispensable

# Corps du programme

print "<h1>Bonjour $in{'nom'} !</h1>";

Ce CGI utilise un module  spécial (CGI_Lite) qui permet de lire les données d’un formulaire et de les placer dans le tableau associatif %in. (cf. paragraphe XIV.B « Installation de modules »). Il reste ensuite à écrire un formulaire qui remplit les données dont on a besoin (pour l’exemple seul

le paramètre « nom » est utilisé).                                                      C’est ici que l’on nomme le

CGI que l’on appelle

<form action=""

METHOD=POST>                                                                 Il faut que le nom de la

<b>Quel est votre nom ?</b>                                                 variable corresponde à celui

<input type=text name=nom>                                                utilisé dans le CGI

<input type=submit value="Allons-y">                                  ($in{'nom'})

</form>                                                  Le bouton « submit »

est indispensable

Ce formulaire HTML sous un navigateur Web :

 

qui appellera le CGI avec le paramètre « nom » ayant pour valeur « Pr. Tournesol » Le CGI répondra alors:

 

Remarque: Les diverses fonctionnalités du module CGI_Lite sont accessible via la documentation en ligne à l’adresse :


                               3.         Un exemple un peu plus complexe

Utilisation de différents « tags » pour saisir des informations.

Un problème se pose avec les tags de type « sélection multiple » : nous avons plusieurs valeurs dans une même variable Pour résoudre ce problème le module CGI_Lite offre une fonction $cgi->get_multiple_values ($in{'champ'}) qui permet de retourner sous forme de tableau les différentes valeur du champ.

On va créer un CGI qui « crée » une salade de fruits avec les paramètres de l’utilisateur. Voici le formulaire « » sous Netscape :

 

Le programme CGI répondra :

 

Source du formulaire:

<form action=""

METHOD=POST>

<b>Quel est votre nom ?</b>

<input type=text name=nom>

<br>

<b>Que voulez vous dans votre salade de fruit ?<br>

<input type=checkbox name=fruit value="amande">Amande<br>

<input type=checkbox name=fruit value="banane">Banane<br>

<input type=checkbox name=fruit value="cerise">Cerise<br> <input type=checkbox name=fruit value="kiwi">  Kiwi  <br> Et pour sucrer :

<select name=sucre>

<option checked>sucre vannill&eacute;

<option>sucre de canne

<option>sirop

<option>rien du tout

</select><br>

Une remarque ? <br>

<textarea name=remarques cols=40 rows=4></textarea>

<br>

<input type=submit value="Allons-y"> </form>

Le source de est un petit peu plus complexe :

#!/bin/perl

use CGI_Lite;               # Module CGI_Lite

$cgi=new CGI_Lite;          # On cree un objet de type CGI

%in = $cgi->parse_form_data;# On lit les donnees

print "Content-type: text/html\n\n"; # Indispensable: Header # Les champs du formulaire sont maintenant dans le tableau

# associatif %in

# On fait donc reference a un champ par $in{'champ'}.

# ATTENTION: Certains champs ont plusieurs valeurs

# (SELECT multiple, boites-a-cocher )

# dans ce cas on fait reference aux valeurs dans un tableau

# obtenu par $cgi->get_multiple_values ($in{'champ'})

print "Bonjour $in{'nom'} !<p>\n";

print "Voici donc une petite salade de fruits :\n";

print "<br>Compos&eacute;e de <ul>\n";

# Pour toute valeur

foreach $f ($cgi->get_multiple_values ($in{'fruit'})) {

print "<li>$f\n";

}

print "</ul>\n";

print "Et pour la douceur un petit peu de $in{'sucre'}<br>\n"; if (exists($in{'remarques'})) { # Si le champ a ete rempli      print "Nous avons tenu compte de votre remarque<br>\n";

    print "<b>$in{'remarques'}</b>\n"; }

                E.        Accès aux bases de données : DBI

Un des aspects les plus intéressants de Perl. Il permet d'intégrer des requêtes SQL dans un programme.

Depuis Perl version 5, on accède de la même manière à une base de données quelque soit le système choisi. Auparavant l'accès était différent si on utilisait Oraperl (Oracle), ou Syperl (Sybase) Maintenant on utilise un module DBI (database interface), ce qui permet de spécifier, à la connexion, que l'on travaille sur une base Oracle, MySQL, Ingres, ou Sybase

Quand on installe Perl, il faut installer un « module » DBI, et un « module »

DBD::Oracle (ou DBD::postgres, ou DBD::mysql …). Pour l’installation de modules cf XIV.B Installation de modules p. 43).

Au LIM nous utilisons indifféremment MySQL et Oracle (sur Unix uniquement) Voici quelques commandes à utiliser pour accéder aux bases de données.

•  use DBI; En début de programme spécifie que l'on va faire de l'accès aux bases de données

•  $dbh = DBI->connect("dbi:Oracle:cours", 'nom','mot-de-passe');

=> Connexion à Oracle, sur la base de données qui s'appelle « cours », avec l’utilisateur nom et son mot de passe.

Ou $dbh = DBI->connect("dbi:mysql:test", 'nom', 'mot-depasse'); => Connexion à MySQL, sur la base de données qui s'appelle « test»

•  $dbh->disconnect;   => Pour se déconnecter de la base de données en fin de programme

•  $dbh->do("requête"); => Pour exécuter une requête SQL.

A n'utiliser qu'avec des requêtes du genre create table, update nom-table, insert into nom-table

Il est préférable de traiter une erreur éventuelle dans ce genre d'opération (requête SQL mal formulée, connexion interdite, ). On le fait de la même manière que pour la détection des erreurs dans l'ouverture de fichier :

$dbh->do("requête") || die "Pb de requête : $DBI::errstr";

(l'erreur vient du système de base de données, c'est pourquoi on utilise la variable $DBI::errstr)

•  Pour une requête de type select, on va procéder en quatre temps :

1) préparation de la requête (prepare),

2.    exécution (execute),

3.    parcours de chaque ligne retournée par la requête (fetchrow_array), dans une boucle,

4.    fin de la requête (finish)

Exemple: Lister toutes les lignes d'une table

$sel = $dbh->prepare("select * from table where condition");

$sel->execute || die "Pb de sélection : $DBI::errstr"; while (($champ1, $champ2, ) = $sel->fetchrow_array) {

print "Contenu: $champ1, $champ2, \n";

}

$sel->finish; # On ferme la requête select

Remarque:

La lecture d'une ligne se fait donc avec $sel->fetchrow_array, qui retourne en fait un tableau (d'où son nom). On pourrait donc écrire @tab = $sel->fetchrow_array;

Il est possible de paramétrer une requête, en mettant des points d'interrogation dans la requête au niveau du prepare, les paramètres seront spécifiés dans le execute. Exemple: Afficher le nom d'un patient dont le numéro est demandé à l'utilisateur

$sel = $dbh->prepare("select nom from patient where no = ?");

print "Veuillez entrer un numéro de patient";

$nopatient = <STDIN>; # lecture au clavier (ie entrée standard)

chomp($nopatient); # ne pas oublier d’enlever le retour-chariot

$sel->execute($nopatient)

|| die "Pb de sélection : $DBI::errstr";

($nom) = $sel->fetchrow_array;

print "Nom du patient $nopatient : $nom \n"; $sel->finish;

Voici maintenant un exemple de programme Perl qui crée une table "patient" avec trois champs (numéro, nom, prénom), et qui demande de saisir une liste de noms - prénoms, et qui, pour chaque ligne, insère les données dans la table (le programme se charge d'incrémenter à chaque fois le numéro de patient) :

#!/bin/perl

use DBI;                 # On va utiliser la base de données

# Connexion à Oracle sous l'utilisateur scott

$dbh = DBI->connect("dbi:Oracle:cours", 'scott/tiger');

# Création de la table patient :

$dbh->do("create table mpatient ( numero integer not null primary key,

nom varchar(40),

prenom varchar(20))") || die "Pb création table: $DBI::errstr";

# Préparation d'une requête d'insertion des valeurs dans la BDD

$ins = $dbh->prepare("insert into mpatient values (?, ?, ?)"); $nopatient=0;                   # Initialisation du compteur print "Entrez une série de nom-prenom, finir par CONTROL-D\n";

while ($ligne = <>) {           # Pour chaque ligne lue

# Séparation en nom,prenom

# caractère de séparation: tabulation

($nom, $prenom) = split(/\t/, $ligne);

# Exécution de la requete (insert), détection de l'erreur

$ins->execute($nopatient, $nom, $prenom)

|| die "Pb à l'insertion : $DBI::errstr";

$nopatient++;              # Incrémentation du compteur

}

$ins->finish; # On ferme la requête insert

$dbh->disconnect; # Déconnexion de la BDD

En fait, on lit les données de l'entrée standard (<>), ce même programme pourrait fonctionner aussi bien avec un fichier venu d'un tableur (Excel ou autre).

Voici un programme qui affiche le contenu de la table mpatient (que l'on vient de créer).

#!/bin/perl

use DBI;                  # On va utiliser la base de données

$dbh = DBI->connect("dbi:Oracle:cours", 'scott','tiger');

# Préparation d'une requête de sélection des valeurs

$sel = $dbh->prepare("select * from mpatient");

$sel->execute || die "Pb à la sélection : $DBI::errstr";

print "Voici la liste des patients enregistrés";

while (($nopatient, $nom, $prenom) = $sel->fetchrow_array) {

# Pour chaque ligne lue

print "Patient no $nopatient : $nom, $prenom\n";

}

$sel->finish; # On ferme la requête insert

$dbh->disconnect; # Déconnexion de la BDD

Il existe d’autres méthodes pour accéder aux bases de données. Voir la documentation Perl à ce propos, une copie HTML se trouve à l'URL suivante :

                F.        Accès à une base de données depuis Web

Pour accéder à une base de données depuis Web, cela sous-entend que l’on va utiliser des programmes CGI qui accèdent à une base de données (CGI et DBperl)

Voici un petit exemple simple qui liste tous les patients de notre base de données sous la forme d’un tableau (on demandera au préalable de saisir un motif de recherche des patients). Formulaire:

<form action="" METHOD=POST>

<b>Votre recherche ? </b>

<input type=text name=recherche>

<input type=submit value="Allons-y"> </form>

Sous Netscape :

 

La réponse sera :

 

le programme

#!/bin/perl

use DBI;                    # On va utiliser la base de donnees

use CGI_Lite;               # Module CGI_Lite

$cgi=new CGI_Lite;          # On cree un objet de type CGI

%in = $cgi->parse_form_data;# On lit les donnees

 

print "Content-type: text/html\n\n"; # Indispensable: Header

 

$dbh = DBI->connect("dbi:Oracle:cours", 'scott','tiger');

# Preparation d'une requete de selection des valeurs

$sel = $dbh->prepare("select * from mpatient where nom like ?");

$recherche = "%$in{'recherche'}%";

$sel->execute($recherche)

|| die "Pb à la sélection : $DBI::errstr";

 

print "Patients dont le nom contient $in{'recherche'}";

print "<table border><th>Num&eacute;ro<th>nom<th>

pr&eacute;nom<tr>";

$nblignes=0;

while (($nopatient, $nom, $prenom) = $sel->fetchrow_array) {

# Pour chaque ligne lue print "<tr><td>$nopatient<td>$nom<td>$prenom\n";

$nblignes++;

}

print "</table>Nombre de patients : $nblignes";

$sel->finish; # On ferme la requête insert

$dbh->disconnect; # Déconnexion de la BDD

XII. Bibliographie

La bibliographie présente les références des livres en anglais. Il est précisé quand une traduction en

Français existe. Accessoirement une URL permet d’avoir des informations sur le livre

Tous les livres n’ont pas étés lus ! (les trois derniers). Un éditeur revient souvent : O’Reilly qui possède une site contenant tous ses livres sur PERL : S’il ne faut retenir qu’une URL pour PERL ce serait celle-ci :

elle contient le programme Perl lui-même (téléchargeable gratuitement bien sûr) ainsi qu’une mine d’information sur les différents modules, sur les adresses à consulter…

LIVRE

Titre, auteurs, prix, éditeur, (éventuellement

URL)

Commentaires

 

Programmation Perl

Larry Wall, Tom Christiansen &Randal L.

Schwartz, Décembre 1996

710 pages, 280F ed. O'Reilly & Associates

 ISBN: 2-84177-004-4

Le livre de référence sur Perl. Cette nouvelle version intègre perl5. Larry Wall (créateur du langage Perl) en est le co-auteur

 

Introduction à Perl, 2è édition

Randal L. Schwartz & Tom Christiansen.

2nde édition février 1998, 335 pages, 220F, ed. O'Reilly & Associates

 ISBN: 2-84177-41-9

Préface de  Larry Wall.

Un livre plus pédagogique que « programmation Perl », mais moins fournit.

 

Mastering Regular Expressions, Powerful

Techniques for Perl and Other Tools

Jeffrey E. F. Friedl

première édition Janvier 1997, 368 pages, $29.95 ed. O'Reilly & Associates

ISBN: 1-56592-257-3

Tout ce que vous avez toujours voulu savoir sur les expressions régulières.

 

Serveurs CPAN (Comprehensive Perl Archive Network).

Documentation Perl en français :

Groupe de news :

Il s’agit de serveurs officiels des programmes Perl, des documentations, des modules

 

Apprendre Perl 5 en 21 jours

David Till

Ed. SAMS,01-Mai-96,($28 - $39.99)

ISBN: 0672308940

ATTENTION: Une version française existe

Gros livre qui permet d’apprendre pas-à-pas toutes les fonctionnalités de Perl. Il faut avoir 21 jours devant vous !

 

LIVRE

Titre, auteurs, prix, éditeur, (éventuellement

URL)

Commentaires

 

Programmer des CGI sur World Wide Web

Shishir Gundavaram ,

1ère édition, novembre 1996, 450 pages, 220 francs, ed. O'Reilly & Associates

 ISBN: 2-84177-011-7

Livre sur les techniques CGI avec les exemples en Perl. Les différents types de CGI sont abordés, mais pas forcément en profondeur

 

Perl resource kit (UNIX ou Windows)

Larry Wall, Clay Irving, Nate Patwardhan, Ellen

Siever, Brian Jepson

première édition Novembre 1997

1812 pages, $149.95

ISBN 1-56592-370-7  (1-56592-409-6 pour Win)

Quatre volumes et un CDROM. Utile

si vous n’êtes pas connecté à internet

(c’est en fait un

« miroir » d' un CPAN). Inclu un module d’interface perl/java

 

Introduction au langage Perl

Il s’agit de ce cours disponible sous Web à l’URL :

rl/

 

Notamment les exemples sous :

rl/exemples/

 

Autre Site interressant (contient un cours Perl, HT

ML et Unix) :

 

Programmation avancée en Perl

Sriram Srinivasan

juin 1998, 448 pages, 280 francs

ISBN : 2-84177-039-7

Pour ceux qui veulent mieux comprendre le fonctionnement de Perl lui-même. Comprend aussi une initiation à PerlTk

 

Perl en action, Tom Christiansen & Nathan

Torkington

septembre 1999, 972 pages, 350 F

ISBN : 2-84177-077-X

Recettes et solutions. Une vraie mine d’or.

 

Perl for System Administration

David N. Blank-Edelman

Ed. QUE

Juillet 2000

($35)

ISBN: 1-56592-609-9

Utile pour

l’administration sur

Windows / NT

(livre décevant pour Unix, encore plus pour Mac OS…)

XIII. INDEX

A                                          M

abs ..13                           méthode .28

and ..7                           my .12, 28

ARGV .25                     N

B                                          new ..28

bless .28                            not 7

C                                          O

CGI_Lite 32                           objet .28

chomp .14                             open .17

chop .14                             or 7

close .18                     P

cos ..13

package ..28

D                                            pop 15

DBI ..36                          print .13, 18

delete ..16                           push .15

DESTROY 28                     R

die .13

do .10                          rand ..13

return ..12

E                                          reverse .15

each .16                     S

else ..9

elsif .9                            shift ..15

exists 16                            sin ..13

exit 13                            sleep .13

exp 13                            sort 15

splice 15

F                                          split ..14

for .11                          sqrt ..13

foreach 11                            STDERR 17

STDOUT 17

G

sub 12

grep ..14                           substr ..14

system .13

I

if 9                       T

index 14                            tan ..13

int ..13                            tkperl ..2

J                                                                                                              U

join 15                            uc .14

ucfirst ..14

K

unshift .15

keys ..16                            until .10

L                                                                                                                    use .28

lc .14                      V, W

lcfirst 14                           values ..16

length ..14                            while 10

local .28

log ..13

XIV. ANNEXES : Installation et utilisation de Perl

                A.        Installation du programme principal

Tout commence à l’adresse .

Pour installer Perl, vous avez le choix entre télécharger les « sources » du programme et les compiler vous-même (c’est intéressant, faisable, mais prévoyez 2-3 jours !).

Bien heureux les utilisateurs de Linux qui ont Perl d’entrée de jeux !

Sur les autres systèmes, je vous conseille de télécharger une distribution « binaire » que l’on trouvera sur les serveurs CPAN (Comprehensive Perl Archive Netword) dont la page de garde est : .

Heureusement pour nous (malheureusement pour France Telecom)  ils existe de nombreux sites miroirs, notamment en France :

Exemple :

Suivez le lien « binary distributions ("ports") », et choisissez votre système d’exploitation.

1.        Sur Unix

Tout dépend de l’Unix, en général vous téléchargerez un fichier compacté (utilisez « gunzip »).

Parfois le résultat sera un « installeur » (programme faisant toute l’installation), parfois une archive

(fichier finissant par « .tar », que vous décompacterez en utilisant la commande « tar xvf »), lire les instruction d’installation dans un fichier « README ».

2.        Sur Windows ou NT

Je vous propose de le télécharger directement sur le Web une version ActiveState : 

Il suffit de cliquer sur le lien "Windows Intel", après le téléchargement, il suffit de double-cliquer sur « » et de suivre les instructions

3.        Sur Mac OS

#mac

Vous téléchargez un fichier compacté (ex : ), que vous traiterez avec l’application « stuffit expander », qui créera un fichier exécutable (ex : Mac_Perl_520r4_appl).

                B.        Installation de modules

Les « modules » sont des librairies qui ajoutent des possibilités au langage Perl. Dans ce cours nous avons vu les deux exemples de modules : « CGI_Lite » et « DBI », ces modules ne sont pas livrés avec le langage, c’est à vous de les installer.

Ces modules sont tous répertoriés dans les archives CPAN. Un utilitaire vous permet de télécharger, compiler et installer un module depuis Internet. Cela signifie qu’il faut que vous soyez connectés à Internet, et que vous connaissez les paramètres réseau (il faudra spécifier, si besoin, votre proxy…).

                               1.         Sur Unix

Utilisez la commande « perl –MCPAN –e shell » Pour installer un module, tapez :

install CGI_Lite install Date::Manip

Pour recherche un module (par exemple : les modules parlant de CGI) tapez :

i /CGI/

2.      Sur Windows

Vous trouverez dans votre distribution un programme « », il suffit de le lancer, et vous accéderez à la même interface que sous Unix.

Pour installer un module, tapez :

install CGI_Lite install Date-Manip

Pour recherche un module (par exemple : les modules parlant de CGI) tapez :

search CGI

3.      Sur Macintosh

Contrairement aux autres distributions, il n’y a pas (d’emblée) d’utilitaire permettant de charger automatiquement les modules. Néanmoins un utilitaire a été développé : « cpan-mac », à télécharger à l’adresse :

4.      Quelques modules utiles

Nom du module

Commentaires

LWP : :UserAgent

Utilitaires pour la consultation automatiques de site

Web

CGI_Lite

Tout ce qu’il faut pour « récupérer » les informations d’un formulaire Web dans un CGI

CGI

Offre plus de possibilités que le précédent module, mais moins facile d’accès

DBI

Accès aux bases de données

Date : :Manip

Tout ce qu’il faut pour manipuler des dates (y compris en Français !)

GD

Permet de créer des images GIF

Net::LDAP

Consulter des annuaires LDAP automatiquement

Net::SMTP

Envoyer des courriers électronique

Mail::POP3Client

Consultation automatisée de courrier

GIFGraph

Créer des images GIF pour faire des graphes statistiques (Camemberts ou barres)

Apache

Un ensemble de modules pour la connexion avec Apache (installation complexe)

XML : :Parse

Permet de manipuler des fichiers XML

                C.        Documentation en ligne

Sur Unix, vous disposez d’un manuel habituel :

« man perl »

Vous accéderez aussi à la documentation de chaque module en tapant :

Perldoc module

Exemple : perldoc DBD::mysql

Documentation sur Internet : ou, en français :

                D.        Perl sous Unix

Il faut bien comprendre qu’un script Perl est un texte contenant des instructions Perl. Ce texte sera ensuite exécuté par l’interpréteur Perl.

On créera donc un fichier texte à l’aide d’un éditeur de texte (comme « vi » ou « emacs »…)  De préférence, suffixer les scripts perl par l’extension « .pl » Créer le script :

emacs

Il faut obligatoirement commencer par la ligne :

#!/bin/perl    (ou le chemin d’accès à l’interpréteur Perl) Syntaxe Unix pour désigner l’interpréteur …

Les programmes Perl sont des « exécutables », il faut donc placer le mode « x » sur le programme.

                E.        Perl sous Windows

Lancer « notepad » (ou tout un autre éditeur de texte)

Et créer un fichier qui s'appellera "" (".pl" est l'extension désignant perl)

-    taper le programme perl

-    l'enregistrer (bien penser à l’enregistrer au format texte).

-    Pour l'exécuter, deux solutions :

-    dans le navigateur Windows "double-cliquer" dessus (problème : on n’a le temps de rien voir !)

-    Ouvrir une session DOS et taper : perl

-    Pour la mise au point: n'oubliez pas de le sauvegarder avant de l'exécuter

Le principal piège sous Windows : les chemins d’accès aux fichiers sont désignés par des  « \ » (séparateur de fichiers) , ce qui amène souvent à écrire :

Open (F, "C:\\repertoire\\$fichier") ;

                F.        Utilisation de MacPerl

Macperl est donc une implémentation du langage Perl pour Macintosh. Il s’agit de la version 5 de Perl.

Ensuite il faut ouvrir un nouveau « script » (programme) en choisissant « new » dans le menu

« file » :

 

Il faut ensuite taper un petit programme Perl. Essayez le programme suivant : print "Bonjour !!!";

Et choisissez « run untitled » dans le menu « script », une fenêtre apparaîtra alors avec le résultat du programme

Vous pouvez sauvegarder votre programme Perl.

La fenêtre de droite permet également de saisir des données, exemple : le programme « fraise » print "Aimez-vous les fraises ?";

On tape alors la réponse (suivie d'un « retour-chariot »), le programme répond:

   

Le crayon a disparu, position normale !

Vous remarquerez que le menu « script » disparaît le temps de l’exécution du programme.

Essayez le programme suivant : changement des « a » en « @ » while (<>) { s/a/@/g;

print;

}

Quand vous exécutez ce programme, il vous demande à chaque fois de taper une phrase, et vous répond automatiquement. Pour mettre fin à votre saisie il faut alors taper CONTROL-D (comme sous Unix).

Sauvegarder ce fichier (sous le nom « change_a » par exemple) Vous pouvez le sauvegarder sous le format « droplet », ceci vous permettra d’utiliser ensuite votre programme comme un véritable convertisseur, sur le « finder » vous pourrez prendre un document texte (par exemple le fichier ) et le faire glisser sur l’icône de votre programme. Vous verrez alors apparaître la fenêtre de MacPerl avec le contenu de votre fichier converti


31