7) PHP - ASP - Perl

Communication entre un Serveur Web et un Navigateur Client
L'adresse logique du Serveur Web est fournie par un Serveur de Nom (Domain Name Server).
Les données (la requête) sont prises en charge par les protocoles IP (Internet Protocol) au niveau OSI 3 (réseau) et TCP (Transport Control Protocol) au niveau OSI 4 (transport),  le tout encapsulé dans une trame Ethernet qui prend en charge les niveaux OSI 1 et 2 (physique et liaison) selon le schéma ci-dessous :

Communication Client - Serveur
En-tête Ethernet
(Couche 2)
Adresse MAC destination
Adresse MAC source
Protocole utilisé
MAC (Medium Access Control)
Ces adresses peuvent être modifiées par les équipements traversés.
En-tête IP
(Couche 3)
Version et IHS
Type de service
Longueur totale
Adresse logique de la source
Adresse logique de la destination
Protocole de transport
Durée de vie ...
CheckSum
IHS (Internet Header Length)
IP utilise des datagrammes de longueurs variables. C'est un protocole sans connexion. Il gère l'adressage logique, le routage, la fragmentation et le réassemblage des paquets.
En-tête TCP
(Couche 4)
Longueur de l'en-tête
Port source
Port destination
Numéro de séquence
Acquittement ...
TCP assure la connexion tant que toutes les données ne sont pas arrivées ou qu'un matériel ne demande pas la fermeture. Il contrôle l'ordre et la validité des données reçues.
Le numéro du port source est fixé par le client et n'a pas de signification. Le numéro du port destination est celui du service demandé. Ils sont croisés dans la réponse.
Données
Requête HTTP
(Couche 5)
Méthodes ...
Client ...
Requête ...
Réponse ...
URL du document et méthode (Get, Post, Head) ...
Adresse du client, URL d'appel, User-Agent ...
Authentification, codage, taille et type de la requête ...
Formats acceptés en réponse ...

