Cours PHP
Cours PHP
Cours PHP
Introduction
PHP est un langage interprété (un langage de script) exécuté du côté serveur (comme les scripts CGI,
ASP, ...) et non du côté client (un script écrit en Javascript ou une applet Java s'exécute sur votre
ordinateur...). La syntaxe du langage provient de celles du langage C, du Perl et de Java. Ses principaux
atouts sont:
Origines de PHP
Le langage PHP a été mis au point au début d'automne 1994 par Rasmus Lerdorf. Ce langage de script
lui permettait de conserver la trace des utilisateurs venant consulter son CV sur son site, grâce à l'accès
à une base de données par l'intermédiaire de requêtes SQL. Ainsi, étant donné que de nombreux
internautes lui demandèrent ce programme, Rasmus Lerdorf mit en ligne en 1995 la première version de
ce programme qu'il baptisa Personal Sommaire Page Tools, puis Personal Home Page v1.0 (traduisez
page personnelle version 1.0).
Etant donné le succès de PHP 1.0, Rasmus Lerdorf décida d'améliorer ce langage en y intégrant des
structures plus avancées telles que des boucles, des structures conditionnelles, et y intégra un package
permettant d'interpréter les formulaires qu'il avait développé (FI, Form Interpreter) ainsi que le support
de mSQL. C'est de cette façon que la version 2 du langage, baptisée pour l'occasion PHP/FI version 2, vit
le jour durant l'été 1995. Il fut rapidement utilisé sur de nombreux sites (15000 fin 1996, puis 50000 en
milieu d'année 1997).
A partir de 1997, Zeev Suraski et Andi Gurmans rejoignirent Rasmus pour former une équipe de
programmeurs afin de mettre au point PHP 3 (Stig Bakken, Shane Caraveo et Jim Winstead les
rejoignirent par la suite). C'est ainsi que la version 3.0 de PHP fut disponible le 6 juin 1998.
A la fin de l'année 1999 la version 4.0 de PHP, baptisée PHP4, est apparue. PHP en est
aujourd'hui à sa cinquième version.
PHP permet un interfaçage simple avec de nombreux systèmes de gestion de bases de données (SGBD),
parmi lesquels :
Adabas D
dBase
Empress
FilePro
Informix
Interbase
mSQL
MySQL
Oracle
PostgreSQL
Solid
Sybase
Velocis
Unix dbm
Un script PHP est un simple fichier texte contenant des instructions écrites à l'aide de caractères ASCII 7
bits (des caractères non accentués) incluses dans un code HTML à l'aide de balises spéciales et stocké
sur le serveur. Ce fichier doit avoir l'extension « .php » pour pouvoir être interprété par le serveur.
Ainsi, lorsqu'un navigateur (le client) désire accéder à une page dynamique réalisé en PHP :
Le code PHP stocké sur le serveur n'est donc jamaisvisible directement par le client puisque dès
qu'il en demande l'accès, le serveur l'interprète!
De cette façon aucune modification n'est à apporter sur les navigateurs.
Pour que le script soit interprété par le serveur deux conditions sont nécessaires:
Le fichier contenant le code doit avoir l'extension telle que .php et non .html
Le code PHP contenu dans le code HTML doit être délimité par des balises du type <? et ?>
Un script PHP doit:
comporter l'extension .php
être imbriqué entre les délimiteurs <? et ?>
Pour des raisons de conformité avec certaines normes (XML et ASP par exemple), plusieurs balises
peuvent être utilisées pour délimiter un code PHP :
1. <? et ?>
2. <?php et ?>
3. <script language="php"> et </script>
4. <%php et %>
Un exemple de script simple
<html>
<head><title>Exemple</title></head>
<body>
<?php
echo "Hello world";
?>
</body>
</html>
On notera bien évidemment que la fonction echo permet d'afficher sur le navigateur la chaine délimitée
par les guillemets.
L'interprétation du code
Un code PHP (celui compris entre les délimiteurs <?php et ?>) est un ensemble d'instructions se
terminant chacune par un point-virgule (comme en langage C). Lorsque le code est interprété, les
espaces, retours chariot et tabulation ne sont pas pris en compte par le serveur. Il est tout de
même conseillé d'en mettre (ce n'est pas parce qu'ils ne sont pas interprétés que l'on ne peut
pas les utiliser) afin de rendre le code plus lisible (pour vous, puisque les utilisateurs ne
peuvent lire le code source: il est interprété).
Les commentaires
Une autre façon de rendre le code plus compréhensible consiste à insérer des commentaires, des lignes
qui seront tout simplement ignorées par le serveur lors de l'interprétation.
Pour ce faire, il est possible, comme en langage C, d'utiliser des balises qui vont permettre de délimiter
les explications afin que l'interpréteur les ignore et passe directement à la suite du fichier.
Ces délimiteurs sont /* et */. Un commentaire sera donc noté de la façon suivante:
/* Voici un commentaire! */
Les commentaires peuvent être placés n'importe où à l'intérieur des délimiteurs de script
PHP
Les commentaires ne peuvent contenir le délimiteur de fin de commentaire (*/)
Les commentaires ne peuvent être imbriqués
Les commentaires peuvent être écrits sur plusieurs lignes
Les commentaires ne peuvent pas couper un mot du code en deux
Il est possible aussi d'utiliser un type de commentaire permettant de mettre toute la fin d'une ligne en
commentaire en utilisant le double slash (//). Tout ce qui se situe à droite de ce symbole sera mis
en commentaire.
Typologie
La manière d'écrire les choses en langage PHP a son importance. Le langage PHP est par exemple
sensible à la casse (en anglais case sensitive), cela signifie qu'un nom contenant des majuscules est
différent du même nom écrit en minuscules. Toutefois, cette règle ne s'applique pas aux fonctions, les
spécifications du langage PHP précisent que la fonction print peut être appelée print(), Print() ou
PRINT().
Enfin, toute instruction se termine par un point-virgule.
Introduction
Un serveur web est un logiciel permettant de rendre accessibles à de nombreux ordinateurs (les clients)
des pages web stockées sur le disque. Cette fiche pratique explique comment installer le serveur web
Apache sur un système de type UNIX (typiquement une distribution de Linux telle que RedHat,
Mandrake ou n'importe quelle autre).
Pour cela quelques connaissances sur Linux ou bien Unix sont nécessaires. Le but de cette fiche va être
d'être capable de récupérer les sources des différents éléments nécessaires et de les compiler (un
compilateur C est donc nécessaire, il est généralement installé par défaut sur la plupart des distributions
Linux) afin d'avoir un système opérationnel.
Il s'agit de choisir l'extension associée aux scripts PHP. Par souci d'homogénéité, il est courant
de choisir l'extension .php3
24. Démarrez le serveur Apache. (Il est essentiel d'arrêter et redémarrer le serveur, et non
uniquement de le relancer. Il suffit généralement de taper apachectl stop, puis apachectl start).
Premier lancement
Pour vérifier si l'installation a bien fonctionnée, il vous suffit de créer un petit fichier dans la racine des
documents du serveur web (appelée DocumentRoot dans le fichier de configuration httpd.conf). Nommez
ce fichier toto.php3, et mettez le code suivant dans ce fichier:
<html>
<head><title>Exemple</title></head>
<body>
<?php
?>
</body>
</html>
http://localhost/toto.php3
Vous devriez logiquement voir apparaître la phrase "PHP fonctionne!" sur votre navigateur !
Introduction à EasyPHP
Afin de faire fonctionner PHP, il est nécessaire à la base d'en télécharger les sources depuis un site
spécialisé (par exemple PHP.net), puis de compiler celui-ci (ainsi que d'éditer les liens) afin de créer un
fichier exécutable.
Ce processus demande des notions avancées en informatique, c'est pourquoi trois adeptes de PHP
(Emmanuel Faivre, Laurent Abbal et Thierry Murail) ont mis au point un package (appelé EasyPHP)
contenant 3 produits incontournables de la scène PHP :
EasyPHP est ainsi un pack fonctionnant sous Windows permettant d'installer en un clin d'oeil
les éléments nécessaires au fonctionnement d'un site web dynamique développé en PHP
Récupérer EasyPHP
www.manucorp.com
www.easyphp.org
Il vous suffit dans un premier temps de télécharger la version la plus récente de EasyPHP. Vous pouvez
la télécharger à cette adresse :
Page de téléchargement de EasyPhP
Installer EasyPHP
L'installation de EasyPHP est très simple, notamment avec l'apparition de la version 1.4 comportant un
installeur automatique.
Pour installer EasyPHP, il vous suffit dans un premier temps de double-cliquer sur le fichier téléchargé
précédemment :
L'écran d'installation de EasyPHP suivant devrait apparaître, cliquez sur Next (Suivant</) :
Cette erreur indique que la librairie msvcrt.dll n'a pû être copiée. La raison de cette erreur
provient du fait que votre système Windows est actuellement en train d'utiliser cette libraire et ne
peut donc l'écraser.
Pour y remédier, copiez cette librairie (par exemple dans c:\) sur votre disque dur (cliquez ici
pour télécharger la librairie pour Windows 9x), puis redémarrez en mode MS-DOS, puis tapez
copy c:\msvcrt.dll c:\windows\system. Le système va vous demander de confirmer cet
écrasement répondez "Oui" (Y ou O), redémarrez Windows et EasyPHP devrait fonctionner !
Démarrage de EasyPHP
Pour démarrer Apache, MySQL et PHP, il vous suffit de lancer EasyPHP à partir du groupe créé dans le
menu démarrer :
Pour vérifier si EasyPHP fonctionne, il vous suffit de taper dans votre navigateur préféré :
http://localhost
ou http://127.0.0.1
Les deux adresses ci-dessus représentant votre machine locale.
Editer votre site
Pour créer votre site web dynamique avec EasyPHP, il vous suffit de déposer vos créations dans le sous-
répertoire /www de EasyPHP.
<?
phpinfo();
?>
Plus d'informations
Pour plus d'informations ou en cas de problème avec EasyPHP, allez sur EasyPHP.org. En cas de
problème, commencez par consulter la FAQ, puis consultez le Forum
Une variable est un objet repéré par son nom, pouvant contenir des données, qui pourront être modifiées
lors de l'exécution du programme. Les variables en langage PHP peuvent être de trois types:
scalaires
tableaux
tableaux associatifs
Quelque soit le type de variable, son nom doit obligatoirement être précédé du caractère dollar
($). Contrairement à de nombreux langages de programmation, comme le langage C, les
variables en PHP n'ont pas besoin d'être déclarées, c'est-à-dire que l'on peut commencer à les
utiliser sans en avoir averti l'interpréteur précédemment, ainsi si la variable existait
précédemment, son contenu est utilisé, sinon l'interpréteur lui affectera la valeur en lui
assignant 0 par défaut. De cette façon si vous ajoutez 3 à une nouvelle variable (non définie
plus haut dans le code), sa valeur sera 3...
Nommage des variables
un nom de variable doit commencer par une lettre (majuscule ou minuscule) ou un "_" (pas par
un chiffre)
un nom de variable peut comporter des lettres, des chiffres et le caractère _ (les
espaces ne sont pas autorisés!)
Nom de variable correct Nom de variable incorrect Raison
$Variable $Nom de Variable comporte des espaces
$Nom_De_Variable $123Nom_De_Variable commence par un chiffre
$nom_de_variable [email protected] caractère spécial @
$nom_de_variable_123 $Nom-de-variable signe - interdit
$nom_de_variable nom_de_variable ne commence pas par $
Les noms de variables sont sensibles à la casse (le langage PHP fait la différence entre un nom en
majuscule et un nom en minuscules), il faut donc veiller à utiliser des noms comportant la même
casse! Toutefois, les noms de fonctions font exception à cette règle...
Variables scalaires
Il existe des caractères repérés par un code ASCIIspécial permettant d'effectuer des opérations
particulières. Ces caractères peuvent être représentés plus simplement en langage PHP grâce
au caractère '\' suivi d'une lettre, qui précise qu'il s'agit d'un caractère de contrôle:
Caractère Description
\" Guillemet
\\ barre oblique inverse (antislash)
\r retour chariot
\n retour à la ligne
\t Tabulation
En effet, certains de ces caractères ne pourraient pas être représentés autrement (un retour à la
ligne ne peut pas être représenté à l'écran). D'autre part, les caractères \ et " ne peuvent pas
faire partie en tant que tel d'une chaîne de caractère, pour des raisons évidente d'ambiguité...
Variables tableaux
Les variables, telles que nous les avons vues, ne permettent de stocker qu'une seule donnée à la fois.
Or, pour de nombreuses données, comme cela est souvent le cas, des variables distinctes seraient
beaucoup trop lourdes à gérer. Heureusement, PHP propose des structures de données permettant de
stocker l'ensemble de ces données dans une "variable commune". Ainsi, pour accéder à ces valeurs il
suffit de parcourir la variable de type complexe composée de « variables » de type simple.
Les tableaux stockent des données sous forme de liste. Les données contenues dans la liste sont
accessibles grâce à un index (un numéro représentant l'élément de la liste). Contrairement à des
langages tels que le langage C, il est possible de stocker des éléments de types différents dans un même
tableau.
Ainsi, pour désigner un élément de tableau, il suffit de faire suivre au nom du tableau l'indice de
l'élément entre crochets:
$Tableau[0] = 12;
$Tableau[1] = "CCM";
Avec PHP, il n'est pas nécessaire de préciser la valeur de l'index lorsque l'on veut remplir un tableau, car
il assigne la valeur 0 au premier élément (si le tableau est vide) et incrémente les indices suivants. De
cette façon, il est facile de remplir un tableau avec des valeurs. Le code précédent est équivalent à:
$Tableau[] = 12;
$Tableau[] = "CCM";
Les indices de tableau commencent à zéro
tous les types de variables peuvent être contenus dans un tableau
Lorsqu'un tableau contient d'autres tableaux, on parle de tableaux multidimensionnels. Il est possible de
créer directement des tableaux multidimensionnels en utilisant plusieurs paires de crochets pour les
index (autant de paires de crochets que la dimension voulue). Par exemple, un tableau à deux
dimensions pourra être déclaré comme suit:
$Tableau[0][0] = 12;
$Tableau[0][1] = "CCM";
$Tableau[1][0] = 1245.652;
$Tableau[1][1] = "Au revoir";
Variables tableaux associatifs
PHP permet l'utilisation de chaînes de caractères au lieu de simples entiers pour définir les indices d'un
tableau, on parle alors de tableaux associatifs. Cette façon de nommer les indices peut parfois être plus
agréable à utiliser:
$Toto["Age"] = 12;
$Toto["Adresse"] = "22 rue des bois fleuris";
$Toto["Nom"] = "Ah, vous auriez bien aimé
connaître le nom de famille de Toto...";
Portée (visibilité) des variables
Selon l'endroit où on déclare une variable, celle-ci pourra être accessible (visible) de partout dans le code
ou bien que dans une portion confinée de celui-ci (à l'intérieur d'une fonction par exemple), on parle de
portée (ou visibilité) d'une variable.
Lorsqu'une variable est déclarée dans le code même, c'est-à-dire à l'extérieur de toute fonction ou de
tout bloc d'instructions, elle est accessible de partout dans le code (n'importe quelle fonction du
programme peut faire appel à cette variable). On parle alors de variable globale
Lorsque l'on déclare une variable à l'intérieur d'un bloc d'instructions (entre des accolades), sa portée se
confine à l'intérieur du bloc dans lequel elle est déclarée.
Une variable déclarée au début du code, c'est-à-dire avant tout bloc de donnée, sera globale, on
pourra alors les utiliser à partir de n'importe quel bloc d'instructions
Une variable déclarée à l'intérieur d'un bloc d'instructions (dans une fonction ou une boucle par
exemple) aura une portée limitée à ce seul bloc d'instructions, c'est-à-dire qu'elle est inutilisable
ailleurs, on parle alors de variable locale
D'une manière générale il est préférable de donner des noms différents aux variables locales et
globales pour des raisons de lisibilité et de compréhension du code.
Définition de constantes
Une constante est une variable dont la valeur est inchangeable lors de l'exécution d'un programme. Avec
PHP, les constantes sont définies grâce à la fonction define(). la syntaxe de la fonction define() est la
suivante:
define("Nom_de_la_variable", Valeur);
Le nom d'une constante définie à l'aide de la fonction define() ne doit pas commencer par le
caractère $ (de cette façon aucune affectation n'est possible).
Les opérateurs sont des symboles qui permettent de manipuler des variables, c'est-à-dire effectuer des
opérations, les évaluer, ...
On distingue plusieurs types d'opérateurs:
Résultat
Opérateur Dénomination Effet Exemple
(pour x=7)
+ opérateur d'addition Ajoute deux valeurs $x+3 10
opérateur de
- Soustrait deux valeurs $x-3 4
soustraction
opérateur de
* Multiplie deux valeurs $x*3 21
multiplication
plus: opérateur de
/ Divise deux valeurs $x/3 2.3333333
division
opérateur Met la valeur 3 dans la
= Affecte une valeur à une variable $x=3
d'affectation variable $x
Donne le reste de la division entière
% opérateur modulo $x%3 1
entre 2 nombres
Les opérateurs d'assignation
Ces opérateurs permettent de simplifier des opérations telles que ajouter une valeur dans une variable et
stocker le résultat dans la variable. Une telle opération s'écrirait habituellement de la façon suivante par
exemple: $x=$x+2
Avec les opérateurs d'assignation il est possible d'écrire cette opération sous la forme suivante: $x+=2
Ainsi, si la valeur de x était 7 avant opération, elle sera de 9 après...
Opérateur Effet
+= addition deux valeurs et stocke le résultat dans la variable (à gauche)
-= soustrait deux valeurs et stocke le résultat dans la variable
*= multiplie deux valeurs et stocke le résultat dans la variable
/= divise deux valeurs et stocke le résultat dans la variable
%= donne le reste de la division deux valeurs et stocke le résultat dans la variable
|= Effectue un OU logique entre deux valeurs et stocke le résultat dans la variable
Effectue un OU exclusif entre deux valeurs et stocke le résultat dans la
^=
variable
&= Effectue un Et logique entre deux valeurs et stocke le résultat dans la variable
.= Concatène deux chaînes et stocke le résultat dans la variable
Les opérateurs d'incrémentation
Ce type d'opérateur permet de facilement augmenter ou diminuer d'une unité une variable. Ces
opérateurs sont très utiles pour des structures telles que des boucles, qui ont besoin d'un compteur
(variable qui augmente de un en un).
Un opérateur de type $x++ permet de remplacer des notations lourdes telles que $x=$x+1 ou bien
$x+=1
Si vous ne comprenez pas ces opérateurs cela n'est pas important, vous n'en aurez probablement pas
l'utilité. Pour ceux qui voudraient comprendre, rendez- vous aux chapitres suivants:
compréhension du binaire
représentation des données
Instructions arithmétiques et logiques en assembleur
Ce type d'opérateur traite ses opérandes comme des données binaires, plutôt que des données
décimales, hexadécimales ou octales. Ces opérateurs traitent ces données selon leur représentation
binaire mais retournent des valeurs numériques standard dans leur format d'origine.
Les opérateurs suivants effectuent des opérations bit-à-bit, c'est-à-dire avec des bits de même
poids.
Si vous ne comprenez pas ces opérateurs cela n'est pas important, vous n'en aurez probablement pas
l'utilité. Pour ceux qui voudraient comprendre, rendez- vous aux chapitres suivants:
compréhension du binaire
représentation des données
Instructions arithmétiques et logiques en assembleur
Ce type d'opérateur traite ses opérandes comme des données binaires d'une longueur de 32 bits, plutôt
que des données décimales, hexadécimales ou octales. Ces opérateurs traitent ces données selon leur
représentation binaire mais retournent des valeurs numériques standards dans leur format d'origine.
Les opérateurs ne peuvent pas être classés dans une catégorie spécifique mais ils ont tout de
même chacun leur importance!
Opérateur Dénomination Effet Syntaxe Résultat
"Bonjour"."Au "BonjourAu
. Concaténation Joint deux chaînes bout à bout
revoir" revoir"
Référencement de
$ Permet de définir une variable $MaVariable = 2;
variable
Permet d'accéder aux données $MonObjet-
-> Propriété d'un objet
membres d'une classe >Propriete
Les priorités
Lorsque l'on associe plusieurs opérateurs, il faut que l'interprêteur PHP sache dans quel ordre les traiter,
voici donc dans l'ordre décroissant les priorités de tous les opérateurs:
On appelle structure conditionnelle les instructions qui permettent de tester si une condition est vraie
ou non, c'est-à-dire si la valeur de son expression vaut 0 ou 1 (le PHP associe le mot clé true à 1 et false
à 0). Ces structures conditionnelles peuvent être associées à des structures qui se répètent suivant la
réalisation de la condition, on appelle ces structures des structures de boucle
La notion de bloc
Une expression suivie d'un point-virgule est appelée instruction. Par exemple a++; est une instruction.
Lorsque l'on veut regrouper plusieurs instructions, on peut créer ce que l'on appelle un bloc, c'est-à-dire
un ensemble d'instructions (suivies respectivement par des point-virgules) et comprises entre les
accolades { et }.
Les instructions if, while et for peuvent par exemple être suivies d'un bloc d'instructions à
exécuter...
L'instruction if
L'instruction if est la structure de test la plus basique, on la retrouve dans tous les langages (avec une
syntaxe différente...). Elle permet d'exécuter une série d'instruction si jamais une condition est réalisée.
if (condition réalisée) {
liste d'instructions
Remarques:
L'instruction if dans sa forme basique ne permet de tester qu'une condition, or la plupart du temps on
aimerait pouvoir choisir les instructions à exécuter en cas de non réalisation de la condition...
L'expression if ... else permet d'exécuter une autre série d'instruction en cas de non-réalisation de la
condition.
if (condition réalisée) {
liste d'instructions
}
else {
L'instruction if ... else ne permet de tester qu'une condition, or il est parfois nécessaire de tester
plusieurs conditions de façon exclusive, c'est-à-dire que sur toutes les conditions une seule sera
réalisée ...
L'expression if ... elseif ... else permet d'enchaîner une série d'instructions et évite d'avoir à imbriquer
des instructions if.
if (condition réalisée) {
liste d'instructions
...
série d'instructions
Il est possible de faire un test avec une structure beaucoup moins lourde grâce à la structure suivante,
appelée opérateur ternaire:
Remarques:
L'instruction switch permet de faire plusieurs tests de valeurs sur le contenu d'une même variable. Ce
branchement conditionnel simplifie beaucoup le test de plusieurs valeurs d'une variable, car cette
opération aurait été compliquée (mais possible) avec des if imbriqués. Sa syntaxe est la suivante:
switch (Variable) {
case Valeur1:
Liste d'instructions
break;
case Valeur2:
Liste d'instructions
break;
case Valeurs...:
Liste d'instructions
break;
default:
Liste d'instructions
break;
Les parenthèses qui suivent le mot clé switch indiquent une expression dont la valeur est testée
successivement par chacun des case. Lorsque l'expression testée est égale à une des valeurs suivant un
case, la liste d'instructions qui suit celui-ci est exécutée. Le mot clé break indique la sortie de la structure
précède la liste d'instructions qui sera exécutée si l'expression
conditionnelle. Le mot clé default
n'est jamais égale à une des valeurs.
N'oubliez pas d'insérer des instructions break entre chaque test, ce genre d'oubli est difficile à
détecter car aucune erreur n'est signalée...
Les boucles
Les boucles sont des structures qui permettent d'exécuter plusieurs fois la même série d'instructions
jusqu'à ce qu'une condition ne soit plus réalisée...
On appelle parfois ces structures instructions répétitives ou bien itérations.
La façon la plus commune de faire une boucle, est de créer un compteur (une variable qui
s'incrémente, c'est-à-dire qui augmente de 1 à chaque tour de boucle) et de faire arrêter la
boucle lorsque le compteur dépasse une certaine valeur.
La boucle for
L'instruction for permet d'exécuter plusieurs fois la même série d'instructions: c'est une boucle!
Dans sa syntaxe, il suffit de préciser le nom de la variable qui sert de compteur (et éventuellement sa
valeur de départ, la condition sur la variable pour laquelle la boucle s'arrête (basiquement une condition
qui teste si la valeur du compteur dépasse une limite) et enfin une instruction qui incrémente (ou
décrémente) le compteur.
liste d'instructions
Par exemple:
for ($i=1; $i<6; $i++) {
echo "$i<br>";
D'autre part, le langage PHP autorise la déclaration de la variable de boucle dans l'instruction for elle-
même!
Par exemple:
echo "$i<br>";
il faudra toujours vérifier que la boucle a bien une condition de sortie (i.e le compteur
s'incrémente correctement)
une instruction echo dans votre boucle est un bon moyen pour vérifier la valeur du
compteur pas à pas en l'affichant!
il faut bien compter le nombre de fois que l'on veut faire exécuter la boucle:
o for($i=0;$i<10;$i++) exécute 10 fois la boucle ($i de 0 à 9)
o for($i=0;$i<=10;$i++) exécute 11 fois la boucle ($i de 0 à 10)
o for($i=1;$i<10;$i++) exécute 9 fois la boucle ($i de 1 à 9)
o for($i=1;$i<=10;$i++) exécute 10 fois la boucle ($i de 1 à 10)
L'instruction while
L'instruction while représente un autre moyen d'exécuter plusieurs fois la même série d'instructions.
liste d'instructions
Cette instruction exécute la liste d'instructions tant que (while est un mot anglais qui signifie tant que)
la condition est réalisée.
La condition de sortie pouvant être n'importe quelle structure conditionnelle, les risques de
boucle infinie (boucle dont la condition est toujours vraie) sont grands, c'est-à-dire qu'elle risque
de provoquer un plantage du navigateur!
Saut inconditionnel
Il peut être nécessaire de faire sauter à la boucle une ou plusieurs valeurs sans pour autant mettre fin à
celle-ci.
La syntaxe de cette expression est "continue;" (cette instruction se place dans une boucle!), on l'associe
généralement à une structure conditionnelle, sinon les lignes situées entre cette instruction et la fin de la
boucle seraient obsolètes.
Exemple: Imaginons que l'on veuille imprimer pour $x allant de 1 à 10 la valeur de 1/($x-7) ... il est
évident que pour $x=7 il y aura une erreur. Heureusement, grâce à l'instruction continue il est possible
de traiter cette valeur à part puis de continuer la boucle!
$x=1;
while ($x<=10) {
if ($x == 7) {
continue;
$a = 1/($x-7);
echo "$a<br>";
$x++;
$x=1;
while ($x<=10) {
if ($x == 7) {
$x++;
continue;
$a = 1/($x-7);
echo "$a<br>";
$x++;
Arrêt inconditionnel
A l'inverse, il peut être voulu d'arrêter prématurément la boucle, pour une autre condition que celle
précisé dans l'en-tète de la boucle. L'instruction break permet d'arrêter une boucle (for ou bien while). Il
s'agit, tout comme continue, de l'associer à une structure conditionnelle, sans laquelle la boucle ne ferait
jamais plus d'un tour!
Dans l'exemple de tout à l'heure, par exemple si l'on ne savait pas à quel moment le dénominateur ($x-
7) s'annule (bon...OK...pour des équations plus compliquées par exemple) il serait possible de faire
arrêter la boucle en cas d'annulation du dénominateur, pour éviter une division par zéro!
for ($x=1; $x<=10; $x++) {
$a = $x-7;
if ($a == 0) {
break;
echo "1/$a<br>";
PHP autorise l'utilisation de la commande exit, qui permet d'interrompre totalement l'interprétation du
script, ce qui signifie que le serveur n'envoie plus d'informations au navigateur: le script est figé dans
son état actuel. cette instruction est particulièrement utile lors de l'apparition d'erreur!
La notion de fonction
On appelle fonction un sous-programme qui permet d'effectuer un ensemble d'instructions par simple
du programme principal. Les fonctions permettent d'exécuter
appel de la fonction dans le corps
dans plusieurs parties du programme une série d'instructions, cela permet une simplicité du
code et donc une taille de programme minimale. D'autre part, une fonction peut faire appel à
elle-même, on parle alors de fonction récursive (il ne faut pas oublier de mettre une condition
de sortie au risque sinon de ne pas pouvoir arrêter le programme...).
PHP recèle de nombreuses fonctions intégrées permettant d'effectuer des actions courantes. Toutefois, il
est possible de définir des fonctions, dites fonctions utilisateurs afin de simplifier l'exécution de séries
d'instructions répétitives. Contrairement à de nombreux autres langages, PHP nécessite que l'on
définisse une fonction avant que celle-ci puisse être utilisée, car pour l'appeler dans le corps du
programme il faut que l'interpréteur la connaisse, c'est-à-dire qu'il connaisse son nom, ses arguments et
les instructions qu'elle contient. La définition d'une fonction s'appelle "déclaration" et peut se faire
n'importe où dans le code. La déclaration d'une fonction se fait grâce au mot-clé function, selon la
syntaxe suivante:
liste d'instructions
Remarques:
le nom de la fonction suit les mêmes règles que les noms de variables:
o le nom doit commencer par une lettre
o un nom de fonction peut comporter des lettres, des chiffres et les caractères _ et & (les
espaces ne sont pas autorisés!)
o le nom de la fonction, comme celui des variables est sensible à la casse (différenciation
entre les minuscules et majuscules)
Les arguments sont facultatifs, mais s'il n'y a pas d'arguments, les parenthèses doivent rester
présentes
Il ne faut pas oublier de refermer les accolades
Le nombre d'accolades ouvertes (fonction, boucles et autres structures) doit être égal au
nombre d'accolades fermées!
La même chose s'applique pour les parenthèses, les crochets ou les guillemets!
Une fois cette étape franchie, votre fonction ne s'exécutera pas tant que l'on ne fait pas appel à
elle quelque part dans la page!
Appel de fonction
Pour exécuter une fonction, il suffit de faire appel à elle en écrivant son nom (une fois de plus en
respectant la casse) suivie d'une parenthèse ouverte (éventuellement des arguments) puis d'une
parenthèse fermée:
Nom_De_La_Fonction();
Remarques:
le point virgule signifie la fin d'une instruction et permet à l'interpréteur de distinguer les
différents blocs d'instructions
si jamais vous avez défini des arguments dans la déclaration de la fonction, il faudra veiller à les
inclure lors de l'appel de la fonction (le même nombre d'arguments séparés par des virgules!)
Nom_De_La_Fonction(argument1, argument2);
Renvoi d'une valeur par une fonction
La fonction peut renvoyer une valeur (et donc se terminer) grâce au mot-clé return. Lorsque l'instruction
return est rencontrée, la fonction évalue la valeur qui la suit, puis la renvoie au programme appelant
(programme à partir duquel la fonction a été appelée).
Une fonction peut contenir plusieurs instructions return, ce sera toutefois la première instruction return
rencontrée qui provoquera la fin de la fonction et le renvoi de la valeur qui la suit.
return valeur_ou_variable;
Il est possible de passer des arguments à une fonction, c'est-à-dire lui fournir une valeur ou le nom
d'une variable afin que la fonction puisse effectuer des opérations sur ces arguments ou bien grâce à ces
arguments.
Le passage d'arguments à une fonction se fait au moyen d'une liste d'arguments (séparés par des
virgules) entre parenthèses suivant immédiatement le nom de la fonction. Les arguments peuvent être
de simple variables, mais aussi des tableaux ou des objets. A noter qu'il est possible de donner une
valeur par défaut à ces arguments en faisant suivre le nom de la variable par le signe "=" puis la valeur
que l'on affecte par défaut à la variable.
Lorsque vous voulez utiliser un argument dans le corps de la fonction en tant que variable, celui-ci doit
être précédé par le signe $.
<?
function dire_texte($qui, $texte = 'Bonjour')
return false;
}else{
?>
<?
?>
Lorsque vous manipulerez des variables dans des fonctions, il vous arrivera de constater que vous avez
beau modifier la variable dans la fonction celle-ci retrouve sa valeur d'origine dès que l'on sort de la
fonction...
Cela est du à la portée des variables, c'est-à-dire si elles ont été définies comme variables globales ou
locales.
Il existe plusieurs niveaux de définition de variables :
Une variable précédée du mot clé global sera visible dans l'ensemble du code, c'est-à-dire que
sa portée ne sera pas limitée à la fonction seulement. Ainsi, toutes les fonctions pourront utiliser
et modifier cette même variable
Le niveau static permet de définir une variable locale à la fonction, qui persiste durant tout le
temps d'exécution du script
Par défaut, la variable possède le niveau local, c'est-à-dire que la variable ne sera modifiée qu'à
l'intérieur de la fonction et retrouvera la valeur qu'elle avait juste avant l'appel de fonction à la
sortie de celle-ci
<?
function ajoute_camion($mode='')
global $chaine;
static $nb=0;
if($mode == "affiche"){
ajoute_camion(); // nb == 1
ajoute_camion(); // nb == 2
ajoute_camion(); // nb == 3
?>
Une autre méthode pour modifier une variable consiste à la faire précéder du caractère &, précisant qu'il
s'agit alors d'un alias: la valeur de la variable est modifiée à la sortie de la fonction. On parle alors de
passage par référence. Dans ce cas on passe la référence (adresse mémoire) de la variable à la fonction,
ce qui permet de modifier sa valeur.
<?
}
$chaine = "Bonjour ";
dire_texte("cher phpeur",$chaine);
?>
Lorsque vous souhaitez qu'une fonction retourne plusieurs valeurs, le plus simple est d'utiliser un
tableau.
<?
function nom_fonction()
.....
$retour = nom_fonction();
?>
La récursivité
Les fonctions récursives sont des fonctions qui s'appellent elles-mêmes. Ce type de fonction se révéle
indispensable pour parcourir une arborescence par exemple.
Voici un exemple simple.
<?
function fonction_recursive($n=0)
$n++;
fonction_recursive($n);
La notion de classe
Php3 intègre un soupçon de caractéristiques empruntées aux langages orientés objet, c'est-à-dire la
possibilité d'utiliser des objets, entités regroupant des données et des fonctions au sein d'une structure
et rendant la programmation plus simple qu'en programmation habituelle (appelée programmation
procédurale par opposition à la programmation orientée objet).
On appelle classe la structure d'un objet, c'est-à-dire la déclaration de l'ensemble des entités qui
composeront un objet. Un objet est donc "issu" d'une classe, c'est le produit qui sort d'un moule. En
réalité on dit qu'un objet est une instanciation d'une classe, c'est la raison pour laquelle on pourra
parler indifféremment d'objet ou d'instance (éventuellement d'occurrence).
Les attributs (parfois appelés données membres): il s'agit des données représentant l'état de
l'objet
Les méthodes (parfois appelées fonctions membres): il s'agit des opérations applicables
aux objets
déclaration d'une classe
Pour pouvoir manipuler des objets, il est essentiel de définir des classes, c'est-à-dire définir la structure
d'un objet. Avec Php, cette définition se fait de la manière suivante:
class Nom_de_la_classe {
var $Donnee_Membre_1;
var $Donnee_Membre_2;
var $...
function Nom_de_la_fonction_membre1(parametres) {
liste d'instructions;
Nom_de_la_classe représente bien évidemment le type d'objet désigné par la classe ou du moins le nom
que vous leur attribuez.
Contrairement aux langages orientés objet comme le C++, Php n'inclut pas dans sa version 3 de niveaux
de visibilité des éléments de la classe, il n'y a donc pas de concept d'encapsulation, un des concepts
majeurs de la programmation orientée objet.
Instanciation de la classe
Après avoir déclaré une classe, il faut instancier des objets pour pouvoir l'exploiter. Cette opération se
fait à l'aide du mot clé new permettant de faire des objets découlant d'une classe. La syntaxe du mot clé
new est la suivante:
A partir du moment où l'objet est instancié, il possède des propriétés qui lui sont propres, cela signifie
que si vous instanciez un nouvel objet, la modification des propriétés de l'un n'influera aucunement sur
celles de l'autre.
Il existe une méthode spéciale (portant le même nom que la classe) s'exécutant automatiquement lors
de l'instanciation de l'objet. Cette méthode, appelée constructeur est très utile pour initialiser les
données membres lors de l'instanciation.
L'accès aux propriétés d'un objet se fait grâce au nom de l'objet, suivi d'une flêche (->) représentée par
un moins (-) et un signe supérieur (>), puis du nom de la donnée membre (sans le signe $). Par
exemple:
$Nom_de_l_objet->Nom_de_la_donnee_membre = Valeur;
L'accès aux méthodes d'un objet se fait comme pour l'accès aux propriétés, c'est-à-dire par le nom de
l'objet, suivi d'une flêche et du nom de la méthode. La méthode est suivie de parenthèses, contenant les
paramètres, si il y'en a. L'accès à une méthode se fait donc de la façon suivante:
$Nom_de_l_objet->Nom_de_la_fonction_membre(parametre1,parametre2,...);
Le mot clé $this permet de désigner l'objet dans lequel on se trouve, c'est-à-dire que lorsque l'on désire
faire référence dans une fonction membre à l'objet dans lequel elle se trouve, on utilise this.
Grâce à cette variable spéciale, il est possible dans une fonction membre de faire référence aux
propriétés situées dans le même objet que la fonction membre.
Ainsi, lorsque l'on désire accéder à une propriété d'un objet à partir d'une méthode du même objet, il
suffit de faire précéder le nom de la donnée membre par $this->. Par exemple:
class Toto{
var $age;
var $sexe;
var $adresse;
function DefineTotoAge($Age){
$this->age = $Age;
PHP, dans sa version 3, reste assez limité du point de vue de la programmation objet. La plupart des
aspects marquants de la programmation objet ne sont pas présents dans le langage:
l'encapsulation
l'héritage
le polymorphisme
Le but de PHP est de permettre la création de pages web dynamiques, ainsi son but premier
est de pouvoir envoyer des données au navigateur.
PHP fournit 3 fonctions permettant d'envoyer du texte au navigateur. Ces fonctions ont la particularité de
pouvoir insérer dans les données envoyées des valeurs variables, pouvant être fonction d'une valeur
récupérée par exemple, c'est ce qui rend possible la création de pages dynamiques. Les 3 fonctions sont
les suivantes:
echo
print
printf
La fonction echo
La fonction echo permet d'envoyer au navigateur la chaîne de caractères (délimitée par des guillemets)
qui la suit. La syntaxe de cette fonction est la suivante:
echo Expression;
L'expression peut être une chaîne de caractères ou une expression que l'interpréteur évalue
echo "Chaine de caracteres";
echo (1+2)*87;
Ainsi, étant donné que la chaîne de caractères est délimitée par des guillemets, l'insertion de
guillemets doubles dans la chaîne provoquerait une erreur. C'est la raison pour laquelle les
guillemets doubles, ainsi que tous les caractères spéciaux, doivent être précédés d'un
antislash. Voici un récapitulatif des caractères spéciaux nécessitant l'ajout d'un antislash:
Caractère Description
\" guillemet
\$ caractère $
\\ barre oblique inverse (antislash)
\r retour chariot
\n retour à la ligne
\t tabulation
Le caractère $ a un rôle particulier dans la mesure où l'interpréteur le comprend comme une variable, ce
qui signifie que lorsque le caractère $ est rencontré dans la chaîne qui suit la fonction echo, l'interpréteur
récupère le nom de la variable qui suit le caractère $ et le remplace par sa valeur. Dans l'exemple
suivant par exemple, on assigne la date actuelle à une variable appelée $MaDate, puis on l'affiche sur le
navigateur:
<HTML>
<HEAD>
<TITLE>Affichage de l'heure</TITLE>
</HEAD>
<BODY>
<?
// Récupération de la date
$MaDate = date("Y");
?>
</BODY>
</HTML>
La fonction print
La fonction print est similaire à la fonction echo à la différence près que l'expression à afficher est entre
parenthèses. La syntaxe de la fonction print est la suivante:
print(expression);
L'expression peut, comme pour la fonction echo être une chaîne de caractères ou une expression que
l'interpréteur évalue:
print("Chaine de caracteres");
print ((1+2)*87);
La fonction printf
La fonction printf() (empruntée au langage C) est rarement utilisée car sa syntaxe est plus lourde.
Toutefois, contrairement aux deux fonctions précédentes, elle permet un formatage des données, cela
signifie que l'on peut choisir le format dans lequel une variable sera affichée à l'écran.
La syntaxe de printf() est la suivante:
Une chaîne formattée est une chaîne contenant des codes spéciaux permettant de repérer l'emplacement
d'une valeur à insérer et son format, c'est-à-dire sa représentation. A chaque code rencontré doit être
associé une valeur ou une variable, que l'on retrouve en paramètre à la fin de la fonction printf.
Les
valeurs à insérer dans la chaîne formattées sont séparées par des virgules et doivent apparaître
dans l'ordre où les codes apparaissent dans la chaîne formattée Les codes de formatage des
types de données sont les suivants:
Imaginons que l'on définisse une variable en virgule flottante, afin d'obtenir une précision de calcul plus
grande qu'avec un entier, mais qu'on désire l'afficher en tant qu'entier. Dans ce cas la fonction printf
prend toute son importance:
$Pi = 3.1415927;
$R = 24.546;
Le code PHP peut être implanté au sein du code HTML. Cette caractéristique n'est pas à négliger car le
fait d'écrire uniquement du code PHP là où il est nécessaire rend la programmation plus simple (il est
plus simple d'écrire du code HTML que des fonctions echo ou print, dans lesquelles les caractères
spéciaux doivent être précédés d'un antislash sous peine de voir des erreurs lors de l'exécution).
L'exemple le plus simple concerne les pages dynamiques dont l'en-tête est toujours le même: dans ce
cas, le code PHP peut ne commencer qu'à partir de la balise <BODY>, au moment où la page peut
s'afficher différemment selon une variable par exemple.
Mieux, il est possible d'écrire plusieurs portions de script en PHP, séparées par du code HTML statique car
les variables/fonctions déclarées dans une portion de script seront accessibles dans les portions de
scripts inférieures.
Les variables d'environnement sont, comme leur nom l'indique, des données stockées dans des variables
permettant au programme d'avoir des informations sur son environnement. L'environnement, dans le cas
du script PHP est:
Le serveur
Le client
Ces variables sont créées par le serveur à chaque fois que le script PHP est appelé, le serveur les lui
fournit en paramètres cachés lors de l'exécution de l'interpréteur.
Elles permettent notamment d'avoir des informations sur le type de serveur, son
administrateur, la date à laquelle le script a été appelé, l'adresse IP et le type de navigateur du
client,...
Il est possible de créer un script permettant de visualiser l'ensemble des variables d'environnement.
La première façon consiste à utiliser la fonction phpinfo() qui affiche toute seule un tableau récapitulatif
des paramètres du serveur et de l'intepréteur PHP, ainsi qu'un tableau des variables d'environnement
<?
phpinfo();
?>
PHP fournit la fonction getenv() permettant de retourner la valeur de la variable d'environnement passée
en paramètre:
<?
echo getenv("HTTP_USER_AGENT");
?>
<?
echo putenv("MA_VARIABLE=mavaleur");
?>
Avec PHP, la création ou la lecture de fichiers est, une fois de plus, assez simple. Il existe une
multitude de fonctions dédiées à l'utilisation des fichiers. La communication entre le script
PHP et le fichier est repérée par une variable, indiquant l'état du fichier et que l'on peut passer
en paramètre aux fonctions spécialisées pour le manipuler.
La fonction fopen()
La fonction de base est la fonction fopen(). C'est elle qui permet d'ouvrir un fichier, que ce soit pour le
lire, le créer, ou y écrire. Voilà sa syntaxe :
Le mode indique le type d'opération qu'il sera possible d'effectuer sur le fichier après ouverture. Il s'agit
d'une lettre (en réalité une chaîne de caractères) indiquant l'opération possible:
w ouverture en écriture seulement (la fonction crée le fichier s'il n'existe pas)
ouverture en écriture seulement avec ajout du contenu à la fin du fichier (la fonction crée le fichier
a
s'il n'existe pas)
w+ ouverture en lecture et écriture (la fonction crée le fichier s'il n'existe pas)
ouverture en lecture et écriture avec ajout du contenu à la fin du fichier (la fonction crée le fichier
a+
s'il n'existe pas)
$fp = fopen("ftp://phpfrance.com/pub/fichier.txt","w");
$fp = fopen("http://igalaxie.com/fichier.txt","a");
De plus, la fonction fopen permet d'ouvrir des fichiers présents sur le web grâce à leur URL. Voici un
script permettant de récupérer le contenu d'une page d'un site web:
<?
?>
Il est généralement utile de tester si l'ouverture de fichier s'est bien déroulée ainsi que d'éventuellement
stopper le script PHP si cela n'est pas le cas:
<?
if (!$fp = fopen("http://www.commentcamarche.net","r")) {
exit;
else {
// votre code;
?>
Un fichier ouvert avec la fonction fopen() doit être fermé, à la fin de son utilisation, par la
fonction fclose() en lui passant en paramètre l'entier retourné par la fonction fopen()
Lecture et écriture
Une fois que le fichier a été ouvert avec le mode désiré, il est possible de lire son contenu et d'y écrire
des informations grâce aux fonctions:
fputs() (aussi parfois appelée fwrite(), les deux noms sont équivalents, on parle d'alias)
permettant d'écrire une chaîne de caractères dans le fichier
entier fputs(entier Etat_du_fichier, chaine Sortie);
La fonction fputs() renvoie le nombre de caractères effectivement écrits dans le fichier
fgets() permettant de récupérer une ligne du fichier
chaîne fgets(entier Etat_du_fichier, entier Longueur);
Le paramètre Longueur désigne le nombre de caractères maximum que la fonction est sensée
récupérer sur la ligne. La fonction fgets() renvoie 0 en cas d'échec, la chaîne dans le cas
contraire
Etant donné que la fonction fgets() récupère à chaque appel une nouvelle ligne du fichier, il est essentiel,
pour récupérer l'intégralité du contenu d'un fichier de l'insérer dans une boucle while.
Ainsi, on utilise la fonction feof(), fonction testant si la fin du fichier n'a pas été atteinte, en tant que
test de la boucle while. De cette façon, tant que la fin du fichier n'a pas été atteinte, on lit la ligne
suivante du fichier...
<?
if (!$fp = fopen("fichier.txt","r")) {
exit;
else {
while(!feof($fp)) {
// On récupère une ligne
$Ligne = fgets($fp,255);
// On affiche la ligne
echo $Ligne;
$Fichier .= $Ligne;
?>
Pour stocker des infos dans le fichier, il faut dans un premier temps ouvrir le fichier en écriture en le
créant si il n'existe pas. On a donc le choix entre le mode 'w' et le mode 'a'. On préférera le second
puisque le pointeur se trouve en fin de fichier (autrement dit on écrit à la suite de ce qui se trouve dans
le fichier au lieu d'écraser le contenu existant éventuellement déjà).
<?
fclose($fp);
?>
Voici un petit script permettant de récupérer le titre d'une page Web (le texte compris entre les balises
<TITLE> et </TITLE>). Il utilise les expressions régulières pour localiser le texte.
<?
echo $regs[1];
fclose($fp);
?>
PHP fournit de nombreuses fonctions permettant de faire des tests sur les fichiers pour connaître leurs
propriétés. Voici la liste des fonctions des tests:
is_dir() permet de savoir si le fichier dont le nom est passé en paramètre correspond à un
répertoire
booléen is_dir(chaine Nom_du_fichier);
La fonction is_dir() renvoie 1 si il s'agit d'un répertoire, 0 dans le cas contraire
<?
if (!is_dir("install")) {
else {
?>
is_executable() permet de savoir si le fichier dont le nom est passé en paramètre est
exécutable
booléen is_executable(chaine Nom_du_fichier);
La fonction is_executable() renvoie 1 si le fichier est exécutable, 0 dans le cas contraire
is_file() permet de savoir si le fichier dont le nom est passé en paramètre ne correspond ni à
un répertoire, ni à un lien symbolique
booléen is_file(chaine Nom_du_fichier);
La fonction is_file() renvoie 1 si il s'agit d'un fichier, 0 dans le cas contraire
is_link() permet de savoir si le fichier dont le nom est passé en paramètre correpond à un lien
symbolique
booléen is_link(chaine Nom_du_fichier);
La fonction is_link() renvoie 1 si il s'agit d'un lien symbolique, 0 dans le cas contraire
D'autres façons de lire et écrire
Dans certains cas, il peut être rébarbatif de devoir mettre en oeuvre les fonctions fopen() et fgets pour
lire l'intégralité du contenu d'un fichier. Pour cette raison PHP fournit des fonctions supplémentaires
permettant de faire directement certaines opérations.
La fonction file() permet de retourner dans un tableau l'intégralité d'un fichier en mettant chacune de
ces lignes dans un élément du tableau (rappel: le premier élément d'un tableau est repéré par l'indice 0).
Voilà sa syntaxe :
L'exemple suivant montre comment parcourir l'ensemble du tableau afin d'afficher le fichier.
<?
$Fichier = "fichier.txt";
if (is_file($Fichier)) {
if ($TabFich = file($Fichier)) {
else {
else {
?>
<?
function ScanDir($Directory){
if($MyDirectory = opendir($Directory)) {
while($Entry = readdir($MyDirectory)) {
if (is_dir($Directory."/".$Entry)) {
else {
$MetaTags = get_meta_tags($Directory."/".$Entry);
}
closedir($MyDirectory);
$open_basedir=".";
echo "<ul>";
ScanDir(".");
echo "</ul>";
?>
</BODY>
</HTML>
PHP rend très simple la récupération de données envoyées par l'intermédiaire de formulaires HTML.
Grâce à la balise FORM du langage HTML, il est très simple de créer des formulaires comprenant:
Voici ce à quoi peut ressembler un formulaire en HTML, permettant d'envoyer les coordonnées d'une
personne à un fichier PHP nommé test.php3:
Le résultat de ce code est le suivant (le bouton Envoyer est volontairement désactivé):
Nom :
Prénom :
Age :
Les variables globales peuvent être activées ou désactivées selon la configuration du serveur, ce qui
détermine la façon dont on pourra récupérer les informations des formulaires.
Pour connaitre leur statut sur le serveur PHP que vous utilisez, il vous suffit de créer une page contenant
uniquement ce code, et de la télécharger sur votre serveur :
<?php
phpinfo();
?>
Ouvrez ensuite ce fichier situé sur le serveur et observez la ligne register_globals, et vous verrez inscrit
en face ON ou OFF (activé ou désactivé).
Pour des raisons de sécurité, depuis la version 4.2.0 de PHP, les variables globales sont
désctivées par défaut. Cependant, l'administrateur du serveur peut changer cette option.
Si les variables globales sont activées, chaque donnée (valeur saisie dans le champ) transmise par
formulaire est directement passée dans une variable (intitulée comme l'attribut NAME du champ).
$nom = 'le_contenu_du_champ_nom'
$prenom = 'le_contenu_du_champ_prenom'
$age = 'le_contenu_du_champ_age'
$afficher = 'ok'
<HTML>
<HEAD>
<TITLE>Affichage des résultats</TITLE>
<BODY>
<?php
echo $nom;
echo '<br>'
echo $prenom;
echo '<br>';
echo $age;
echo '<br>'
echo $afficher;
?>
</BODY>
</HTML>
Néanmoins, pour des raisons de sécurité, il est conseillé de toujours faire comme si les variables
globales étaient désactivées (décrit ci-dessous), même si elles sont actives.
La méthode qui suit est obligatoirement à utiliser si les variables globales sont désactivées sur votre
serveur; elle est toutefois également fortement recommandée, même si elles sont activées.
Vous ne récupérerez donc pas les informations directement par le biais d'une variable, mais via une
variable de type tableau.
Cette variable tiendra compte de la provenance de la donnée, et notamment si l'attribut METHOD du
formulaire est GET ou POST.
Voici les deux variables tableaux qu'il convient d'utiliser pour récupérer les données d'un formulaire.
(donnee correspond à l'attribut NAME du champ).
Variable Signification
$_POST['donnee'] S'utilise lorsque l'attribut METHOD du formulaire est POST.
S'emploie lorsque l'attribut METHOD du formulaire est GET ou bien lorsque
$_GET['donnee']
celui-ci n'est pas (ou pas correctement) spécifié.
Ce tableau récapitule les plus importants "modèles" de variables tableaux de PHP pour récupérer
diverses informations, autres que par un formulaire.
Variable Signification
S'utilise pour un paramètre passé à l'URL.
Par exemple, si on prend cette URL :
http://www.votresite.com/index.php?nom=dupont&prenom=jean
$_GET['donnee']
on aura ces variables :
$_GET['nom'] = 'dupont'
$_GET['prenom'] = 'jean'
S'emploie pour récupérer la valeur une variable de session
$_SESSION['la_variable']
(ici la_variable).
Récupérer la valeur d'un cookie.
$_COOKIE['nom_cookie']
(ici nom_cookie est le nom du cookie).
Récupération de la valeur d'une variable d'environnement.
$_ENV['la_variable']
(ici la_variable)
Récupérer la valeur d'une variable de fichier envoyée par un
$_FILES['la_variable']
formulaire.
$_SERVER['la_variable'] Récupérer la valeur d'une variable serveur
Si jamais un des champs du formulaire n'est pas rempli, il possède la valeur "", c'est-à-dire une chaîne
vide...
Voici, par exemple, ce à quoi pourrait ressembler le fichier test.php3, dont le but est uniquement
d'afficher les informations saisies par l'utilisateur à l'écran, ainsi que de vérifier que tous les champs ont
bien été remplis (si le champ hidden "enregistrer" est égal à ok) :
<HTML>
<HEAD>
<TITLE>Test.php3: Affichage des données utilisateur</TITLE>
</HEAD>
<BODY>
<?php
if ($_POST['entregistrer']=="ok") {
if (($nom=="")||($prenom=="")||($age=="")){
if($nom=="") print("Veuillez saisir le nom de l'utilisateur<BR>\
n");
if($prenom=="") print("Veuillez saisir le prénom de
l'utilisateur<BR>\n");
if($age=="") print("Veuillez saisir l'age de l'utilisateur<BR>\n");
else {
}
}
else {
echo "<p>Vous n'avez pas demandé que les informations soient affichées.<p>"
}
?>
</BODY>
</HTML>
Php permet un interfaçage très simple avec un grand nombre de bases de données. Lorsqu'une base de
données n'est pas directement supportée par Php, il est possible d'utiliser un driver ODBC, pilote
standard pour communiquer avec les bases de données.
La communication avec les bases de données se fait à l'aide de requêtes SQL, un langage de quatrième
génération reconnu par l'ensemble des SGBD.
Dans les exemples ci-dessous, le système de gestion de bases de données utilisé est MySQL, un SGBD
gratuit et rapide fonctionnant (entre autres) sous Linux.
Etant donné que la majorité des serveurs
Web (dont le fameux serveur Apache) fonctionne sous Linux, MySQL est de ce fait le SGBD
le plus utilisé avec Php.
La première étape consiste à déclarer les variables qui vont permettre la connexion à la base de données
(ce sont les paramètres des fonctions de connexion à la base). Ces variables sont:
Ces variables sont en fait des paramètres de la fonction permettant la connexion à la base de
données. Il est donc possible de passer les valeurs de ces variables directement dans chaque
fonction permettant la connexion, mais cela devient vite gênant lors d'un changement de mot
de passe par exemple. Le comble de l'élégance voudrait que l'on stocke ces valeurs dans un
fichier à part, afin de changer les valeurs dans tous les fichiers y faisant référence en une seule
fois.
Php fournit un grand choix de fonctions permettant de manipuler les bases de données. Toutefois, parmi
celles-ci quatre fonctions sont essentielles:
Certaines de ces fonctions renvoient une valeur permettant de connaître l'état de la connexion, ainsi il
est possible d'interrompre le script afin d'éviter les erreurs en cascade. Deux méthodes permettent
d'effectuer cette opération:
Lorsque l'on effectue une requête de sélection de tuples à l'aide de la fonction mysql_query, il est
essentiel de stocker le résultat de la requête (les enregistrements) dans une variable, que l'on nomme
généralement $result.
Toutefois, cette variable contient l'ensemble des enregistrements et n'est donc pas exploitable telle
quelle. Ainsi on utilise la fonction mysql_fetch_row(), qui découpe les lignes de résultat en colonnes (par
exemple Nom,adresse,...) et les affecte à une variable tableau dans l'ordre où elles arrivent.
Ainsi, imaginons une table appelée liens contenant le nom et l'URL de sites internet. Il est possible de
récupérer l'ensemble des enregistrements et de les afficher dans un tableau:
<html>
<head>
<title>Liens</title>
</head>
<body>
<tr>
<th>Nom du site</th>
<th>URL</th>
</tr>
<?php
$host = la_machine;
$user = votre_login;
$bdd = Nom_de_la_base_de_donnees;
$passwd = Mot_de_passe;
// Connexion au serveur
$result = mysql_query($query);
while($row = mysql_fetch_row($result)){
$Nom = $row[0];
$Url = $row[1];
echo "<tr>\n
<td><a href=\"$Url\">$Nom</a></td>\n
<td>$Url</td>\n
</tr>\n";
mysql_close();
?>
</tr>
</table>
</body>
</html>
Dans l'exemple ci-dessus, les requête retournent les champs nom et url. La fonction mysql_fetch_row()
analyse donc chaque ligne de résultat de la requête et stocke les colonnes dans le tableau row[]. Ainsi, le
champ nom sera stocké dans row[0] et url dans row[1]. D'autre part, on inclue généralement
mysql_fetch_row() dans une boucle while de telle façon à ce que l'ensemble des lignes de résultat
soient traitées. Lorsqu'il n'y a plus de ligne à traiter, la boucle while se termine et l'interpréteur
exécute la suite des instructions.
Il peut être utile, avant d'insérer des données dans une table, de détecter la présence d'un
enregistrement dans une table, afin d'éviter de stocker des doublons. Cela peut se faire en effectuant
une requête SQL avec un ordre SELECT et une clause WHERE permettant de vérifier la présence ou non
d'enregistrements correspondant à la requête. La non présence de résultat se traduit par un retour nul
de la part de la fonction mysql_fetch_row(). Voici un exemple affichant le résultat d'une requête le cas
échéant, et dans le cas contraire une phrase expliquant qu'aucun enregistrement correspondant n'a été
trouvé (le code HTML dans lequel le code PHP doit être implanté a volontairement été omis):
<?php
$host = la_machine;
$user = votre_login;
$bdd = Nom_de_la_base_de_donnees;
$passwd = Mot_de_passe;
// Connexion au serveur
$result = mysql_query($query);
if (!mysql_fetch_row($result)) {
else {
while($row = mysql_fetch_row($result)){
$Nom = $row[0];
$Url = $row[1];
echo "<tr>\n
<td><a href=\"$Url\">$Nom</a></td>\n
<td>$Url</td>\n
</tr>\n";
mysql_close();
?>
Chapitre 13 : Expressions régulières
Les expressions régulières sont des modèles créés à l'aide de caractères ASCII permettant de manipuler
des chaînes de caractères, c'est-à-dire permettant de trouver les portions de la chaîne correspondant au
modèle. Ce système est emprunté au système POSIX (un système d'exploitation). De nombreux scripts
sous UNIX les utilisent (notamment Perl).
En réalité il s'agit d'un système fort ingénieux (et aussi très puissant) permettant de retrouver
un mot, ou une phrase (et même beaucoup d'autres choses en réalité) dans un texte,
ressemblant au modèle que l'on a construit...
Les expressions régulières permettent de rechercher des occurrences (c'est-à-dire une suite de
caractères correspondant à ce que l'on recherche) grâce à une série de caractères spéciaux. L'expression
régulière en elle-même est donc une chaîne de caractère contenant des caractères spéciaux et des
caractères standards...
Les symboles ^ et $ indiquent le début ou la fin d'une chaîne, et permettent donc de la délimiter.
Les symboles *, + et ?, respectivement "zero ou plusieurs", "un ou plusieurs", "un ou aucun", permettent
de donner une notions de nombre.
"abc+": chaîne qui contient "ab" suivie de un ou plusieurs "c" ("abc", "abcc" ...)
"abc*": chaîne qui contient "ab" suivie de zero ou plusieurs "c" ("ab", "abc" ...)
"abc?": chaîne qui contient "ab" suivie de zero ou un "c" ("ab" ou "abc")
"abc{2,}": chaîne qui contient "ab" suivie de deux "c" ou plus ("abcc" etc..)
A noter que le premier nombre de la limite ("{0,2}", mais pas "{,2}") est obligatoire. Les symboles vu
précedemment ('*', '+', and '?') sont équivalents à "{0,}", "{1,}", et "{0,1}".
Les crochets [ ] définissent une liste de caractères autorisés (ou interdits). Le signe - permet quand à lui
de définir un intervalle. Le caractère ^ après le premier crochet indique quand à lui une interdiction.
Pour rechercher un caractère faisant partie des caractères spéciaux, il suffit de le faire
précéder d'un antislash (sauf entre crochets)
un antislash doit donc être doublé!
En effet dans les crochets, chaque caractère représente ce qu'il est. Pour représenter un ] il faut le
mettre en premier (ou après un ^ si c'est une interdiction), un - se met en premier ou en dernier.
Voici un tableau récapitulatif des caractères spéciaux utilisés dans les expressions régulières:
Caractère Utilité
[] Les crochets définissent une liste de caractères autorisés
() Les parenthèses définissent un élément composé de l'expression régulière qu'elle contient
Les accolades lorsqu'elles contiennent un ou plusieurs chiffres séparés par des virgules
{} représentent le nombre de fois que l'élément précédant les accolades peut se reproduire (par
exemple p{3,5} correspond à ppp, pppp ou ppppp
Un moins entre deux caractères dans une liste représente un intervalle (par exemple [a-d]
-
représente [abcd])
. Le caractère point représente un caractère unique
* Le caractère astérisque indique la répétition indéterminée de l'élément la précédant
? Le caractère "point d'interrogation indique la présence éventuelle de l'élément la précédant
Occurrence de l'élément situé à gauche de cet opérateur ou de celui situé à droite (lard|
|
cochon)
Placé en début d'expression il signifie "chaîne commençant par .. "
^
Utilisé à l'intérieur d'une liste il signifie "ne contenant pas les caractères suivants...
$ Placé en fin d'expression il signifie "chaîne finissant par .. "
[:classe:]
Les classes de caractères sont celles définies par UNIX. Voici un tableau récapitulant
certaines de ces classes:
Nom de la classe Description
[:alnum:] caractères alphanumériques (équivalent à [A-Za-z0-9])
[:alpha:] caractères alphabétiques ([A-Za-z])
[:blank:] caractères blanc (espace, tabulation)
[:ctrl:] caractères de contrôle (les premiers du code ASCII
[:digit:] chiffre ([0-9])
[:graph:] caractère d'imprimerie (qui fait une marque sur l'écran en quelque sorte)
[:print:] caractère imprimable (qui passe à l'imprimante ... tout sauf les caractères de contrôle)
[:punct:] caractère de ponctuation
[:space:] caractère d'espacement
[:upper:] caractère majuscule
[:xdigit:] caractère hexadécimal
Voici quelques exemples d'utilisation des classes de caractère dans une expression régulière :
"^[:alnum:]+$"
chaîne contenant un caractère de ponctuation ou un caractère d'espacement
"[:punct:]|[:space:]"
Un nombre
"^[:digit:]+$"
Les fonctions de manipulation d'expressions régulières
PHP fournit quelques fonctions de bases permettant de manipuler des chaînes à l'aide
d'expressions régulières.
<?
fclose($fp);
?>
Le code suivant (utilisation avancée des expressions régulières) remplace un URL par un hypertexte
HTML (il remplace toute suite de caractères de ponctuations et alphanumériques commençant par
http://, ou ftp:// par le même texte (sans le http://) entre balises HTML hypertexte...):
$Texte = ereg_replace("(http://)(([[:punct:]]|[[:alnum:]])*)",
"<a href=\"\\0\">\\2</a>",$Texte);
La fonction split()
La fonction split() retourne un tableau à partir d'une chaîne et d'une expression régulière. La limite,
optionnelle permet de limiter la taille du tableau retourné. Dans ce cas le dernier élément du tableau
contient le reste de la chaîne. Si une erreur se produit, split retourne 0.
<?
?>
La fonction sql_regcase()
Elle retourne une expression régulière qui représente la chaîne passée en paramètre sans tenir compte
de la case. Chaque caractère de la chaîne est representé entre crochets, avec deux caractères à
l'intérieur un en majuscule et l'autre en minuscule, ou le cas échéant deux fois le même caractères.
Aucune explication ne vaut un bon exemple ;)
<?
?>
Cette fonction permet de générer une chaîne non sensible à la casse, pour les expressions régulières
dans les bases de données par exemple. Dans MySQL lorsque vous utilisez la fonction REGEXP (au lieu
de LIKE) la recherche est sensible à la casse. La solution est donc de générer une chaîne non sensible à
la casse à l'aide de sql_regcase.
<?
$motclef = sql_regcase("motclef");
?>
Prérequis
PHP permet de créer des images au format GIF à l'aide d'une librairie de fonctions prévue à cet effet. La
librairie permettant de créer et manipuler des fichiers graphiques se nomme GD, ainsi, pour pouvoir
utiliser ces fonctions il faut que PHP soit installé avec l'extension GD, c'est-à-dire passer le paramètre --
with-gd.
La librairie de fonctions GD permet de créer assez facilement des fichiers au format GIF, en
fonction par exemple de données stockées dans un SGBD (Système de gestion de bases de
données). Il faut tout de même savoir que ce genre de procédé met à rude épreuve le
processeur, il faut donc utiliser ces fonctions à bon escient (par exemple pour des diagrammes
statistiques à barre, des graphiques sectoriels, ...).
Comment utiliser ces fonctions
Les fonctions de la librairies GD permettent de retourner une image, c'est-à-dire un fichier GIF. Ainsi un
tel fichier ne peut envoyer du texte au navigateur, il doit obligatoirement être appelé à partir d'une
page HTML (généralement avec une balise <IMG src="mon_fichier.php3">).
D'autre part, pour que le navigateur sache qu'il s'agit d'un fichier de type GIF, la premiere chose à faire
(avant d'envoyer n'importe quelle autre information au navigateur) est d'envoyer un en-tête HTTP
indiquant le type MIME du fichier, c'est-à-dire:
headers("Content-Type: image/gif");
La principale fonction de la librairie est imagegif() elle permet de retourner au navigateur l'image créée
avec les autres fonctions, en passant en paramètres un entier identifiant l'image. Si jamais le nom du
fichier est passé en second argument, le fichier est écrit sur le disque.
La fonction imagecreate() permet de créer un identifiant pour une image vierge possèdant les
dimensions indiquées en paramètres.
La fonction imagecreatefromgif() permet de créer un identifiant pour l'image créée à partir d'une
image GIF existant sur le disque, en passant en paramètre le nom du fichier.
Enfin la fonction imagedestroy() permet de vider la mémoire allouée à l'image dont on a passé
l'identifiant en paramètre.
Voilà donc un script minimal (et inutile) créant une image PHP à partir d'une image présente sur le
disque:
<?php
headers("Content-Type: image/gif");
$image = imagecreatefromgif("toto.gif");
imagegif($image);
?>
L'allocation de couleur
La plupart des fonctions graphiques nécessitent le passage en paramètre d'une couleur. Ainsi, PHP
fournit des fonctions permettant d'allouer une couleur à une image en spécifiant les composantes RGB
(Red, Green, Blue soient Rouge, Vert et Bleu) de la couleur.
La fonction imagecolorallocate() alloue une couleur à une image en spécifiant ses composantes RGB
sous forme entière (0 à 255 pour chaque composante), ou hexadécimale (0x00 à 0xFF pour chaque
composante).
Voici quelques exemples d'allocation de couleurs avec cette fonction (avec les composantes en
hexadécimal ou en entier):
$noir = imagecolorallocate($image,0,0,0);
$rouge = imagecolorallocate($image,255,0,0);
$vert = imagecolorallocate($image,0,0xFF,0);
La création de formes
La librairie GD fournit un panel de fonctions permettant de créer des formes primaires telles que:
des rectangles
des ellipses (donc des cercles)
des arcs
des lignes
Généralement ces fonctions admettent en premier paramètre l'identifiant de l'image dans
laquelle la forme doit être créée, puis les coordonnées permettant de générer la forme, et enfin
la couleur de l'élément. Elles retournent 1 si l'élément a pu être dessiné, 0 dans le cas contraire
Voici un exemple montrant comment créer des formes simples avec PHP:
<?php
$image = imagecreate(160,100);
$fond = imagecolorallocate($image,0xEF,0xF2,0xFB);
$noir = imagecolorallocate($image,0,0,0);
imagefill($image,0,0,$fond);
imagefilledpolygon($image,array(80,15,45,85,125,85),3,$noir);
header("Content-Type: image/gif");
imagegif($image);
?>
Deux fonctions supplémentaires vous permettront de remplir une zone avec une couleur:
Fonction Description
Remplit une zone d'une même couleur par la couleur spécifiée
imagefill(entier image,entier x,entier
en argument, en commençant le remplissage à partir du point
y,entier couleur)
indiqué en paramètre
imagetoborder(entier image,entier Remplit une zone délimitée par une bordure d'une couleur, par
x,entier y,entier couleurbordure,entier la couleur spécifiée en argument, en commençant le
couleur) remplissage à partir du point indiqué en paramètre
Les chaînes de caractères
PHP permet d'autre part de dessiner des chaînes de caractères dans une image grâce à une grande
variété de fonctions dédiées. Cela autorise ainsi la création de légendes ou de boutons dynamiques, en
fonction du texte passé en paramètre, stocké dans un fichier, ou bien dans une base de données.
La principale fonction permettant de créer des chaînes de caractères dans l'image est imagestring() :
Cette fonction permet de créer une chaîne de caractères contenant le texte passé en argument à la
position spécifiée par les arguments (x,y) avec la police indiquée.
En réalité PHP propose 5 polices par défaut numérotées de 0 à 5, mais il est possible de spécifier une
police p[ersonnalisée grâce à la fonction imageloadfont() :
Le format du fichier de police passé en paramètre peut varier selon le système sur lequel PHP
fonctionne...
$hauteur = imagefontheight($police);
Fonction Description
Crée un caractère à l'emplacement (x,y) (position de l'angle
booléen imagechar(entier supérieur gauche du caractère). La police du caractère peut-être
image,entier police,entier x,entier choisie parmi les polices par défaut (1 à 5) ou bien une police
y,chaîne caractere,entier couleur) personnalisé que vous avez ouvert précédemment avec
imageloadfont()
Crée un caractère orienté à l'horizontale (rotation de 90°) à
booléen imagecharup(entier l'emplacement (x,y) (position de l'angle supérieur gauche du
image,entier police,entier x,entier caractère). La police du caractère peut-être choisie parmi les
y,chaîne caractere,entier couleur) polices par défaut (1 à 5) ou bien une police personnalisé que vous
avez ouvert précédemment avec imageloadfont()
entier imagefontheight(entier
retourne la hauteur de la police utilisée
police)
entier imagefontwidth(entier
retourne la largeur de la police utilisée
police)
entier imageloadfont(chaîne Charge la police dont le nom est passé en argument et retourne son
nom_du_fichier) identifiant
Crée une chaîne de caractères à l'emplacement (x,y) (position de
booléen imagestring(entier l'angle supérieur gauche de la chaîne de caractère). La police du
image,entier police,entier x,entier caractère peut-être choisie parmi les polices par défaut (1 à 5) ou
y,chaîne texte,entier couleur) bien une police personnalisé que vous avez ouvert précédemment
avec imageloadfont()
Crée une chaîne de caractères orientée verticalement (rotation de
booléen imagestringup(entier 90°) à l'emplacement (x,y) (position de l'angle supérieur gauche de
image,entier police,entier x,entier la chaîne de caractère). La police du caractère peut-être choisie
y,chaîne texte,entier couleur) parmi les polices par défaut (1 à 5) ou bien une police personnalisé
que vous avez ouvert précédemment avec imageloadfont()
Un diagramme des navigateurs de vos visiteurs
Le script suivant est fourni par le webmaster de C'est quoi Linux. Il vous permet de créer une image
contenant un diagramme circulaire des navigateurs de vos visiteurs, sachant que ceux-ci sont stockés
dans une table appelée visiteurs dans un champ nommé navigateur.
Pour stocker ces valeurs, il suffit de créer cette table sur votre site, puis de stocker la valeur à l'aide de
la requête suivante:
INSERT INTO visiteurs values("$HTTP_USER_AGENT")
<?
header("Content-type: image/gif");
$host="votre.base.de.donnees";
$user="votre.login";
$pass="votre.mot.de.passe";
$bdd="nom_de_la_base";
mysql_connect($host,$user,$pass);
mysql_select_db($bdd);
$query="SELECT navigateur FROM visiteurs";
$result=mysql_query($query);
$netscape3=0;
$netscape4=0;
$ie3=0;
$ie4=0;
$ie5=0;
$autre=0;
while($row=mysql_fetch_row($result))
$total++;
if(ereg("3(\.)([0-9]+) (\[)([a-z]+)(\])(.*)$",$row[0]))
$netscape3++;
if(ereg("4(\.)([0-9]+) (\[)([a-z]+)(\])(.*)$",$row[0]))
$netscape4++;
if(ereg("MSIE(\_?)( ?)3",$row[0]) )
$ie3++;
if(ereg("MSIE(\_?)( ?)4",$row[0]) )
$ie4++;
if(ereg("MSIE(\_?)( ?)5",$row[0]) )
$ie5++;
&&(!ereg("4(\.)([0-9]+) (\[)([a-z]+)(\])(.*)$",$row[0]))
&&(!ereg("MSIE(\_?)( ?)3",$row[0]) )
&&(!ereg("MSIE(\_?)( ?)4",$row[0]) )
&&(!ereg("MSIE(\_?)( ?)5",$row[0]) ))
$autre++;
mysql_close();
function compare($navig,$nbre)
if($navig==$netscape3) { $navig++; }
if($nbre!=1)
if($navig==$netscape4) { $navig++; }
if($nbre>2)
if($navig==$ie3) { $navig++; }
if($nbre>3)
if($navig==$ie4) { $navig++; }
if($nbre>4)
if($navig==$ie5) { $navig++; }
return($navig);
$netscape3=$netscape3*10;
$netscape4=$netscape4*10;
$ie3=$ie3*10;
$ie4=$ie4*10;
$ie5=$ie5*10;
$autre=$autre*10;
$netscape4=compare($netscape4,1);
$ie3=compare($ie3,2);
$ie4=compare($ie4,3);
$ie5=compare($ie5,4);
$autre=compare($autre,5);
function radians($degrees)
return($degrees * (pi()/180.0));
$x = cos(radians($degrees)) * ($diameter/2);
$y = sin(radians($degrees)) * ($diameter/2);
return(array($x,$y));
$ChartDiameter = 130;
$ChartFont = 2;
$ChartFontHeight = imagefontheight($ChartFont);
$ChartFontWidth = imagefontwidth($ChartFont);
$ChartData = array($netscape3,$netscape4,$ie3,$ie4,$ie5,$autre);
$netscape4=>"Netscape 4",
$autre=>"Autres Navigateurs");
rsort($ChartData);
arsort($ChartData2);
$ChartCenterX = $ChartDiameter/2 + 10;
$colorBody = imagecolorallocate($image,0xEF,0xF2,0xFB);
$colorBorder = imagecolorallocate($image,0x00,0x00,0x00);
$colorText = imagecolorallocate($image,0x00,0x00,0x00);
$colorSlice[]= imagecolorallocate($image,0x76,0x89,0xFF);
$colorSlice[]= imagecolorallocate($image,0x96,0xA6,0xFF);
$colorSlice[]= imagecolorallocate($image,0xA6,0xB9,0xFF);
$colorSlice[]= imagecolorallocate($image,0xB6,0xC9,0xFF);
$colorSlice[]= imagecolorallocate($image,0xC6,0xD9,0xFF);
$colorSlice[]= imagecolorallocate($image,0xD6,0xE9,0xFF);
imagefill($image,0,0,$colorBody);
$Degrees = 0;
$ChartDataReel=(int)($ChartData[$index]/10);
$StartDegrees = round($Degrees);
$Degrees+= (($ChartDataReel/$total)*360);
$EndDegrees = round($Degrees);
$CurrentColor = $colorSlice[$index%(count($colorSlice))];
floor($ChartCenterX + $ArcX),
floor($ChartCenterX + $ArcX),
floor($ChartCenterY + $ArcY), $CurrentColor);
$CurrentColor = $colorSlice[$index%(count($colorSlice))];
imagefilltoborder($image, $LineX + 2,
$valeur=(int)($ChartData[$index]/10);
$valeur2=$ChartData[$index];
$pourcentage=round(($valeur/$total)*100);
imagegif($image);
?>
Chapitre 15 : Entêtes http et Cookies
Lors de chaque échange par le protocole HTTP entre votre navigateur et le serveur, des données dîtes
d'en-têtes contenant des informations sur les données à envoyer (dans le cas d'une requête) ou
envoyées (dans le cas d'une réponse). Les informations en question, généralement sur une page web ou
une image, suivent ces en-têtes. Les en-têtes HTTP permettent aussi d'effectuer des actions sur le
navigateur comme le transfert de cookies ou bien une redirection vers une autre page.
Ces en-têtes sont les premières informations envoyées au navigateur (pour une réponse) ou au serveur
(dans le cas d'une requête), elles se présentent sous la forme:
en-tête: valeur
La syntaxe doit être rigoureusement respectée, c'est-à-dire qu'aucun espace ne doit figurer entre
le nom de l'en-tête et les deux points (:). Un espace doit par contre figurer après celui-ci !
PHP fournit une fonction permettant d'envoyer très simplement des en-têtes HTTP manuellement du
serveur au navigateur (il s'agit alors d'une réponse HTTP. La syntaxe de cette fonction est la suivante:
Etant donnée que les en-têtes HTTP sont les premières informations envoyées, la fonction
header() doit être utilisée avant tout envoi de données HTML au navigateur (le script qui la
contient doit donc être placé avant la balise <HTML> et avant toute fonction echo(),print ou
printf())
Alors que la fonction header() permet d'envoyer des en-têtes HTTP au navigateur, PHP fournit une
seconde fonction permettant de récupérer dans un tableau l'ensemble des en-têtes HTTP envoyées par le
navigateur. Voici la syntaxe de cette fonction:
Tableau getallheaders();
Le tableau retourné par la fonction contient les en-têtes indexés par leur nom. Voici un script permettant
par exemple de récupérer des en-têtes particuliers.
<?
$entetes = getallheaders;
echo $entetes["location"];
?>
PHP permet de gérer très facilement les cookies (pour plus d'informations sur les cookies, veuillez vous
reporter à cet article), c'est-à-dire la création de petits fichiers texte chez le client permettant de
mémoriser individuellement des préférences pour chaque utilisateur sans le gérer du côté du serveur.
Créer le cookie
Pour créer un cookie sur une machine appelant un de vos scripts PHP, il faut utiliser la fonction
setcookie() dans celui-ci. La fonction SetCookie() permet d'envoyer les informations relatives aux cookies
dans les en-têtes HTTP
Voici la syntaxe de la fonction setcookie:
chaîne Valeur,
entier expiration,
chaîne chemin,
chaîne domaine,
entier securisé);
L'argument NomDuCookie est celui qui vous permettra de faire référence à un cookie spécifique stocké
sur le disque des utilisateurs. A chaque cookie correspond un nom auquel une valeur est attribuée.
expiration: détermine le moment à partir duquel le cookie sera effacé du disque du client. Elle
doit être passée sous forme d'un entier indiquant le nombre de secondes à compter du 1 er
janvier 1970 à partir desquelles le cookies n'est plus valide. Il est généralement d'usage
d'utiliser la fonction now() qui retourne le nombre de secondes de cette date à maintenant et d'y
ajouter le nombre de secondes de validités que l'on désire. Pour un cookie valide pendant un an
ce sera now()+31536000. Dans certains cas la fonction mktime() peut s'avérer elle aussi très
pratique
chemin désigne le répertoire à partir de la racine de votre domaine pour lequel votre cookie est
valide, c'est-à-dire que si vous ne voulez utiliser le cookie que dans des scripts stockÉs dans le
répertoire /commerce il faudra définir le chemin /commerce/
domaine il s'agit du domaine de votre serveur, celui-ci doit obligatoirement contenir 2 points
(par exemple www.commentcamarche.net). Par défaut (si vous omettez ce paramètre) le
domaine qui a créé le cookie (donc le votre) sera automatiquement inséré
sécurisé lorsqu'il est mis à 1 indique que le cookie ne sera transmis que si la ligne est sécurisée
(par SSL ou S-HTTP
Quelques précisions sur les cookies
La fonction setcookie() doit être utilisée avant tout envoi de données HTML vers le
navigateur, même si ces données sont envoyées avec echo, print ou équivalent (le script
qui la contient doit donc être placé avant la balise <HTML> et avant toute fonction
echo(),print ou printf()).
Le cookie n'est pas visible avant le prochain chargement de page.
Avec PHP3 si vous envoyez plusieurs cookies de suite, les appels seront traités en ordre
inverse, alors qu'avec PHP4 ils seront traités dans l'ordre.
Il est possible d'utiliser des tableaux dans un cookie. Autant de cookies que d'éléments
du tableau seront alors envoyés, mais tout se fait de façon transparente, puisque à la
lecture un tableau sera créé. Il est quand même préférable d'utiliser les fonctions
implode et explode pour envoyer ainsi qu'un seul cookie.
Il faut savoir que certains navigateurs ne traitent pas bien les cookies
o Microsoft Internet Explorer 4 avec le Service Pack 1 ne traite pas correctement
les cookies qui ont le paramètre chemin défini.
o Inversement Netscape Communicator 4.05 et Microsoft Internet Explorer 3.x ne
traitent pas correctement les cookies qui n'ont pas les paramètres chemin et
expiration définis.
Exemple d'utilisation de cookies
Voilà donc un script permettant de savoir si un visiteur est déjà venu sur le site pendant le mois:
<?php
setcookie(
"Visites",
"Oui",
time()+2592000,
"/",
".commentcamarche.net",0);
?>
<?php
SetCookie("CcmUserSessionCookie","$login:$pass");
SetCookie("CcmDejaVisite","1",time()+3600*24,"/",".phpfrance.com",0);
SetCookie("CcmAn2000","1",mktime(0,0,0,1,1,2001),"/",".phpfrance.com",0);
?>
Lorsqu'un cookie pour votre domaine est présent sur le disque du client, si celui-ci visite une de vos
pages PHP dont le chemin est inclut dans le paramètre chemin (si le chemin est / le cookie est valide
pour toutes les pages de votre site) le cookie sera automatiquement passé en paramètre à votre script et
sa valeur sera directement accessible dans la variable $NomDuCookie.
Voici le même script que précédemment permettant cette fois ci de compter le nombre de visite de la
page par le visiteur:
<?php
$Visites++;
setcookie(
"Visites",
$Visites,
time()+2592000,
"/",
".commentcamarche.net",0);
?>
A chaque appel de la page, le script récupère la valeur du cookie nommé Visites, l'incrémente, puis
envoie le cookie dont la valeur a été incrémentée.
Supprimer un cookie
Il peut éventuellement être utile de proposer à l'utilisateur de supprimer certains de ses cookies, ou bien
de le faire vous même de façon transparente.
Pour ceci il suffit de renvoyer le cookie grâce à la fonction setcookie() en spécifiant simplement
l'argument NomDuCookie:
<?php
setcookie("Visites");
?>
Une autre méthode consiste à envoyer un cookie dont la date d'expiration est passée:
<?php
setcookie("Visites","",0,"/","",0);
?>
Lorsque vous souscrivez en tant que membre de CCM, un mot de passe et un login vous sont demandés.
Après confirmation de votre inscription en renvoyant simplement le mail qui vous a été automatiquement
envoyé, vous pouvez utiliser votre login et votre mot de passe dans la section s'identifier, activant un
cookie sur votre disque dur, contenant un numero d'identification ainsi qu'un numéro aléatoire
permettant au site de vous reconnaître dans certaines sections en comparant ces valeurs avec celles
stockées dans une entrée de la base de donnée. Cela fait apparaître de nouvelles options aux membres
CCM sans gêner les non-membres...
PHP étant un langage consacré au Web, il possède bien évidemment des fonctions lui
permettant de communiquer avec le "monde extérieur" à l'aide de fonctions standards. Le
service le plus utilisé sur Internet étant la messagerie électronique, il est naturel que PHP
permette d'envoyer des mails.
La fonction mail()
En PHP3 il existe une fonction très simple qui permet d'envoyer un email. Voilà sa syntaxe
chaîne Sujet,
chaîne corps_du_message,
chaîne options);
Le dernier champ est facultatif, on en parlera juste après. Dans un premier temps nous allons envoyer
un email de base. Voilà le nouveau code du fichier traitant les données envoyées par le formulaire
précédant :
<html?>
<body?>
<?
mail(
);
?>
</body?>
</html?>
$from_email = "[email protected]";
mail(
$entetemail
);
La fonction email()
La fonction email() remplace parfois la fonction mail() chez certains hébergeurs (dont Free) car elle
permet uniquement d'envoyer des mails à partir de votre adresse email.
Elle s'utilise à peu près de façon similaire à la fonction mail() mais sa syntaxe est quelque peu différente:
email("webmaster",
"Bonjour Toto",
Le protocole IMAP (Internet Message Access Protocol) est un protocole (datant de 1986) permettant
d'accèder à une messagerie électronique. Beaucoup plus évolué que le protocole POP (Post Office
Protocol), il a toutefois été supplanté par ce dernier qui est plus simple.
Ainsi PHP implémente la version 4 de ce protocole et fourni des fonctions permettant de manipuler des
boîtes aux lettres directement sur le serveur IMAP, ainsi que sur des serveurs POP ou NNTP (serveurs de
news).
La première fonction à utiliser est la fonction imap_open(), elle permet de se connecter à la boîte au
lettre et retourne un identifiant d'accès pour la boîte aux lettres, utilisable avec les autres fonctions
IMAP. Sa syntaxe est la suivante:
chaîne utilisateur,
chaîne mot_de_passe);
La boîte doit être spécifiée de la manière suivante (il s'agit ici de la boîte INBOX, celle dans laquelle les
nouveaux messages arrivent):
"{serveur:port}INBOX"
Le port utilisé par les serveurs IMAP est 143 par défaut.
Voici dans le cas de la newsletter de Comment ça Marche le script permettant d'ouvrir la boîte:
$mailbox = imap_open("{imap.pro.proxad.net:143}INBOX",
"password");
Une fois la boîte au lettre ouverte, il est possible (et généralement utile) de consulter les informations
sur l'état de la boîte aux lettres grâce à la fonction imap_check() dont la syntaxe est comme suit:
Celle-ci retourne un objet dont il est possible de connaître les propriétés, c'est-à-dire toutes les
informations sur la boîte au lettre passée en paramètre. Voici les propriétés de l'objet retourné par la
fonction imap_check():
Propriété Description
Date Date du dernier message
Driver Version du pilote utilisé
Mailbox Nom associé à la boîte aux lettres
Nmsgs Nombre de messages dans la boîte
Recent Nombre de messages non lus
La fonction certainement la plus utile est la fonction imap_header() car c'est elle qui permet de lire les
messages contenus à l'aide de l'identifiant de la boîte et du numéro du message:
entier Message[,
entier Longueur_champ_from[,
entier Longueur_sujet]]);
Ainsi les propriétés de l'objet renvoyé par imap_header() sont les suivantes:
Propriété Description
Answered
bcc
bccadress
cc
ccaddress/td>
Date
date
Deleted
fetchfrom
from
in_reply_to
MailDate
message_id
Msgno
newsgroups
Recent
references
remail
return_pathaddress
sender
senderaddress
Size
subject
Subject
to
toaddress
update
Unseen
Les propriétés de l'objet retourné par la fonction imap_header() sont accessible par la notation suivante:
$Nom_de_l_objet->Propriétés;
La fonction imap_num_msg() permet de savoir très facilement le nombre de messages sur le serveur.
Ainsi le script suivant permet d'afficher les mails contenus dans la boîte INBOX du compte
[email protected] et supprime les mails dont le sujet contient "a détruire" ou les mails
dont le corps contient "destruction":
<?
$mailbox = imap_open("{imap.pro.proxad.net:143}INBOX",
"password");
$check = imap_check($mailbox);
$nMessages = imap_num_msg($mailbox);
echo "<tr><td>$header->Subject</td></tr>\n";
$from = $header->from[0];
echo "<tr><td>$from</td></tr>\n";
$corps = imap_body($mailbox,$index);
echo "<tr><td>$corps</td></tr>\n";
if (eregi(".*a detruire.*",$header->Subject)||
eregi("destruction",$corps)) {
imap_delete($mailbox,$index,0);
echo "</table>\n";
imap_expunge($mailbox);
imap_close($mailbox);
?>
Introduction à LDAP
PHP permet la connexion et l'envoi de requêtes sur un annuaire LDAP, c'est-à-dire un serveur permettant
de stocker des informations de manière hiérarchique.
Un serveur LDAP est conçu pour être capable de gérer les opérations suivantes :
L'interrogation d'un serveur LDAP avec PHP se fait selon une séquence simple, nécessitant un nombre
peu élevé de fonctions spécialisées. La séquence basique est la suivante :
Avant de pouvoir interroger le serveur LDAP, il est essentiel d'initier la connexion. Pour cela l'interpréteur
PHP a besoin de connaître quelques renseignements relatifs à l'annuaire :
L'adresse du serveur
Le port sur lequel le serveur fonctionne
La racine de l'annuaire
Le login de l'utilisateur (généralement root) ainsi que son mot de passe
<?
$server = "localhost";
$port = "389";
$rootpw = "secret";
?>
On définit donc cinq variables pour caractériser le serveur LDAP : le nom du serveur, le port (389 par
défaut), la racine supérieure de l'arborescence, la chaîne de connexion pour l'administrateur ainsi que
son mot de passe.
La première fonction à utiliser est la fonction ldap_connect() permettant d'établir une liaison avec le
serveur. Sa syntaxe est la suivante :
<?
echo "Connexion...<br>";
$ds=ldap_connect($server);
?>
Toutefois cette opération n'est pas suffisante pour pouvoir exécuter des opérations sur le serveur LDAP.
En effet, il est nécessaire d'initier la liaison (en anglais to bind) avec le serveur LDAP à l'aide de la
fonction ldap_bind() dont la syntaxe est la suivante :
La déconnexion du serveur LDAP se fait tout naturellement par la fonction ldap_close() avec la syntaxe
suivante :
<?
$server = "localhost";
$port = "389";
$rootpw = "secret";
echo "Connexion...<br>";
$ds=ldap_connect($server);
if ($ds==1)
$r=ldap_bind($ds,$rootdn,$rootpw);
// Ici les opérations à effectuer
echo "Déconnexion...<br>";
ldap_close($ds);
else {
?>
Exécution des opérations
Ajouter une entrée avec ldap_add()
La fonction ldap_add() permet d'ajouter des entrées à un annuaire LDAP auquel on s'est préalablement
connecté (et lié). Voici sa syntaxe :
Lorsqu'un attribut est multivalué (c'est-à-dire lorsqu'un attribut est lui-même composé de plusieurs
valeurs), celles-ci sont indexées dans une case du tableau (les indices du tableau commencent à 0).
Dans l'exemple ci-dessous par exemple, l'attribut "mail" possède plusieurs valeurs :
<?php
if ($ds) {
$r=ldap_bind($ds,$rootdn,$rootpw);
$entry["cn"]="Pillou";
$entry["sn"]="Jean-Francois";
$entry["mail"][0]="[email protected]";
$entry["mail"][1]="[email protected]";
$entry["objectclass"]="person";
} else {
?>
Comparer une entrée avec ldap_compare()
La fonction ldap_compare() permet de comparer la valeur d'un attribut d'une entrée de l'annuaire LDAP,
auquel on s'est préalablement connecté (et lié), à une valeur passée en paramètre. Voici la syntaxe de la
fonction ldap_compare() :
int ldap_compare (int identifiant, string dn, string attribut, string valeur)
La fonction ldap_compare() admet en paramètre l'identifiant du serveur LDAP retourné par la fonction
ldap_connect(), le nom distingué de l'entrée (c'est-à-dire son emplacement dans l'annuaire) ainsi que le
nom de l'attribut de l'entrée et la valeur à laquelle on veut comparer sa valeur dans l'annuaire.
En cas d'erreur, la fonction ldap_compare() renvoie la valeur -1, en cas de réussite elle renvoie TRUE,
enfin dans le cas contraire elle renvoie FALSE.
L'exemple suivant (largement inspiré de celui de www.php.net) montre comment comparer un mot de
passe avec celui stocké dans l'annuaire pour un utilisateur donné :
<?php
$ds=ldap_connect($server);
if ($ds) {
$r=ldap_bind($ds,$rootdn,$rootpw);
$valeur="MonMot2Passe";
$attribut="password";
if ($resultat == -1) {
echo "Erreur:".ldap_error($ds);
ldap_close($ds);
} else {
?>
Notez l'utilisation de la fonction ldap_error() sur laquelle nous reviendrons ultérieurement pour
afficher les détails de l'erreur !
La fonction ldap_delete() permet de supprimer des entrées d'un annuaire LDAP. Voici sa syntaxe :
<?php
if ($ds) {
$r=ldap_bind($ds,$rootdn,$rootpw);
$dn="Pillou Jean-Francois,o=commentcamarche,c=fr";
$r=ldap_delete($ds, $dn);
ldap_close($ds);
} else {
echo "Connexion au serveur LDAP impossible";
?>
Modifier une entrée avec ldap_modify()
La fonction ldap_modify() permet de modifier une entrée de l'annuaire LDAP. Sa syntaxe est la même
que celle de la fonction ldap_add() :
Lorsqu'un attribut est multivalué (c'est-à-dire lorsqu'un attribut est lui-même composé de plusieurs
valeurs), celles-ci sont indexées dans une case du tableau (les indices du tableau commencent à 0).
Dans l'exemple ci-dessous par exemple, l'attribut "mail" possède plusieurs valeurs :
<?php
if ($ds) {
$r=ldap_bind($ds,$rootdn,$rootpw);
$entry["cn"]="Pillou";
$entry["sn"]="Jean-Francois";
$entry["mail"][0]="[email protected]";
$entry["mail"][1]="[email protected]";
$entry["objectclass"]="person";
ldap_close($ds);
} else {
?>
Rechercher une entrée avec ldap_search()
La recherche d'entrée dans l'annuaire est sans aucun doute la fonction la plus utile parmi les fonctions
LDAP de PHP¨car un annuaire est prévu pour être plus souvent sollicité en lecture (recherche) qu'en
écriture (ajout/suppression/modification).
La fonction ldap_search() permet de rechercher une ou plusieurs entrées de l'annuaire LDAP à l'aide du
DN de base, c'est-à-dire le niveau de l'annuaire à partir duquel la recherche est effectuée, ainsi qu'un
filtre représentant le type de recherche que l'on désire effectuer. Sa syntaxe est la suivante :
Le paramètre attributs permet de restreindre les attributs et les valeurs retournées, c'est-à-dire qu'il
s'agit d'un tableau contenant le nom des attributs (chaînes de caractères) des attributs que l'on désire
utiliser. Par défaut l'intégralité des attributs des entrées est renvoyée par le serveur, ce qui peut donner
un nombre de données très important.
Le paramètre attrsonly permet de demander à l'annuaire de retourner uniquement les types d'attributs
et non leurs valeurs lorsqu'il vaut 1. Par défaut (ou lorsque ce paramètre vaut 0) les types des attributs
ainsi que leurs valeurs sont retournés par le serveur.
Le sixième paramètre sizelimit comme son nom l'indique permet de limiter le nombre maximum de
résultat retourné par l'annuaire afin de réduire le volume des données retournées. Il faut noter que si le
serveur est configuré pour retourner moins de résultats, une valeur supérieure de l'attribut ne permettra
pas de dépasser la valeur inscrite dans la configuration du serveur. La valeur 0 indique qu'aucune limite
autre que celle imposée par le serveur n'est définie.
Le septième paramètre timelimit permet de limiter le temps maximal de la recherche pris par le serveur.
Il faut noter que si le serveur est configuré pour retourner moins de résultats, une valeur supérieure de
l'attribut ne permettra pas de dépasser la valeur inscrite dans la configuration du serveur. La valeur 0
indique qu'aucune limite autre que celle imposée par le serveur n'est définie.
Enfin le huitième paramètre deref permet d'indiquer selon sa valeur la façon de procéder avec les alias
lors de la recherche. Les valeurs possibles de ce paramètre sont les suivantes:
LDAP_DEREF_NEVER : les alias ne sont jamais déréférencés. Il s'agit de la valeur par défaut.
LDAP_DEREF_SEARCHING : les alias sont déréférencés uniquement pendant la recherche et non
pendant leur localisation.
LDAP_DEREF_FINDING : les alias sont déréférencés uniquement pendant leur localisation et non
lors de la recherche.
LDAP_DEREF_ALWAYS : les alias sont toujours déréférencés.
L'exemple suivant permet de connaître le nombre de résultats retournés pour une recherche d'une
personne dont le nom ou le prenom commence par la chaîne $person passée en paramètre :
<?php
if ($ds) {
$r=ldap_bind($ds,$rootdn,$rootpw);
$dn = "o=commentcamarche, c=fr";
$filtre="(|(sn=$person*)(cn=$person*))";
";
ldap_close($ds);
} else {
?>
Toutefois, une fois l'opération de recherche effectuée, il s'agit d'exploiter les résultats obtenus. Ainsi, la
majeure partie des fonctions LDAP ont pour but le traitement des résultats de la recherche.
Dans l'exemple ci-dessus, la fonction ldap_get_entries() permet de récupérer des informations sur les
entrées retournées par la fonction ldap_search().
De nombreuses fonctions LDAP permettent d'exploiter les résultats renvoyés par la fonction
ldap_search(). Ces fonctions ont un nom commençant généralement par ldap_get_ suivi du nom de
l'élément à récupérer :
<?php
if ($ds) {
$r=ldap_bind($ds,$rootdn,$rootpw);
$filtre="(|(sn=$person*)(cn=$person*))";
";
ldap_close($ds);
} else {
echo "Connexion au serveur LDAP impossible";
?>
La fonction ldap_get_entries() permet de récupérer l'ensemble des entrées retournées par la fonction
ldap_search() ainsi que de lire les attributs associés et leur(s) valeur(s).
Sa syntaxe est la suivante :
La structure du tableau retourné (on supposera qu'il se trouve dans la variable $entrees) est la
suivante :
<?php
if ($ds) {
$r=ldap_bind($ds,$rootdn,$rootpw);
echo "Affichage des données des ".$info["count"]. " entrées trouvées :";
for($j=0;$j<$info[$i]["mail"]["count"];$j++) {
ldap_close($ds);
} else {
?>
Notez que pour récupérer uniquement le nombre de résultats total, il est préférable d'utiliser la
fonction ldap_count_entries() que de passer par la fonction ldap_get_entries() puis
$entrees["count"]
Plus d'informations
Pour plus d'informations sur LDAP, reportez-vous à la section consacrée à ce sujet
Pour plus d'informations sur l'interfaçage d'un annuaire LDAP, reportez-vous au site de référence
PHP.net
PhpLdapAdmin, une application en PHP permettant de gérer votre annuaire LDAP
Chapitre 18 : de XML à Php
Introduction à XML
PHP permet l'analyse syntaxique (parsage ou parsing en anglais) d'un document XML.
Le langage XML (eXtensible Markup Language, traduisez Langage à balises extensibles) est un
métalangage, c'est-à-dire un langage permettant de définir votre propre langage. Ainsi contrairement au
langage HTML, le langage XML permet d'aller définir vos propres balises, ce qui permet de séparer la
présentation du document de son contenu.
Cette séparation entre le contenu et la présentation se fait à l'aide d'un analyseur syntaxique (parseur),
c'est-à-dire un programme capable de vérifier la cohérence de la syntaxe du document et de l'interpréter
afin de mettre en page son contenu. PHP propose une extension permettant de mettre au point
facilement des analyseurs XML. Cette extension utilise la librairie expat disponible à
http://www.jclark.com/xml/.
Télécharger Expat.
Pour activer le support de cette librairie lors de l'installation de PHP il suffit de lancer la configuration de
PHP avec l'option --with-xml.
Pour vérifier que votre installation supporte bien la librairie expat, il vous suffit de créer un fichier
phpinfo.php3 contenant uniquement les lignes suivantes
<?
phpinfo();
?>
Fonctionnement de l'extension XML
Les analyseurs XML sont également divisés selon l'approche qu'ils utilisent pour traiter le document. On
distingue actuellement deux types d'approches :
Les API utilisant une approche hiérarchique : les analyseurs utilisant cette technique construisent
une structure hiérarchique contenant des objets représentant les éléments du document, et dont
les méthodes permettent d'acCèder aux propriétés. La principale API utilisant cette approche est
DOM (Document Object Model)
Les API basés sur un mode événementiel permettent de réagir à des événements (comme le
début d'un élément, la fin d'un élément) et de renvoyer le résultat à l'application utilisant cette
API. SAX (Simple API for XML est la principale interface utilisant l'aspect événementiel Ainsi, on
tend à associer l'approche hiérarchique avec DOM et l'approche événementielle avec SAX.
<debut>
</debut>
Avec un parseur XML utilisant une approche événementielle, les 3 événements suivants seraient
générés :
Start Element : debut
Start CDATA section, value : Bienvenue sur CCM - http://www.commentcamarche.net
Close Element : debut
L'extension XML fonctionne selon un mode événementiel, c'est-à-dire qu'elle définit des fonctions
permettant de réagir aux divers événements :
La première étape consiste à créer un analyseur XML (ou plus exactement pour utiliser une instance de
parseur XML) grâce à la fonction xml_create_parser() $xml_parseur = xml_parser_create(); Une
fois le parseur créé, il s'agit de lui associer des événements, c'est-à-dire qu'il s'agit de créer des
fonctions qui seront appelées par le parseur en cas de déclenchement d'un événement.
L'extension XML (expat) définit 7 types d'événements et leurs gestionnaires (handlers)
associés :
Toutes ces fonctions de gestion des événements prennent comme premier argument l'instance du
parseur qui a été renvoyée par la fonction xml_create_handler().
L'instance du parseur
Le nom de la fonction qui gère les balises ouvrantes
Le nom de la fonction qui gère les balises fermantes
Les fonctions de gestion des événements définies par l'utilisateur doivent exister avant de commencer à
parser le document. De plus leurs définitions doivent concorder exactement avec le prototype défini dans
le manuel PHP (http://www.php.net).
Par exemple la fonction chargée de gérer l'événement "balise ouvrante" doit comporter trois
paramètres :
function ouverture ($parser, $name, $attrs){
echo "$name<BR>";
}
Son nom et le nom de ses attributs peuvent être modifiés mais le nombre de ses arguments et leur ordre
doit être conforme au manuel PHP. Dans le cas de la fonction associée à l'ouverture de balise, le premier
argument est l'identifiant de l'instance du parseur, le second est le nom de la balise rencontrée (pour une
balise <Debut> sa valeur sera "Debut") et le troisième est un tableau associatif contenant tous les noms
des attributs de cet élément et leur valeur.
Le prototype est le même que pour le gestionnaire d'événement associé aux balises ouvrantes
du texte est trouvé hors des balises :
function texte ($parser, $data_text){
return $data_text;
}
Dans cette fonction le deuxième argument est le texte retourné par le gestionnaire d'événement
La fonction xml_parser_set_option() permet de définir des options de parsage. Le premier argument est
bien évidemment l'instance du parseur. Le second argument peut prendre deux valeurs (0 ou 1,
représenté par la constante XML_OPTION_CASE_FOLDING) : cette option est activée par défaut. Le fait
de désactiver cette option force le gestionnaire d'événement à transformer les noms des balises en
majuscule (il est essentiel de ne pas la désactiver car le XML est sensible à la casse, c'est-à-dire qu'il
différencie minuscules et majuscules). Le troisième argument définit quel encodage utiliser dans le
parseur XML (ISO-8859-1, US-ASCII ou UTF-8). Par défaut l'encodage est celui de xml_parser_create())
xml_parser_set_option($xml_parseur, XML_OPTION_CASE_FOLDING);
Pour parser un fichier XML, il suffit de l'ouvrir en lecture, puis de faire appel à la fonction xml_parse() :
xml_error_string(xml_get_error_code($xml_parseur)),
xml_get_current_line_number($xml_parseur))
);
Si le document XML n'est pas bien formé la fonction xml_parse() renvoie la valeur false
Comme chacun devrait le savoir, il est possible avec XML de faire appel à des entités externes, c'est-à-
dire importer des éléments XML stockés dans un autre fichier. Ainsi il est essentiel lors du parsage d'un
fichier XML d'incorporer le document externe au document XML principal.
Cela est possible grâce au gestionnaire d'entité externe permettant d'appeler une fonction à chaque fois
qu'une balise du type suivant est rencontrée dans le document XML :
<?
// Fichier à analyser
$file = "data.xml";
$depth = array();
$stack = array();
$globaldata ="";
global $depth;
global $stack;
for ($i = 0; $i < $depth[$parser]; $i++)
array_push($stack,$name);
$depth[$parser]++;
global $depth;
global $stack;
global $globaldata;
$depth[$parser]--;
array_pop($stack);
global $globaldata;
$globaldata = $data;
function externalEntityRefHandler($parser,
$openEntityNames,
$base,
$systemId,
$publicId)
if ($systemId)
xml_parser_free($parser);
return FALSE;
xml_parser_free($parser);
function new_xml_parser($file)
global $parser_file;
//création du parseur
$xml_parser = xml_parser_create();
if (!is_array($parser_file))
{ settype($parser_file, "array"); }
$parser_file[$xml_parser] = $file;
xml_parser_free($xml_parser);
?>
Mise en pratique :
Idée générale
Le moteur de recherche suivant a été mis au point par moi-même et ne correspond donc qu'à une idée
possible de moteur de recherche simple, ne gérant qu'un seul mot clé.
Le concept du fonctionnement de ce moteur est de créer une base de donnée contenant les mots clés de
chaque page du site stockés dans des balises spéciales appelées méta tags. Un premier script permet
donc de "scanner" l'ensemble des répertoires (et sous-répertoires) d'un site à la recherche de fichiers
dont l'extension est .htm ou .html, puis de scruter leur contenu à la recherche des balises méta
keywords (les mots-cés), title (le titre de la page), puis de stocker ces données, ainsi que l'emplacement
du fichier sur le serveur, dans une base de données. Chaque fichier du site devant être indexé devra
comporter les balises méta suivantes:
<head>
<META NAME="keywords" content="mot clé 1,mot cle 2,Mot clé 3, Mots clefs">
</head>
La balise ROBOTS permet de spécifier si le fichier doit être indexé ou non. Si vous ne voulez pas qu'une
page de votre site soit indexée, il suffit alors de lui incorporer la balise méta suivante:
<head>
</head>
Les balises précédentes ont l'avantage d'être utilisées aussi par les principaux moteurs du marché
(Yahoo!,Altavista,Voilà,...)
Dans un second temps, un script PHP permet d'exploiter la base de données ainsi créée en
cherchant dans celle-ci le mot clé saisi par l'utilisateur par l'intermédiaire d'un formulaire.
Le but est de créer une table comportant les champs nécessaires au stockage des enregistrements, c'est-
à-dire contenant les champs suivants:
<html>
<head>
<title>Creation de la table</title>
</head>
<body>
<?php
keyword text,
titre varchar(128),
id INT(11),
)";
// on ferme la base
mysql_close();
?>
</body>
</html>
Le script suivant est le script principal du moteur, car c'est lui qui permet de parcourir l'arborescence du
site à la recherche des fichiers HTML, de les scruter afin de déterminer s'ils doivent être ajoutés à la base
et, le cas échéant, stocker les données nécessaires à leur exploitation.
Le script va dans un premier temps supprimer les anciens enregistrements de la table, puis lancer une
procédure ayant pour rôle de parcourir l'arborescence à la recherche de fichier HTML.
Cette procédure est récursive, c'est-à-dire qu'elle s'appelle elle-même. Elle admet en paramètre le
répertoire dans lequel elle doit rechercher des fichiers, ainsi que le chemin d'accès relatif à ce répertoire.
La procédure examine chaque enregistrement du répertoire.
S'il s'agit d'un répertoire (autre que le répertoire courant (.) ou parent (..)), alors la fonction
examine le sous-répertoire
S'il s'agit d'un fichier dont l'extension est .htm ou .html, la fonction récupère l'ensemble des
méta tags dans un tableau associatif
o Si le méta tag ROBOTS contient la valeur NONE, la fonction passe son chemin
o Sinon, la fonction récupère les méta tags relatifs aux mots clés et au titre et les stocke
dans la base
<?php
echo "
<p>\n
<tr><td>\n
</td></tr>\n
</table>\n
<p>\n";
$MyDirectory = opendir($Directory);
while($Entry = readdir($MyDirectory)) {
ScanDir("$Entry/$Directory");
else {
if (eregi(".htm",$Entry)) {
$MetaTags = get_meta_tags($Directory."/".$Entry);
if ($MetaTags["robots"] == "all") {
$MetaKey = $MetaTags["keywords"];
$MetaKey = strtoupper($MetaKey);
$MetaTitre = $MetaTags["title"];
VALUES(\"$Directory/$Entry\",\"$MetaKey\",\"$MetaTitre\")";
}
}
closedir($MyDirectory);
$open_basedir=".";
ScanDir(".");
mysql_close();
?>
Pour exploiter la base de données, il faut dans un premier temps créer un formulaire permettant à vos
utilisateurs de saisir un mot clé à chercher. Voici un exemple de formulaire simple leur permettant
d'effectuer leur recherche:
</form>
Puis il s'agit de créer le script PHP (le dernier) recherchant l'ensemble des enregistrements de la base de
données contenant la chaîne entrée par l'utilisateur. Ce script est simple, il effectue dans un premier
temps une requête SQL sélectionnant les enregistrements contenant la chaîne. Puis il affiche le nombre
d'enregistrements retournés, et une boucle while exploite ces enregistrements et les affiche les uns à la
suite des autres.
<?php
<html>
<head>
<title>Résultat de la recherche</title>
</head>
<body>";
echo "
<p>";
else {
";
$result = mysql_query($query);
$row = mysql_fetch_row($result);
$Nombre = $row[0];
echo "
<p>
";
else {
$result = mysql_query($query);
if ($Nombre == "1") {
echo "
<p>";
else {
echo "
<p>";
while($row = mysql_fetch_row($result))
{
echo "
<p>\n
<b>$row[2]</b>\n
<p>\n
";
// on ferme la base
mysql_close();
?>
</body>
</html>
Remarques
Le moteur présenté ci-dessus permet de faire une recherche basique, il est donc possible de lui ajouter
des fonctionnalités, permettant par exemple de faire une recherche à partir de plusieurs mots-clés
(comme les moteurs de recherche courants). D'autre part, les résultats sont affichées de manière
basique les uns à la suite des autres. Il vous revient d'adapter la présentation des résultats à votre site,
ainsi que celle du formulaire ou des messages d'avertissement...
Introduction à LDAP
PHP permet la connexion et l'envoi de requêtes sur un annuaire LDAP, c'est-à-dire un serveur permettant
de stocker des informations de manière hiérarchique.
Pour plus d'informations sur les fonctions LDAP de PHP, reportez-vous à l'article consacré à ce sujet
Avant de commencer, il faut installer le module LDAP pour le langage PHP. Ce module ajoute un
certain nombre de fonctions qui débutent par « ldap_ » et qui permettent d'interfacer le serveur.
En effet, par défaut, PHP n'est pas livré avec le support LDAP. Si vous n'installez pas le module et
que vous tentez d'utiliser les commandes concernant LDAP, vous obtiendrez le message d'erreur
suivant :
Fatal error: Call to unsupported or undefined function ldap_connect() in
Dans le cadre de cet article, on se propose d'écrire un interface d'administration pour un annuaire. On va
prévoir les actions de base, c'est à dire : ajouter, modifier et supprimer des éléments de notre annuaire
LDAP.
Naturellement chacun à une action précise. Il y aura donc une page principale qui affichera les personnes
contenues dans l'annuaire et qui proposera les différentes actions associées aux objets.
Dans chaque module, on va avoir besoin d'un certain nombre de variables qui caractérisent le serveur
LDAP. On va donc créer un fichier de configuration externe qui sera chargé au démarrage de chaque
module. De cette façon, lorsque vous voulez installer votre application sur une autre plate-forme, vous
ne devez modifier que ce fichier de configuration.
De plus, on va prévoir la possibilité de modifier le modèle d'affichage, c'est à dire l'apparence de votre
interface. On utilisera donc deux fichiers :
On supposera que l'ensemble des pages PHP créées dans ce tutorial se trouvent sous le répertoires
ldap_admin/.
Nous allons donc protéger le répertoire ldap_admin/ qui contiendra les pages d'administration de notre
annuaire. Chaque utilisateur qui voudra accéder à ces pages devra s'authentifier. Nous utilisons la
méthode des fichiers .htaccess.
On va ainsi définir que seul l'utilisateur ldap_admin peut accéder à l'interface d'administration du forum.
On va dans un premier temps créer le fichier des utilisateurs.
Placez-vous dans le répertoire ldap_admin et exécuter la commande suivante pour créer ce fichier (pour
les utilisateurs de Linux) :
On va alors avoir à rentrer un mot de passe pour l'utilisateur: ldap_admin autorisé à accéder au
répertoire protégé.
New password:
On confirme.
Re-type new password:
Une fois que le fichier des utilisateurs est généré, on va créer le fichier .htaccess qui sera stocké dans le
répertoire à protéger, ici ldap_admin/.
On protège aussi le fichier de configuration :
<Files config_LDAP.inc.php3>
Order Deny,Allow
</Files>
AuthUserFile /home/httpd/html/services/ldap_admin/ldap_admin.passwd
AuthType Basic
<Limit GET POST>
require valid-user
</Limit>
La sécurisation de notre interface est maintenant terminée.
Fichier de configuration
<?
$server = "localhost";
$port = "389";
$rootpw = "secret";
?>
On définit donc cinq variables pour caractériser le serveur LDAP : le nom du serveur, le port (389 par
défaut), la racine supérieure de l'arborescence, la chaîne de connexion pour l'administrateur ainsi que
son mot de passe. Le fichier de configuration sera automatiquement appelé par le fichier header.php3
qui définit le haut de notre interface.
L'interface PHP/LDAP
Détaillons maintenant le fichier admin.php3 qui est la page principale de notre interface :
Cette page liste les personnes saisies dans l'annuaire et propose soit de les modifier soit de les
supprimer. Elle propose aussi un lien en bas de page pour ajouter une nouvelle personne.
En début de programme, le fichier header.php3, qui décrit le haut de page de l'interface, est
chargé.
Ce même fichier charge automatiquement le fichier de configuration.
Le fichier footer.php3, utilisé pour le bas de page est chargé à la fin.
La connexion au serveur LDAP est réalisée grâce à la fonction ldap_connect.
Ensuite, la fonction ldap_search permet de rechercher tous les objets de type person et de les afficher
avec une boucle de type « for » sous la forme d'un tableau en ajoutant deux liens qui correspondent
respectivement à la modification et à la suppression.
Pour la modification, la page modifie.php3 est appelée. On lui passe en paramètre la valeur de cn
contenue dans l'annuaire, qui correspond au nom concaténé au prénom.
La même chose est réalisée pour le lien concernant la suppression sauf que la page supprime.php3 est
appelée.
Le paramètre cn est encodé avec la fonction urlencode() de façon à transformer cette chaîne de
caractère en une chaîne compatible avec le format des URL. Ainsi les espaces seront par exemple
remplacés par des « + ».
<?
require("header.php3");
$ds=ldap_connect($server);
if ($ds==1)
echo "<tr>
<th>Nom et prénom</th>
<th>Adresse e-Mail </th>
<th>Téléphone</th>
</tr>";
for ($i=0;$i<$info["count"];$i++)
$mynom = $info[$i]["cn"][0];
$myemail = $info[$i]["mail"][0];
$mytel = $info[$i]["telephonenumber"][0];
echo" <tr><th>$mynom</th><th>
<A HREF=mailto:$myemail>$myemail</a></th><th>$mytel</th>";
$mynom=urlencode($mynom);
Supprimer</a></th></tr>";
echo"</table>";
ldap_close($ds);
require("footer.php3");
?>
Ajout d'une entrée à LDAP
Continuons avec la page ajoute.php3 qui est utilisée pour ajouter de nouvelles personnes dans notre
annuaire : Sur la copie d'écran, vous pouvez constater sur le haut et bas de page est exactement le
même que sur notre page principale (dû à l'utilisation des fichiers header.php3 et footer.php3). La page
est constituée d'un formulaire avec des champs obligatoires. Vous retrouvez les boutons standards pour
valider ou annuler votre nouvelle saisie. Pour essayer de garder toute la fonction « ajouter » dans la
même page (formulaire et enregistrement), on introduit une variable go qui détermine si la page est
appellée pour la première fois ou si elle est rappellée après la validation du formulaire.
Cette variable est en fait un champ caché du formulaire (<INPUT type="hidden" name="go"
value="1">).
Si la variable go est égale à 1 et que les champs nom, prénom et mail ne sont pas vides, on peut alors
enregistrer la nouvelle personne dans l'annuaire.
Pour ce faire, on se connecte au serveur et on s'authentifie avec le super-utilisateur, ici ldap_admin
(fonction ldap_bind()).
Ensuite on doit préparer nos informations avant de les inscrire dans l'annuaire : on construit le champ cn
en concaténant le nom et le prénom. On précise bien que c'est un objet de type person que l'on veut
ajouter et on lance l'enregistrement avec la fonction ldap_add().
Sinon, on affiche le formulaire de saisie avec un message d'erreur si l'on a validé le formulaire sans avoir
rempli les champs obligatoires.
<?
require("header.php3");
if (($go==1) and ($nom!="") and ($prenom!="") and ($mail!=""))
$ds=ldap_connect($server);
if ($ds==1)
$r=ldap_bind($ds,$rootdn,$rootpw);
$info["cn"]=$nom." ".$prenom;
$info["mail"]=$mail;
$info["telephonenumber"]=$tel;
$info["objectclass"]="person";
$r=ldap_add($ds,"cn=$nom $prenom,$racine",$info);
// fermeture de la connexion
ldap_close($ds);
$go==0;
$nom=="";
$prenom="";
$mail="";
$tel="";
à la page d'administration</A>\n";
} else {
if ($go==1)
echo "</TABLE>\n";
echo "</FORM>\n";
require("footer.php3");
?>
Regardons maintenant le source (plus long mais pas plus complexe !) de la page modifie.php3. Le nom
et le prénom étant concaténé dans le champ cn de l'annuaire, il sera impossible de faire une modification
sur le nom ou sur le prénom.
Pour modifier une personne, il faut d'abord la supprimer (avec ldap_delete()) puis la réenregistrer avec
les nouvelles valeurs.
Le champ mail est bien sûr toujours obligatoire. On utilise le même principe pour centraliser sur la même
page le formulaire de modification et le l'enregistrement des modifications (variable go).
<?
require("header.php3");
$cn=urldecode($cn);
// connexion au serveur
$ds=ldap_connect($server);
if ($ds==1)
$r=ldap_bind($ds,$rootdn,$rootpw);
$r=ldap_delete($ds,"cn=$cn,$racine");
$info["cn"]=$cn;
$info["mail"]=$mail;
$info["telephonenumber"]=$tel;
$info["objectclass"]="person";
$r=ldap_add($ds,"cn=$cn,$racine",$info);
ldap_close($ds);
$go==0;
$nom=="";
$prenom="";
$mail="";
$tel="";
} else {
if ($go==1)
// connexion au serveur
$ds=ldap_connect($server);
if ($ds)
$recherche="cn=$cn";
$num= ldap_get_entries($ds,$sr);
if ($num["count"]>0)
$mynom = $num[0]["cn"][0];
$myemail = $num[0]["mail"][0];
$mytel = $num[0]["telephonenumber"][0];
SIZE=40 maxlength=80><BR></TD></TR>\n";
SIZE=40 maxlength=255><BR></TD></TR>\n";
echo "</TABLE>\n";
echo "</FORM>\n";
} else {
} else {
require("footer.php3");
?>
Suppression d'une entrée de l'annuaire LDAP
On termine enfin avec la page supprime.php3 qui, avant de supprimer, va demander une confirmation.
<?
require("header.php3");
$cn=urldecode($cn);
if ($go==0) {
$cn=urlencode($cn);
else {
$cn=urldecode($cn);
$ds=ldap_connect($server);
if ($ds==1) {
$r=ldap_bind($ds,$rootdn,$rootpw);
$r=ldap_delete($ds,"cn=$cn,$racine");
require("footer.php3");
?>
Modification d'une entrée de l'annuaire LDAP
Vous voilà prêt à administrer votre annuaire... ou à construire votre propre interface d'administration.
Pour un souci de simplicité, seules les fonctionnalités de base ont été implémentées.
Une page pour rechercher une personne pourrait aussi être écrite.
La présentation de l'interface est sommaire mais assez pratique : toutefois, pour la page admin.php3, il
serait envisageable d'ajouter un alphabet qui lorsque l'on clique sur une lettre, déclenche l'affichage des
personnes dont le nom commence par la lettre sélectionnée.
De même, vous pouvez modifier aussi la structure de l'annuaire. Par exemple, vous pouvez ajouter des
propriétés à votre objet person : un champ photo qui pourrait contenir le chemin d'accès complet à une
photo d'identité stockée sur votre serveur...
Les sources sont commentés de façon à vous aider à concevoir de nouveaux programmes en PHP.