Le service installé sur le Serveur (démon httpd) récupère la requête, la traite et envoie la réponse au Client. Si une extension de programmation est intallée sur le Serveur, c'est l'interpréteur du langage qui fournit au Serveur le code HTML destiné au Client.
La réponse HTTP (encapsulée dans la réponse TCP/IP) contient un codage du résultat de la requête (200 : OK, 301 : Moved Permanently, 400 : Bad Request, 404 : Not Found, 500 : Internal Server Error ... ), des informations sur le logiciel serveur, l'URL de la ressource retournée, la taille du document et des informations sur celui-ci.
Daemon (Disk And Execution Monitor) : service installé sur un système Unix pour accomplir une tâche spécifique.
URL (Uniform/Universal Ressource Locator) désigne le nom et l'emplacement absolu d'une ressource Internet ainsi que le protocole à utiliser pour y accéder : "http://" serveur [":" port] [chemin ["?" requête] ]
http est le nom du protocole utilisé,
serveur est le nom ou l'adresse IP du serveur qui contient la ressource,
port le numéro du service interrogé (80 par défaut),
chemin l'emplacement de la ressource dans l'arborescence du serveur (ou /),
requête un complément optionnel.
Le choix d'un serveur Web induit souvent un environnement (mais ce n'est pas une obligation).
La plateforme Apache, PHP, MySQL est indépendante de la machine sur laquelle elle est installée.
Apache (A PAtCHy server) est le serveur Web le plus utilisé dans le monde. C'est une solution libre (dérivée de l'application universitaire NCSA httpd 1.3), gratuite, évolutive et puissante. Sa configuration à partir de fichiers textes est assez complexe, mais permet d'obtenir une sécurité maximum. Il est souvent associé au langage PHP complété par la base de données MySQL.
A l'origine de PHP on trouve le succés du site de Rasmus Lerdorf en 1994. Le travail d'une communauté de développeurs et l'utilisation d'un nouveau moteur d'analyse (Zend), ont produit un langage crédible pour le développement sur le Web. Le "Personnal Home Page" initial est devenu "PHP Hypertext Preprocessor" (et non "People Hate Perl").
Une page PHP (extension .php) se présente sous la forme d'instructions PHP souvent insérées dans une page HTML. Lorsque la page est sollicitée, les scripts sont interprétés sur le serveur (le langage est compilé dans le serveur Apache) sans faire appel à des ressources supplémentaires comme les scripts CGI (Common Gateway Interface). La réponse (calculs, requêtes SQL adressées à un SGBD, ...) est mise au format HTML et intégrée au HTML initial. On dit que ces pages Web sont dynamiques parce qu'elles sont créées à chaque appel et éventuellement différentes selon la requête traitée.
Insertion dans une page
Pour insérer un script PHP dans une page HTML on peut utiliser les méthodes suivantes
<?php Instructions PHP ?> ou
<? Instructions PHP ?> ou bien (avec l'option "enable_short_tags")
<script language="php"> Instructions PHP </script> ou encore
<% Instructions PHP %> (avec l'option "asp_tags")
Ce qui fait tout de même beaucoup.

Un hello world
Fichier PHP (Côté Serveur) Fichier PHP (Côté Client)
<html>
<head><title>Hello World !</title></head>
<body>
<?php echo "<i>Coucou !</i>" ?>
</body>
</html>
<html>
<head><title>Hello World !</title></head>
<body>
<i>Coucou !</i>
</body>
</html>

Sans s'attarder sur la pertinence d'utiliser PHP pour afficher un "Coucou" en italique, remarquons simplement que le module PHP a traité le "echo" de la section PHP et a intégré le résultat au flot HTML.
Éléments du langage
La syntaxe est (une de plus) celle du C.
Les commentaires sont : # ou // jusqu'à la fin de la ligne, ou compris entre /* et */.
define permet de créer des constantes en plus de celles définies par le système (_FILE_, PHP_OS, ...) :
define("Passe","TocToc") ;
Les noms des variables sont précédés par $. Il n'existe pas de déclaration explicite et le type (integer, double, string, array ou object) est défini par l'affectation. Le langage est "sensible à la casse". La portée d'une variable est limitée à son environnement de définition. static conserve sa valeur entre deux appels de fonctions, global la rend accessible à tous les niveaux. Une variable peut pointer sur une fonction.
Les chaînes de caractères sont encadrées par des guillemets simples ou doubles. Les guillemets simples interceptent l'interprétation des variables $ et des séquences d'échappement \ (sauf \\ et \').
Les affectations peuvent être effectuées :
par valeur :
$An = 2003 ; $Rouge=array(255,0,0) ; // $Rouge[0] = 255 (on peut utiliser le délimiteur de zone <<<)
par référence (avec le signe &):
$a = 3 ; $b = 0 ; $a = &$b ; // $a et $b valent 0
$a = 5 ; // $a et $b valent 5
par redirection (avec $$) :
$Date = "Mois" ; $$Date = "Janvier" ; // $Mois = "Janvier"
Les fonctions settype(), gettype() ainsi que la construction "cast" (integer) 1.5 ; permettent de s'assurer du type d'une expression .
Opérateurs
arithmétiques + ; - ; * ; / ; % (modulo) ;
d'affectation = ;
combinés (association d'un opérateur arithmétique et de l'opérateur d'affectation)
++ et -- préfixés ou postfixés
de concaténation . (point);
binaires & (et) ; | (ou) ; ^ (ou exclusif) ; - (complément) ; << ; >> ;
de comparaisons = = (égalité) ; = = = (égalité et même type) ; != ; < ; > ; (inégalités strictes) ; <= ; >= (inégalités)
logiques and ; && (et) ; or ; || (ou) ; xor (ou exclusif) ; ! (non)
Remarque : Faux = FALSE = 0 ; Vrai = TRUE = 1

Quelques exemples avec les opérateurs
Instructions Résultats Instructions Résultats
$a = 40 ; $b = 7 ; $a % $b = 5 $a = 5 ; $a += 2 ; $a = 7
$a = 10 ; echo $a++ ; 10 mais $a vaut 11 $a = 10 ; echo --$a ; 9
$a = 12 ; $b = 5 ; $a . $b = 125 $a = 5 ; $b = 6 ; $a & $b = 4
$a = 3 ; $b = 6 ; $a | $b = 7 $a = 3 ; $a << 2 = 12
$a = 7 ; $a >> 1 = 3 $a = 8 ; ($a = = 1) = 0

Structures de contrôle
On retrouve tous les classiques
if (Expr) {Instr si Vrai} else {Instr si Faux}
if (Expr1) {Instr si Vrai1} else if(Expr2) {Instr si Faux1 et Vrai2}
Remarque : else if = elseif
Notons la forme : (Expr1) ? (Expr2) : (Expr3)
while (Expr) {Instr tant que Vrai}
do {Instr} while (Expr) // Instr est exécuté au moins une fois
for (CompteurMin, CompteurMax, Increm) {Instr}
switch (Expr) {case Expr1 : Instr1; break; ... ; default : Instr ;}
Remarque : "break" permet de sortir d'une ou plusieurs boucles.
Compléments
Le langage possède de nombreuses fonctions applicables aux tableaux (pointeurs, parcours, tri ...), aux chaînes (découpages, concaténations, occurences ...), aux expressions rationnelles (Norme Posix 1003.2), aux dates (base Unix Epoch - 1er janvier 1970),  aux fichiers (localisation, gestion, lecture/écriture, ...). Il permet l'exécution de programmes externes (opérateur ", exec, ...) et l'appel de fichiers PHP dans un fichier HTML <? include Essai.php ; ?>
PHP peut être programmé "Objet" (mot clé "class").
Dans un contexte Web, le langage accède à de nombreuses informations (Propriétés de la requête si elle existe, N° IP, port TCP du socket, et logiciel du client, Gestion de cookies, Gestion de sockets ...) .
MySQL, dérivé de mSQL, est un SGBD relationnel performant basé sur le langage d'interrogation normalisé SQL (Structured Query Language). Écrit en C, il est porté par toutes les plateformes et interfacé avec la plupart des langages de programmation.
Le langage, capable d'utiliser une architecture multiprocesseur, privilégie la vitesse au détriment de techniques plus coûteuses en langage machine (pas de replication de bases de données ni de mécanismes de transaction "commit/rollback"). Les droits des utilisateurs sont enregistrés dans des tables internes et les mots de passe sont cryptés.
Quelques exemples testés avec EasyPhp 1.6 (PHP 4.2)
Il est bien évident que pour utiliser les fichiers, il faut les installer sur un serveur Web qui traite PHP.
L'utilisation dans un autre contexte ne prête à aucun commentaire.
NB : Afin de rendre visibles les contenus, j'ai remplacé l'extension "php" par "txt".
Calcul de la factorielle d'un nombre Récursivité et passage de paramètres
Fact1.php présente un formulaire, Fact1a.php effectue le calcul et affiche le résultat.
On ferait la même chose (plus facilement) côté client en JavaScript.
Fact1.php
Formulaire qui ne contient aucun script PHP (il pourrait avoir l'extension html).
La méthode de traitement est POST (mais pourrait être GET).
Fact1a.php
Récupère les données du formulaire, transmet le nombre à la fonction Factorielle et affiche le résultat.
Le tableau $HTTP_POST_VARS qui contient les données du formulaire est décomposé dans la structure "foreach". Le nombre $Recup[0] est traité récursivement par la fonction Fac(nombre) puis affiché.
Compteur de passages et numéros IP
Insertion de fichiers PHP, utilisation d'un fichier texte, date serveur et numéro IP du client
Compteur.php est le document principal. Compteura.php lit, incrémente et réécrit le nombre contenu dans le fichier Compteur.txt, puis l'affiche en utilisant les images gif du dossier Compteur. Adressip.php affiche la date et l'heure du Serveur Web ainsi que l'adresse IP et l'hôte du Client.
Compteur.php
Document principal qui insère dynamiquement deux autres fichiers.
include ("Compteura.php");
include ("Adressip.php");
Bien qu'exécuté à l'intérieur de délimiteurs PHP (<? ... ?> , le fichier appelé par la directive include doit aussi contenir ces délimiteurs.
Compteura.php
Ouvre le fichier Compteur.txt en lecture/ecriture
$fp = fopen("Compteur.txt","r+");
Lit le nombre qu'il contient, ajoute 1 et enregistre
$nbVis = fgets($fp,15);
$nbVis += 1;
fseek($fp,0);
fputs($fp,$nbVis);
fclose($fp);
Affiche une image du nombre
for ($i=0;$i<strlen($nbVis);$i++) {
  $ch = substr($nbVis,$i,1);
  if ($ch==" ") $ch="sp";
  echo "<img src=\"compteur/".$ch.".gif\">";
 

$fp descripteur (handle) du fichier texte,

$nbVis maximum 14 chiffres,

fseek => 0 pour remplacer l'ancienne valeur.

Les 3 lignes suivantes matérialisent le partage du nombre en tranches de 3 chiffres.

La dernière boucle for associe à chaque caractère de la chaîne $nbVis une image du dossier Compteur.
(Notez la très jolie variabilisation du nom des images). 
Adressip.php
Formate et affiche la date et l'heure du serveur
setlocale("LC_TIME","fr");
$MonJour = strftime("%A %d %B %Y");
$MonHeure = strftime("%Hh %Mmin %Ss");
ainsi que "l'identité" du client
$MonIP = $REMOTE_ADDR;
$MonHost = gethostbyaddr($MonIP);


Nous sommes le dimanche 18 août 2003
Il est 11h 15min 35s


L'adresse IP de Hôte non défini
est 127.0.0.1
Validation d'une adresse électronique Expressions rationnelles/Backus Naur Form, redirection
EMail.php est le formulaire de saisie, EMaila.php applique les règles de validation et redirige vers EMailb.php si la forme est correcte ou renvoi sur le formulaire en cas d'erreur. Tout se passe au niveau serveur.
EMail.php
L'adresse électronique saisie dans le formulaire est transmise sous la forme classique
form action="EMaila.php?$Rep1" 
Rep1 est le nom du champ qui contient l'adresse.
Le script PHP permet de commenter les propositions non conformes.
EMaila.php
Fichier PHP "pur". Il reçoit l'adresse $Rep1, lui applique les règles définies et effectue une redirection vers la page $f avec le paramètre $v.
header("Location: ".$f."?".$v);
Une Adresse est de la forme Nom@Domaine
Un Nom est composé d'un Atome suivi éventuellement d'autres Atomes
Un Domaine est composé d'au moins deux Atomes.
Deux Atomes sont séparés par un Point. Un Atome ne peut contenir ni espace, ni caractères diacritiques, ni caractères spéciaux (voir les commentaires dans le fichier.
EMailb.php
Ouvert quand l'adresse proposée est conforme aux règles en vigueur.
L'adresse électronique est toujours disponible dans la variable $Rep1.
Accès à une base de données MySQL
Connexion au Serveur, ouverture d'une base de données, lecture d'une table
LogSQL.php présente un formulaire d'identification, LogSQLa.php effectue les connexions, les vérifications et les redirections. La base EssaiDB contient la table Table1 et les champs Login, Passe, Nom, Prenom, Adresse.
Une partie des vérifications est faite en JavaScript.
LogSQL.php
Formulaire de saisie du login et du mot de passe du client.
La méthode de traitement est POST.
Le script JavaScript permet de refuser les champs de formulaire vides.
Le script PHP permet de commenter les retours sur erreur.
LogSQLa.php
Fichier PHP "pur".
Il effectue la connexion au serveur MySQL, ouvre la base EssaiDB, et exécute la requête $Req.
SELECT nom, prenom, adresse
FROM Table1
WHERE login = "$LogUtil" AND passe = "$PassUtil"

En cas d'échec on revient au formulaire initial sinon un fichier de bienvenue est créé à la volée.
Les variables $LogUtil et $PassUtil sont les contenus des champs de même nom du formulaire.
Notez les affectations avec <<<.

Sites dédiés à PHP
Site de Apache
Site de MySQL
Site de PHP
Site de PHP builder
Site de Zend


Active Serveur Page
ASP est optimisé pour les serveurs Web de Microsoft IIS (Internet Information Server) ou PWS (Personal Web Server) dans un environnement Windows NT (néanmoins Sun Chili!Soft propose des implémentations pour d'autres serveurs). Alternative au système CGI/Perl, il permet de créer sur le serveur des pages Web dynamiques sans utiliser des scripts séparés enregistrés dans des répertoires spéciaux. Comme avec PHP, l'environnement ASP du serveur Web exécute les scripts contenus dans un fichier .asp et renvoie un code HTML complet au navigateur appelant mais, à la différence de PHP, l'environnement ASP, distribué avec les produits Web de Microsoft, n'est pas gratuit.
La base statique d'une page ASP est du code HTML. La partie dynamique est constituée de formulaires associés à des bases de données, de scripts écrits en JScript ou VBScript de Microsoft (bien qu'il soit possible d'utiliser Python, Rexx ou PerlScript), d'objets intrinsèques de ASP (Response, Request, Application, Session ou Server), et d'objets COM standards (Component Object Model de Microsoft) appelés Active Server Components.

C
L
I
E
N
T
=> Demande d'une page ASP

404 'Page Not Found' <=






Envoi d'une page HTML <=
S
E
R
V
E
U
R


=> Envoi de la page au moteur de script


=> Exécution du fichier global.asa <=


302 'Object has moved' <=
 Erreur de code ASP <=
Exécution du script <=
H
O
T
E

D
E

S
C
R
I
P
T

Application Web
C'est la réunion de quelques pages et de quelques composants serveur (un site Web peut contenir plusieurs applications). Une application est composée d'un répertoire racine, de ses sous-répertoires et de composants. Une session est ouverte pour chaque client. Le fichier global.asa de la racine, exécuté au début et à la fin de chaque session, permet d'appliquer du code à toute l'application et de suivre l'évolution des variables d'état.
Le modèle objet ASP
L'objet ScriptingContext (accessible en programmation VB par la fonction WebClass) représente le cadre dans lequel s'exécutent les scripts ASP. Créé et détruit automatiquement, il permet d'utiliser les collections, propriétés et méthodes des objets intrinsèques :
Request permet d'accéder aux informations contenues dans une requête HTTP (collections ClientCertificate, Cookies, Form, QueryString, ServerVariables ...),
Response permet de contrôler le contenu de la réponse HTTP du serveur (collection Cookies, propriétés ContentType, Expires, IsClientConnected, méthodes AddHeader, Redirect, Write, ...),
Application permet de stocker des informations (objets et variables) dont la portée s'étend à l'application (collections Contents, StaticObjects, méthodes Lock, Unlock, événements OnStart, OnEnd),
Session permet de stocker des informations propres à un utilisateur (collections Contents, StaticObjects, propriétés CodePage, SessionID, Timeout, méthodes Abandon, événements OnStart, OnEnd),
Server propose quelques propriétés et méthodes fondamentales (ScriptTimeout, CreateObject, ...).
Les objets de script (VBScript) disponibles sont :
FileSystemObject pour accéder au système de fichier du serveur Web,
TextStream pour accéder en lecture/écriture au contenu d'un fichier texte,
Dictionary pour stocker des paires nom:valeur au niveau d'une page (ou éventuellement d'une session).
Les composants serveur
Il s'agit de composants ActiveX ou d'objets COM (.dll ou .exe) conçus pour être utilisés sur le serveur.
On crée une instance d'un composant (ici AdRotator) avec la méthode CreateObject de l'objet Server
set MonComp = Server.CreateObject("MSWC.AdRotator")
ou en le déclarant dans la balise <object>
<object>RUNAT="Server" ID="MonComp" PROGID="MSWC.AdRotator"</object>
Déclaré dans global.asa, la portée (scope) de l'objet peut être étendue à l'application.
Les composants peuvent être fournis par Microsoft avec ses serveurs Web, proposés par des fabricants indépendants ou créés par l'utilisateur à partir de VB, C++, Delphi ou Java.
Accès aux bases de données avec ActiveX Data Object
Pour s'adapter aux niveaux de communication du Web (présentation, métier, données), Microsoft a remplacé ODBC (Open Data Basa Connectivity) par OLEDB et développé l'architecture ci-dessous :

Pour obtenir des données avec ADO, on passe par un fournisseur de données OLEDB. Les ADO sont des enveloppes COM placées au dessus d'OLEDB (mais on peut accéder aux données directement ou en passant par ODBC).
Modèle objet des ADO
L'objet Connection est au sommet de la hiérarchie (s'il n'est pas explicitement défini, il sera instancié automatiquement). Il permet d'établir une connexion avec une source de données. Exemple avec Access :
<%chConx = "Provider=Microsoft.Het.OLEBD.3.51; Data Source=C:\Donnees\K7.mdb"
Set objConx1=Server.CreateObject("ADODB.Connection")
objConx1.Open chConx %>

L'objet Command permet d'exécuter des commandes SQL.
L'objet Recordset permet d'accéder aux enregistrements
<% Set objTab1=Server.CreateObject("ADODB.Recorset")
objTab1.Open "Films", objConx1, ,adLockReadOnly %>

La collection Fields permet d'accéder aux Champs du Recordset.
Éléments du langage et exemples
ASP n'est pas un langage de programmation mais un ensemble d'objets hiérarchisés. L'utilisateur laissera les problèmes de "structures" et de "syntaxe" à son langage de script et ne se posera sur ASP que des questions concernant la hiérarchie, les collections, les méthodes, les propriétés et les événements du modèle objet.
Les scripts sont écrits dans le corps de la page HTML (entre <body> et </body>) et à l'intérieur de balises <% ... %>. Afin d'éviter de ralentir l'analyseur syntaxique, minimisez le nombre de blocs <% ... %> et supprimez les commentaires dans les versions définitives.

Instructions initiales
<% @Language = "VBScript" %> VBScript est le langage par défaut mais on peut en utiliser d'autres.
<% Option Explicit
  Response.Buffer = True
  Response.Expires = -1000 %>
Rend obligatoire la déclaration des variables.
Pour envoyer la page HTML en une seule fois.
Durée de vie de la page HTML dans le cache.

Inclusions de fichiers
Il est possible d'inclure dans les pages ASP des fichiers contenant des portions de code utilisées fréquemment.
#include file="d:\wwwroot\includes\stats.asp"
Les "mini exemples" qui suivent n'ont pas été testés récemment. Ecrits en VBScript, ils utilisent les objets ASP.

Parcours de collections Notez les différences de structures et les similitudes d'objets
En VBScript En JScript
For Each Item In Request.ServerVariables
  chNom = Item
  chVal = Request.ServerVariables(Item)
  Response.Write chNom & "&nbsp;" & chVal & "<br />"
Next
FormItems = new Enumerator(Request.ServerVariables);
while (!FormItems.atEnd()) {
  i = FormItems.item();
  chNom = i;
  chVal = Request.ServerVariables(i);
  Response.Write (chNom & "&nbsp;" & chVal & "<br />");
  FormItems.moveNext(); }
Utilisation des variables d'application dans global.asa
<script language=VBScript runat=Server>
Sub Application_OnStart
 Application("nbVisit")=0
 Application("nbPres")=0
End Sub
Sub Session_OnStart
 Session.Timeout= 3
 Session("Debut")=Now
 Application.Lock
  Application("nbVisit")= Application("nbVisit") + 1
  totVisit=Application("nbVisit")
 Application.Unlock
 Session("IDVisit")=totVisit   
 Application.Lock
  Application("nbPres")= Application("nbPres") + 1
 Application.Unlock
End Sub
Sub Session_OnEnd
 Application.Lock
  Application("nbPres")= Application("nbPres")-1
 Application.Unlock
End Sub </script>
A la première connexion :
Initialisation des variables d'application
nbVisit est le nombre de visiteurs.
nbPres le nombre de sessions ouvertes.
A chaque nouvelle visite :
Le délai d'expiration de la session est fixé à 3 minutes.
Le début de la session est l'heure courante du serveur.
Lock, Unlock règlent les problèmes d'accès simultanés aux variables.
Le nombre de visiteurs augmente de 1.
Le nombre de présents augmente de 1.
L'ID du visiteur est son numéro.



A chaque fin de session :
Le nombre de présents diminue de 1. 
Ouverture/Création d'un fichier
Set objFSO= CreateObject("Scripting.FileSystemObject")
Set objFich=objFSO.CreateTextFile ("d:\temp\Compte.txt", true)
objFich.Write totVisit
objFich.Close
Méthode CreateObject de VBScript.
Ouverture ou création du fichier Compte.txt (true pour écraser).
Ecriture d'une nouvelle chaîne.

Récupération des données d'un formulaire
Problème classique et récurrent. L'attribut ACTION de la balise <FORM> spécifie l'URL que doit utiliser le navigateur pour lancer la requête quand l'utilisateur soumet le formulaire. L'attribut METHOD (POST ou GET) spécifie la technique d'empaquetage des données du formulaire dans la requête HTTP.
Avec POST elles sont intégrées dans le corps de la requête => collection Request.Form
Avec GET elles sont "collées" à l'URL => collection Request.QueryString

Sites dédiés à ASP
Site de L-ASP
Site de ASP.fr
Site de ASPZone


Le langage Perl et l'interface CGI
CGI (Common Gateway Interface) est une norme qui définit l'interfaçage d'applications externes avec un serveur HTTP. Un "programme CGI" est exécuté au moment où le client fait une requête au serveur HTTP. Il sert de passerelle (gateway) entre le navigateur et des informations externes (base de données par exemple). Il n'existe pratiquement pas de limites à ce que peut faire un programme CGI (la seule contrainte "commerciale" étant la durée de l'attente du client).
Pour simplifier la gestion du serveur et diminuer les risques créés par l'utilisation d'exécutables, les programmes CGI sont en général placés dans un dossier "cgi-bin". En conséquence, tout fichier du dossier cgi-bin est considéré comme exécutable et, quand le serveur reçoit une requête sur une URL du type http://www.dom.org/cgi-bin/prog.html, il exécute d'abord son contenu avant de le renvoyer au client. De plus, comme l'utilisation du répertoire cgi-bin est généralement soumise à l'autorisation de l'administrateur du serveur, celui-ci peut contrôler les auteurs et les effets des programmes CGI.
En résumé, le serveur HTTP n'exécute que les programmes qui se trouvent dans un répertoire dédié et il est nécessaire d'obtenir l'autorisation de l'administrateur pour en installer un.
Un programme CGI peut être écrit dans tout langage capable d'accéder aux variables d'environnement et d'écrire sur la sortie standard (C, C++, Fortran, Perl, TCL, un shell Unix, Visual Basic, AppleScript ... )
Les programmes peuvent être compilés (C, C++, ...) ou laissés sous forme de scripts interprétés à l'exécution.
Venu de Unix, proche de C, Perl (Practical Extraction and Reporting Langage) a été le langage le plus utilisé sur l'internet. Né en 1988 et critiqué en 1995 par les partisans de Java, comme tout l'univers CGI, il résiste bien en étant intégré dans l'environnement Windows comme langage de script et supporté en mode kernel par les serveurs Apache et Netscape. C'est un langage interprété, multiplateforme, puissant et complet, aux bibliothèques impressionnantes, qui permet de manipuler des chaînes de caractères en mode procédural ou en mode orienté objet. Il privilégie l'efficacité à la clarté. Totalement gratuit et offert à la communauté sous la licence GNU CopyLeft par son créateur Larry Wall, il est constamment amélioré.
En Perl tout est chaîne de caractères, le nom des variables scalaires est sensible à la casse et précédé de $ (dollar), le ; (point-virgule) marque la fin d'une instruction et le # (dièse) introduit un commentaire. Il utilise les expressions régulières.
$nb1=3; $nb2=2; $nb3=$nb1 + $nb2; # $nb3 contient la chaîne de caractères "5"
$ch4="3"; $ch5="2"; $ch6=$ch4 + $ch5; # $ch6 contient (aussi) la chaîne "5"

Assignations et opérations
Instructions Résultats Instructions Résultats
$a = 10**7; $a = 10 000 000 ++$a ou --$a pré affectation
$a = 10 ; $b=3; $a += $b vaut 13 $a++ ou $a-- post affectation
$a = 12 ; $b = 5 ; $a  -= $b vaut 7 $a = 5 ; $b = 6 ; $a .= $b vaut 56

Tableaux et Dictionnaires
Les tableaux sont des suites linéaires de chaînes de caractères. Le nom des variables tableaux est précédé de @ (arrobas).
@Marques=("Peugeot","Citroën","Renault"); # $Marques[0] = "Peugeot"
$a=15; $b=15.4; $c="Notes"; @tableau=($a,$b,$c);
est équivalent à @tableau=(15, 15.4, "Notes");
Les dictionnaires (hashes) sont des suites de couples nom:valeur. Leur nom est précédé de % (pour cent).
%Ages=("Daniel", 33, "JPaul", 69, "Rene", 51; # $Ages{"JPaul"} = "69"
mais $Ages[3] est aussi égal à "69".
$nbVoitures=@Marques; # nombre d'éléments du tableau
$listVoitures="@Marques"; # liste des éléments du tableau
$derVoitures=$#Marques; # index du dernier élément du tableau
push()/pop() ajoute/extrait un élément à droite d'un tableau
push(@Marques,"Fiat"); $Voiture=pop(@Marques);
unshift()/shift() ajoute/extrait un élément à gauche d'un tableau
et aussi sort(), reverse(), chop(), qw(), key(), values() ...
@ARGV est le tableau des arguments de la ligne de commande. Contrairement à C, le premier argument est @ARGV[0].
Boucles et conditions
for ($i=0; $i<10; $i++) {print "$i\n";} # affiche les nombres de 0 à 9 (même entre "", $i est remplacé par sa valeur)
$i = 0; do while ($i < 10) {print $i++;} # même chose
$i = 0; do {print $i++;} while ($I < 10); # même chose
foreach $Voiture (@Marques) {print "$Voiture\n";}
if (condition1) {action1} elsif (condition2) {action2} else {action3}
unless (conditions1) {action1} else {action2}
# non if
Fichiers
Un fichier peut être physique (sur disque) mais aussi le clavier (STDIN), l'écran (STDOUT) ou la sortie erreurs (STDERR). L'entrée STDIN est souvent utilisée pour traiter les informations en provenance d'un formulaire.
La commande open(alias, "fichier") permet d'ouvrir le fichier "fichier" sous le nom alias. Le mode d'accès est défini par un préfixe ajouté au nom du fichier :
" fichier" ou "<fichier" pour une ouverture en lecture,
">fichier" pour une ouverture en réécriture (ou une création)
">>fichier" pour une ouverture en écriture à la suite
"+>fichier" pour une ouverture en lecture et écriture
| Programme envoie les données vers le programme Programme
Programme | utilise Programme comme source de données
La commande close(alias) ferme le fichier.
@lignes = <alias>; place le contenu du fichier dans le tableau @lignes dont chaque ligne peut être un enregistrement.
read(alias, Buf, nbrCar, Deb); lit NbrCar caractères du fichier alias à partir de Deb et les place dans Buf.
print alias Texte; écrit Texte dans le fichier alias.
printf permet de formater la sortie des variables :
$P1=123.34; $P2=23345.45;
printf("A=\$%8.2f\n", $P1); printf("B= \$%8.2f\n", $P2);
Affiche A=$  123.34 et B= $23345.45
Les fonctions glob(), readdir(), chdir(), mkdir(), rmdir(), unlink(), chmod() ... permettent d'intervenir sur le système de fichiers.
Fonctions
Il existe de nombreuses fonctions qui permettent de gérer les fichiers et leurs accès. On peut bien entendu en créer d'autres.
Exemple avec passage de paramètres :
sub Coucou {print "Bonjour $_[0]. Il fait $_[1].\n";
&Coucou("toi", "beau"); affichera Bonjour toi. Il fait beau. (& est optionnel et les arguments sont récupérés dans la variable tableau $_ )
Pour passer un argument par référence (un tableau par exemple) on utilise \ (antislash) :
@pairs=(0,2,4,6,8); $refpairs=\@pairs; # $$refpairs[1] vaut 2 ou $refpairs ->1 vaut 2
Pour référencer des tableaux anonymes on peut utiliser des [ ] (crochets) (des { } pour les hashes) :
$refpairs = [0,2,4,6,8]; # ce qui est pratique pour manipuler des structures complexes (tableaux de tableaux par exemple)
Les exemples suivants n'ont pas été testés (Notez les nombreuses ressemblances avec PHP)
Exemple 1 : Avant de dire "Coucou", ce script vérifie qu'un nom lui est transmis. Sinon il pose une pose la question.

Hello Word
#!/usr/bin/perl
if ($#ARGV < 0) {
  print "Quel est votre nom ?\n";
  $nom=<STDIN>;
#suppression du retour chariot:
  chop($nom); }
else {$nom=$ARGV[0]; }
print "\nCoucou $nom !\n";
Chemin de l'interpréteur Perl sous Unix
Pas d'arguments en ligne de commande
Sortie vers l'écran
Saisie du nom au clavier
Commentaire
Le premier argument est le nom
Les variables sont interprétées dans les guillemets 

Exemple 2 : ce script très simple ajoute 1 au nombre contenu dans un fichier texte (Compteur.txt).

Fichier compteur
#!C:\Perl\bin\Perl.exe
use strict;
$fichNom="Compteur.txt";
open(Fich1, "$fichNom") || die("Erreur de lecture de $fichNom : $!\n");
$Nombre=<Fich1>;
close(Fich1);
chomp($Nombre);
$Nombre++;
open(Fich1, ">$fichNom") || die("Erreur d'écriture de $fichNom : $!\n");
print Fich1 $Nombre."\n";
close(Fich1);
Chemin de l'interpréteur Perl sous Windows
Module Perl qui rend obligatoire le déclaration des variables
Ouverture en lecture du fichier (descripteur Fich1), lecture du nombre et fermeture du fichier
$! affiche le code retour des fonctions système

Suppression du retour chariot de la chaîne $Nombre
Incrémentation du compteur
Ouverture en écriture du fichier (descripteur Fich1), écriture du nombre (plus un saut de ligne) et fermeture du fichier 

Exemple 3 : il est bien sûr possible de passer les données d'un formulaire à un script CGI en utilisant les méthodes POST ou GET mais le script suivant fait tout dans le même fichier.

Création d'un formulaire et récupération des données
#!C:\Perl\bin\Perl.exe
use strict;
use CGI qw(:standard);
print header(),
start_html('Utilisation d'un formulaire'),
h2('Formulaire 1'),
start_form('get'), "Nom : ",
textfield(-name=>'Nom',  -size=>20, -maxlength=>30),
br, "Prénom : ",
textfield(-name=>'Prenom', -size=>25, -maxlength=>30),
br, "Adresse électronique : ",
textfield(-name=>'EMail', -size=>50, -maxlength=>70),
p, submit(-value=>'Envoyer'),
end_form, hr;
if (param()) {
  print h2('Résultat du formulaire 1'),
  "Votre nom : ", param('Nom'), br,
  "Votre prénom : ", param('Prenom'), br,
  "Votre Adresse électronique : ", param('EMail'),p; }
print end_html;

Module Perl qui rend obligatoire le déclaration des variables
Module CGI qui contient le jeu standard de fonctions
Fonction CGI qui crée un en-tête HTTP
Création "à la volée" d'un fichier HTML et d'un formulaire

Méthode GET
Champs Nom, Prenom et EMail






Lors du premier appel seul le formulaire est affiché (param() est vide)
Le bouton submit fait un second appel et actualise la deuxième partie.

Sites dédiés à Perl
Site de Perl
Site de Perl Mongers
Site de CPAN
Site de Perl Apache
Site de François Dagorn 
Retour au début