Vous êtes sur la page 1sur 106

COURS PHP

Introduction

Qu'est-ce que PHP?

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:

 Une grande communauté de développeurs partageant des centaines de milliers d'exemples de


script PHP ;
 La gratuité et la disponibilité du code source (PHP est distribué sous licence GNU GPL) ;
 La simplicité d'écriture de scripts ;
 La possibilité d'inclure le script PHP au sein d'une page HTML (contrairement aux scripts CGi,
pour lesquels il faut écrire des lignes de code pour afficher chaque ligne en langage HTML) ;
 La simplicité d'interfaçage avec des bases de données (de nombreux SGBD sont supportés, mais
le plus utilisé avec ce langage est MySQL, un SGBD gratuit disponible sur de nombreuses
plateformes : Unix, Linux, Windows, MacOs X, Solaris, etc...) ;
 L'intégration au sein de nombreux serveurs web (Apache, Microsoft IIS, etc.).

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.

SGBD supportés par PHP

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

Chapitre 1 : Implantation du code

L'interprétation du code par le serveur

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 serveur reconnait l'extension d'un fichier PHP et le transmet à l'interpréteur PHP


 Dès que l'interpréteur rencontre une balise indiquant que les lignes suivantes sont du code PHP,
il ne lit plus les instructions: il les exécute!
 L'interpréteur exécute l'instruction puis envoie les sorties éventuelles au serveur
 A la fin du script, le serveur transmet le résultat au client (le navigateur).
Un script PHP est interprété par le serveur, les utilisateurs ne peuvent donc pas voir le code
source!

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.

Implantation au sein du code HTML

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

Voici ci-dessous l'exemple classique de script PHP :

<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.

Chapitre 2 : Caractéristiques du langage

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! */

Il y a toutefois quelques règles à respecter:

 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.

Chapitre 3 Installation PHP

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.

L'installation suivante comprend l'installation de l'interpréteur PHP,


un langage de programmation
permettant de créer des pages créées dynamiquement, ainsi que le SGBD MySQL, un système
de gestion de bases de données relationnelles puissant fonctionnant sous Linux (et gratuit!).

Télécharger les sources


 Les sources de PHP peuvent être téléchargées sur le site http://www.php.net
 Les sources de Apache peuvent être téléchargées sur le site http://www.apache.org
 Les sources de MySQL peuvent être téléchargées sur le site http://www.mysql.org
installer Apache et PHP
1. Décompresser les archives:
2. tar zxvf apache_1.3.x.tar.gz
3.
tar zxvf php-3.0.x.tar
4. Configurer Apache
5. cd apache_1.3.x
6.
./configure --prefix=/www
7. Configurer PHP
8. cd ../php-3.0.x
9.
./configure --with-mysql --with-apache=../apache_1.3.x --enable-
track-vars
Si vous préférez installer PHP dans un autre répertoire, il faut utiliser l'option de configuration --
with-config-file-path=/path
10. Compiler PHP
11. make
12.
make install
13. Installer Apache
14. cd ../apache_1.3.x
15.
16. ./configure --prefix=/www
--activate-module=src/modules/php3/libphp3.a
17.
18. make
19.
make install
20. Modifier le fichier de configuration de PHP
21. cd ../php-3.0.x
22.
cp php3.ini-dist /usr/local/lib/php3.ini
Vous pouvez désormais éditer le fichier de configuration /usr/local/lib/php3.ini.
23. Editez le fichier de configuration du serveur apache (généralement httpd.conf ou srm.conf et
ajoutez la ligne suivante:
AddType application/x-httpd-php3 .php3

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

echo "PHP fonctionne!";

?>

</body>

</html>

Lancez un navigateur sur cette machine et entrez l'URL suivante:

http://localhost/toto.php3

localhost désigne la machine sur laquelle vous vous trouvez...

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 :

 Le serveur Web Apache


 Le moteur de scripts PHP4
 La base de données MySQL
 Un outil de gestion de base de donnée graphique, Phpmyadmin

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

Le pack EasyPHP est disponible sur les sites suivants :

 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</) :

L'installeur va ensuite vous demander de préciser le répertoire d'installation :


Puis il va demander la création d'un groupe dans le menu démarrer

Et enfin il va vous récapituler les


éléments de l'installation avant de procéder à la copie des fichiers.
Après la copie des fichiers, EasyPHP vous présente l'écran suivant indiquant que l'installation s'est
déroulée correctement

Il se peut lors de l'installation que l'installeur vous indique l'erreur suivante :

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.

Par exemple créez un fichier texte contenant le texte suivant :

<?
phpinfo();
?>

Puis renommez ce fichier en phpinfo.php3 et déposez-le dans le sous-répertoire /www.


Vous pouvez désormais visualiser le résultat à l'adresse suivante :
http://localhost/phpinfo.php3

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

Chapitre 4 Les variables en PHP

Concept de variable avec PHP

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

Avec PHP, les noms de variables doivent répondre à certains critères:

 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 $toto@mailcity.com 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

Le langage PHP propose trois types de variables scalaires:

 entiers: nombres naturels sans décimale (sans virgule)


 réels: nombres décimaux (on parle généralement de type double, car il s'agit de nombre
décimaux à double précision)
 chaines de caractères: ensembles de caractères
Il n'est pas nécessaire en PHP de typer les variables, c'est-à-dire de définir leur type, il suffit de leur
assigner une valeur pour en définir le type:
 entiers: nombre sans virgule
 réels: nombres avec une virgule (en réalité un point)
 chaines de caractères: ensembles de caractères entre guillemets simples ou doubles
Instruction Type de la variable
$Variable = 0; type entier
$Variable = 12; type entier
$Variable = 0.0; type réel
$Variable = 12.0; type réel
$Variable = "0.0"; type chaîne
$Variable = "Bonjour tout le monde"; type chaîne

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).

Chapitre 5 Les opérateurs

Qu'est-ce qu'un opérateur?

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:

 les opérateurs de calcul


 les opérateurs d'assignation
 les opérateurs d'incrémentation
 les opérateurs de comparaison
 les opérateurs logiques
 (les opérateurs bit-à-bit)
 (les opérateurs de rotation de bit)
Les opérateurs de calcul

Les opérateurs de calcul permettent de modifier mathématiquement la valeur d'une variable

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...

Les autres opérateurs du même type sont les suivants:

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

OpérateurDénomination Effet SyntaxeRésultat (avec x valant 7)


Augmente d'une unité la
++ Incrémentation $x++ 8
variable
-- DécrémentationDiminue d'une unité la variable $x-- 6
Les opérateurs de comparaison
Opérateur Dénomination Effet Exemple Résultat
==
A ne pas confondre avec Compare deux valeurs et Retourne 1 si $x est
opérateur d'égalité $x==3
le signe d'affectation vérifie leur égalité égal à 3, sinon 0
(=)!!
Vérifie qu'une variable est
opérateur Retourne 1 si $x est
< strictement inférieure à $x<3
d'infériorité stricte inférieur à 3, sinon 0
une valeur
Vérifie qu'une variable est Retourne 1 si $x est
opérateur
<= inférieure ou égale à une $x<=3 inférieur ou égale à
d'infériorité
valeur 3, sinon 0
Vérifie qu'une variable est
opérateur de Retourne 1 si $x est
> strictement supérieure à $x>3
supériorité stricte supérieur à 3, sinon 0
une valeur
Vérifie qu'une variable est Retourne 1 si $x est
opérateur de
>= supérieure ou égale à une $x>=3 supérieur ou égal à 3,
supériorité
valeur sinon 0
Retourne 1 si $x est
opérateur de Vérifie qu'une variable est
!= $x!=3 différent de 3, sinon
différence différente d'une valeur
0
Les opérateurs logiques (booléens)

Ce type d'opérateur permet de vérifier si plusieurs conditions sont vraies:

OpérateurDénomination Effet Syntaxe


|| ou OR OU logique Vérifie qu'une des conditions est réalisée ((condition1)||(condition2))
&& ou
ET logique Vérifie que toutes les conditions sont réalisées ((condition1)&&(condition2))
AND
Vérifie qu'une et une seule des conditions est
XOR OU exclusif ((condition1)XOR(condition2))
réalisée
Inverse l'état d'une variable booléenne
! NON logique (retourne la valeur 1 si la variable vaut 0, 0 si (!condition)
elle vaut 1)
(Les opérateurs bit-à-bit)

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.

Opérateur Dénomination Effet Syntaxe Résultat


Retourne 1 si les deux bits de même poids sont à 9 & 12 (1001 &
& ET bit-à-bit 8 (1000)
1 1100)
Retourne 1 si l'un ou l'autre des deux bits de 9 | 12 (1001 | 13
| OU bit-à-bit
même poids est à 1 (ou les deux) 1100) (1101)
Retourne 1 si l'un des deux bits de même poids 9 ^ 12 (1001 ^
^ OU exclusif 5 (0101)
est à 1 (mais pas les deux) 1100)
Complément
~ Retourne 1 si le bit est à 0 (et inversement) ~9 (~1001) 6 (0110)
(NON)
(Les opérateurs de rotation de bit)

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 suivants effectuent des rotations sur les bits,


c'est-à-dire qu'il décale chacun des bits
d'un nombre de bits vers la gauche ou vers la droite. La première opérande désigne la donnée
sur laquelle on va faire le décalage, la seconde désigne le nombre de bits duquel elle va être
décalée.

Opérateur Dénomination Effet Syntaxe Résultat


Décale les bits vers la gauche (multiplie par 2 à
chaque décalage). Les zéros qui sortent à 6 << 1 12
<< Rotation à gauche
gauche sont perdus, tandis que des zéros sont (110 << 1) (1100)
insérés à droite
Décale les bits vers la droite (divise par 2 à
6 >> 1
Rotation à droite avec chaque décalage). Les zéros qui sortent à droite
>> (0110 >> 3 (0011)
conservation du signe sont perdus, tandis que le bit non-nul de poids
1)
plus fort est recopié à gauche
Autres opérateurs

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:

Priorité des opérateurs


() []
-- ++ ! ~ -
* / %
+ -
< <= >= >
== !=
&
^
|
&&
||
? :
= += -= *= /= %= <<= >>= >>>= &= ^= |=
AND
XOR
Chapitre 6 : Structures conditionnelles

Qu'est-ce qu'une structure conditionnelle?

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.

La syntaxe de cette expression est la suivante:

if (condition réalisée) {

liste d'instructions

Remarques:

 la condition doit être entre des parenthèses


 il est possible de définir plusieurs conditions à remplir avec les opérateurs ET et OU (&& et ||)
par exemple l'instruction suivante teste si les deux conditions sont vraies :
if ((condition1)&&(condition2))
L'instruction ci-dessous exécutera les instructions si l'une ou l'autre des deux conditions est vraie
:
if ((condition1)||(condition2))
 s'il n'y a qu'une instruction, les accolades ne sont pas nécessaires...
L'instruction if ... else

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.

La syntaxe de cette expression est la suivante:

if (condition réalisée) {

liste d'instructions

}
else {

autre série d'instructions

L'instruction if ... elseif ... 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.

La syntaxe de cette expression est la suivante:

if (condition réalisée) {

liste d'instructions

elseif (autre condition réalisée) {

autre série d'instructions

...

else (dernière condition réalisée) {

série d'instructions

une façon plus courte de faire un test (opérateur ternaire)

Il est possible de faire un test avec une structure beaucoup moins lourde grâce à la structure suivante,
appelée opérateur ternaire:

(condition) ? instruction si vrai : instruction si faux

Remarques:

 la condition doit être entre des parenthèses


 Lorsque la condition est vraie, l'instruction de gauche est exécutée
 Lorsque la condition est fausse, l'instruction de droite est exécutée
L'instruction switch

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.

La syntaxe de cette expression est la suivante:

for (compteur; condition; modification du compteur) {

liste d'instructions

Par exemple:
for ($i=1; $i<6; $i++) {

echo "$i<br>";

Cette boucle affiche 5 fois la valeur de $i, c'est-à-dire 1,2,3,4,5


Elle commence à $i=1, vérifie que $i est bien inférieur à 6, etc... jusqu'à atteindre la valeur $i=6, pour
laquelle la condition ne sera plus réalisée, la boucle s'interrompra et le programme continuera son cours.

D'autre part, le langage PHP autorise la déclaration de la variable de boucle dans l'instruction for elle-
même!

Par exemple:

for ($i=0; $i<10; $i++) {

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.

La syntaxe de cette expression est la suivante:

while (condition réalisée) {

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) {

echo "Division par zéro!";

continue;

$a = 1/($x-7);

echo "$a<br>";

$x++;

Il y avait une erreur dans ce programme... peut-être ne l'avez-vous pas vue:


Lorsque $x est égal à 7, le compteur ne s'incrémente plus, il reste constamment à la valeur 7, il aurait
fallu écrire:

$x=1;

while ($x<=10) {

if ($x == 7) {

echo "division par 0";

$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) {

echo "division par 0";

break;

echo "1/$a<br>";

Arrêt d'exécution du script

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!

Chapitre 7 Les fonctions

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...).

La déclaration d'une fonction

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:

function Nom_De_La_Fonction(argument1, argument2, ...) {

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.

La syntaxe de l'instruction return est simple:

return valeur_ou_variable;

Les arguments d'une fonction

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')

if(empty($qui)){ // $qui est vide, on retourne faux

return false;

}else{

echo "$texte $qui"; // on affiche le texte

return true; // fonction exécutée avec succès

?>

Ainsi cette fonction peut être appelée de deux façons différentes:

<?

// Passage des deux paramètres

dire_texte("cher phpeur", "Bienvenue"); // affiche "Bienvenue cher phpeur"

// Utilisation de la valeur par défaut du deuxième paramètre

dire_texte("cher phpeur"); // affiche "Bonjour cher phpeur"

?>

Travailler sur des variables dans les fonctions

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
<?

$chaine = "Nombre de camions : ";

function ajoute_camion($mode='')

global $chaine;

static $nb=0;

$nb++; // on incrémente le nombre de camions

if($mode == "affiche"){

echo $chaine.$nb; // on affiche le nombre de camions

ajoute_camion(); // nb == 1

ajoute_camion(); // nb == 2

ajoute_camion(); // nb == 3

ajoute_camion("affiche"); // affiche Nombre de camions : 4

?>

Passage de paramètre par référence

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.

<?

function dire_texte($qui, &$texte)

$texte = "Bienvenue $qui";

}
$chaine = "Bonjour ";

dire_texte("cher phpeur",$chaine);

echo $chaine; // affiche "Bienvenue cher phpeur"

?>

Retourner plusieurs variables

Lorsque vous souhaitez qu'une fonction retourne plusieurs valeurs, le plus simple est d'utiliser un
tableau.

<?

function nom_fonction()

.....

return array( $variable1, $variable2, $variable3 );

// on retourne les valeurs voulues dans un tableau

$retour = nom_fonction();

echo "$retour[0] - $retour[1] - $retour[2]";

?>

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++;

echo "$n <br>";

if($n < 10){ // si n est inférieur à 10 on continue

fonction_recursive($n);

fonction_recursive(); // affiche les nb de 1 à 10


?>

Chapitre 8 : Les classes

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).

Une classe est composée de deux parties:

 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 {

// Déclarations des données membres

var $Donnee_Membre_1;

var $Donnee_Membre_2;

var $...

// Déclarations des méthodes

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.

Contrairement à la déclaration de classes en C++, la déclaration de la classe ne se finit pas par


un point-virgule!

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:

$Nom_de_l_objet = new Nom_de_la_classe;

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.

Accéder aux propriétés d'un objet

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;

Accéder aux méthodes d'un objet

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,...);

La variable courante $this

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;

$toto_test = new Toto;


$toto_test->DefineTotoAge(10);

echo "L'age de TOTO : " . $toto_test->age . "<br/>";

Les limitations de l'utilisation de classes avec Php

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

Chapitre 9 Envoie de textes au navigateur

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.

Les trois fonctions standards

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

// et stockage dans une variable

$MaDate = date("Y");

echo "Nous sommes en $MaDate";

?>

</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:

printf (chaîne formattée);

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:

Code Type de format


%b Entier en notation binaire
%c Caractère codé par son code ASCII
%d Entier en notation décimale
%e Type double (nombre à virgule) au format scientifique (1.76e+3)
%f Type double (nombre à virgule)
%o Entier en notation octale
%s Chaîne de caractères
%x Entier en notation hexadécimale (lettres en minuscules)
%X Entier en notation hexadécimale (lettres en majuscules)
%% Caractère %

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;

$Perimetre = 2 * $Pi * $R;

printf ("Le périmètre du cercle est %d",$Perimetre);


L'importance de l'implantation du code php au sein du code HTML

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.

Chapitre 9 Variable d’environnements

Notion de variable d'environnement

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,...

Les variables d'environnement

On peut donc classer les variables d'environnement en deux catégories:

 Les variables d'environnement dépendant du client


 Les variables d'environnement dépendant du serveur
Les variables d'environnement dépendant du client
Variable
Description
d'environnement
Il s'agit de la méthode d'authentification qui a été utilisée par le client pour
$AUTH_TYPE
accéder au script PHP
$COMSPEC Location de l'interpréteur de commandes sur la machine (Sous Windows)
Type de données contenu présent dans le corps de la requête. Il s'agit du
$CONTENT_TYPE
type MIME des données
$DOCUMENT_ROOT Racine des documents sur le serveur
$DOCUMENT_URI Adresse du script PHP en relatif (à partir de la racine du serveur)
$HTTP_ACCEPT Types MIME reconnus par le serveur (séparés par des virgules)
$HTTP_ACCEPT_ENCODING Types d'encodage que le serveur peut réaliser (gzip,deflate)
$HTTP_ACCEPT_LANGUAGE Langue utilisée par le serveur (par défaut en-us)
Type de connexion ouverte entre le client et le serveur (par exemple Keep-
$HTTP_CONNECTION
Alive)
$HTTP_HOST Nom d'hôte de la machine du client (associée à l'adresse IP)
$HTTP_REFERER URL de la page qui a appelé le script PHP
Cette variable permet d'avoir des informations sur le type de navigateur
utilisé par le client, ainsi que son système d'exploitation. Voici quelques
exemples de User-Agents:
 Mozilla/4.0 (compatible;
 MSIE 5.01;
$HTTP_USER_AGENT  Windows NT;
 TUCOWS Network)
 Mozilla/4.7 [en] (X11;
 I;
 Linux 2.2.14-15mdk i686)
$LAST_MODIFIED Date et heure de dernière modification du fichier
$PATH Il s'agit du chemin d'accès aux différents répertoires sur le serveur
Il s'agit du chemin d'accès au script PHP en relatif (de la racine du serveur
$PATH_INFO
jusqu'au script PHP)
$PHP_SELF Nom du script PHP
$REDIRECT_STATUS Il s'agit de l'état de la redirection (echec ou succès)
$REDIRECT_URL Il s'agit de l'URL vers laquelle le navigateur du client a été redirigé
Il s'agit de la partie de l'URL (ayant servi à accéder au script PHP) située
$QUERY_STRING après le point d'interrogation. C'est de cette manière que sont transmises les
données d'un formulaire dans le cas de la méthode GET
$REMOTE_ADDR Cette variable contient l'adresse IP du client appelant le script CGI
Cette variable permet de savoir le port sur lequel la requête HTTP a été
$REMOTE_PORT
envoyée au serveur
Chemin d'accès complet au script PHP
$SCRIPT_FILENAME  Sous windows, il sera de la forme:
c:/php/php.exe
Chemin d'accès relatif (par rapport au chemin d'accès à la racine web
$SCRIPT_NAME
($DOCUMENT_ROOT)) au script PHP
Les variables d'environnement dépendant du serveur
Variable d'environnement Description
$DATE_GMT Date actuelle au format GMT
$DATE_LOCAL Date actuelle au format local
$DOCUMENT_ROOT Racine des documents Web sur le serveur
$GATEWAY_INTERFACE Version des spécifications CGI utilisées par le serveur
$HTTP_HOST Nom de domaine du serveur
$SERVER_ADDR Adresse IP du serveur
$SERVER_ADMIN Adresse de l'administrateur du serveur
$SERVER_NAME Nom donné au serveur en local
$SERVER_PORT Numéro de port associé au protocole HTTP sur le serveur
$SERVER_PROTOCOL Nom et version du protocole utilisé pour envoyer la requête au script PHP
$SERVER_SOFTWARE Type (logiciel) du serveur web
 Pour un serveur Apache sous Unix:
Apache/1.3.2 (Unix) PHP/3.0.5
 Pour un serveur Apache sous Windows:
Apache/1.3.2 (Win32) PHP/3.0.5
Affichage des variables d'environnement

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");

?>

Enfin il est possible de définir des variables d'environnement:

<?

echo putenv("MA_VARIABLE=mavaleur");

?>

Chapitre 10 Fichiers et repertoires

La gestion des fichiers avec PHP

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 :

entier fopen(chaine nomdufichier, chaine mode);

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:

 r (comme read) indique une ouverture en lecture seulement


 w (comme write) indique une ouverture en écriture seulement (la fonction crée le fichier s'il
n'existe pas)
 a (comme append) indique une ouverture en écriture seulement avec ajout du contenu à la fin
du fichier (la fonction crée le fichier s'il n'existe pas)
Lorsque le mode est suivi du caractère + celui-ci peut être lu et écrit. Enfin, le fait de faire suivre le
entre crochets indique que le fichier est traité de façon binaire.
mode par la lettre b
Voici un tableau récapitulant l'ensemble des modes de fichiers possibles:
Mode Description

r ouverture en lecture seulement

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)

r+ ouverture en lecture et écriture

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)

Voici des exemples d'utilisations possibles de cette fonction:

$fp = fopen("../fichier.txt","r"); //lecture

//écriture depuis début du fichier

$fp = fopen("ftp://phpfrance.com/pub/fichier.txt","w");

//écriture depuis fin du fichier

$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:

<?

$fp = fopen("http://www.commentcamarche.net","r"); //lecture du fichier

while (!feof($fp)) { //on parcourt toutes les lignes

$page .= fgets($fp, 4096); // lecture du contenu de la ligne

?>

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")) {

echo "Echec de l'ouverture du fichier";

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")) {

echo "Echec de l'ouverture du fichier";

exit;

else {

while(!feof($fp)) {
// On récupère une ligne

$Ligne = fgets($fp,255);

// On affiche la ligne

echo $Ligne;

// On stocke l'ensemble des lignes dans une variable

$Fichier .= $Ligne;

fclose($fp); // On ferme le fichier

?>

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à).

<?

$fp = fopen("php_8_fichier.txt","a"); // ouverture du fichier en écriture

fputs($fp, "\n"); // on va a la ligne

fputs($fp, "$nom|$email"); // on écrit le nom et email dans le fichier

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.

<?

$fp = fopen("http://www.commentcamarche.net","r"); //lecture du fichier

while (!feof($fp)) { //on parcourt toutes les lignes

$page .= fgets($fp, 4096); // lecture du contenu de la ligne

$titre = eregi("<title>(.*)</title>",$page,$regs); //on isole le titre

echo $regs[1];

fclose($fp);

?>

Les tests de fichiers

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")) {

echo "Il ne s'agit pas d'un répertoire


";

else {

echo "Il s'agit bien d'un répertoire


";

?>

 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 :

Tableau file(chaine nomdufichier);

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)) {

for($i = 0; $i < count($TabFich); $i++)


echo $TabFich[$i];

else {

echo "Le fichier ne peut être lu...<br>";

else {

echo "Désolé le fichier n'est pas valide<br>";

?>

La fonction fpassthru() permet d'envoyer le contenu du fichier dans la fenêtre du navigateur. La


syntaxe de cette fonction est la suivante:

booléen fpassthru(entier etat);


Cette fonction permet en réalité d'envoyer le contenu du fichier à partir de la position courante dans le
fichier, c'est-à-dire qu'il est possible par exemple de lire quelques lignes avec fgets(), puis d'envoyer le
reste au navigateur... Le script suivant permet de parcourir tous les fichiers HTML contenus dans votre
site et d'en afficher l'arborescence :
<HTML>
<HEAD>
<TITLE>Affichage de l'arborescence</TITLE>
</HEAD>
<BODY>

<?

function ScanDir($Directory){

if (is_dir($Directory) && is_readable($Directory)) {

if($MyDirectory = opendir($Directory)) {

while($Entry = readdir($MyDirectory)) {

if (is_dir($Directory."/".$Entry)) {

if (($Entry != ".") && ($Entry != "..")) {

echo "<li><b>Repertoire</b>: $Directory/$Entry</li>\n";


echo "<ul>";
ScanDir($Directory."/".$Entry);
echo "</ul>";

else {

echo "<li><b>Fichier</b>: $Directory/$Entry </li>\n";


if (eregi("(\.html)|(\.htm)",$Entry)){

$MetaTags = get_meta_tags($Directory."/".$Entry);

}
closedir($MyDirectory);

$open_basedir=".";

echo "<ul>";
ScanDir(".");
echo "</ul>";

?>
</BODY>
</HTML>

Chapitre 11 : Récupération des données

PHP rend très simple la récupération de données envoyées par l'intermédiaire de formulaires HTML.

Création d'un formulaire

Grâce à la balise FORM du langage HTML, il est très simple de créer des formulaires comprenant:

 des champs de saisie


 des cases à cocher
 des boutons radio
 des listes à choix multiples
 des champs "hidden" (cachés) pour transmettre certaines informations
 ...
Pour utiliser un tel formulaire capable d'envoyer des informations à un script PHP, il suffit de mettre le
nom du fichier PHP qui réceptionnera les informations en tant que valeur de l'attribut ACTION de la balise
FORM.

Voici ce à quoi peut ressembler un formulaire en HTML, permettant d'envoyer les coordonnées d'une
personne à un fichier PHP nommé test.php3:

<FORM Method="POST" Action="test.php3">

Nom : <INPUT type=text size=20 name=nom><BR>

Prénom : <INPUT type=text size=20 name=prenom><BR>

Age : <INPUT type=text size=2 name=age><BR>

<INPUT type=submit value=Envoyer>

<INPUT type=hidden name=afficher value=ok>


</FORM>

Le résultat de ce code est le suivant (le bouton Envoyer est volontairement désactivé):

Nom :

Prénom :

Age :

Récupération et utilisation des données

Note sur les variables globales

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.

Avec les variables globales activées

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).

Exemple (d'après le formulaire précédent), sur la page test.php3, on aura :

$nom = 'le_contenu_du_champ_nom'
$prenom = 'le_contenu_du_champ_prenom'
$age = 'le_contenu_du_champ_age'
$afficher = 'ok'

Cette page test.php3 affichera donc le contenu des champs :

<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.

Variables gobales désactivées

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 {

echo "Récapitulatif des informations saisies<BR>\n


<UL>
<LI>Nom: $nom</LI>
<LI>Prenom: $prenom</LI>
<LI>Age: $age</LI>
</UL>
";

}
}
else {
echo "<p>Vous n'avez pas demandé que les informations soient affichées.<p>"
}

?>

</BODY>
</HTML>

Chapitre 12 Base de Données

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 déclaration des variables

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:

 $user : Le nom d'utilisateur


 $passwd : Le mot de passe
 $host : L'hôte (ordinateur sur lequel le SGBD est installé)
 $bdd : Le nom de la base de données
Rappel: Les variables ne sont pas visibles par vos visiteurs étant donné que le script (portant
l'extension .php3) est systématiquement interprété par le serveur Web

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.

Les fonctions de base

Php fournit un grand choix de fonctions permettant de manipuler les bases de données. Toutefois, parmi
celles-ci quatre fonctions sont essentielles:

 La fonction de connexion au serveur


 La fonction de choix de la base de données
 La fonction de requête
 La fonction de déconnexion
Avec le SGBD MySQL, ces fonctions sont les suivantes:
 mysql_connect
 mysql_select_db
 mysql_query
 mysql_close
Gestion des erreurs

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:

 Le stockage du résultat de l'exécution de la fonction dans une variable. Par exemple:


$connect = mysql_connect($host,$user,$passwd);
 L'utilisation de la fonction die() en cas d'erreur d'exécution. Si la fonction retourne la valeur 0
(c'est-à-dire s'il y a une erreur) la fonction die() (traduisez meurt) renvoie un message d'erreur.
Par exemple:
 mysql_connect($host,$user,$passwd)
or die("erreur de connexion au serveur $host");
Traitement des résultats

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>

<table border="1" cellpadding="0" cellspacing="0">

<tr>

<th>Nom du site</th>
<th>URL</th>

</tr>

<?php

// Déclaration des paramètres de connexion

$host = la_machine;

// Généralement la machine est localhost

// c'est-a-dire la machine sur laquelle le script est hébergé

$user = votre_login;

$bdd = Nom_de_la_base_de_donnees;

$passwd = Mot_de_passe;

// Connexion au serveur

mysql_connect($host, $user,$passwd) or die("erreur de connexion au serveur");

mysql_select_db($bdd) or die("erreur de connexion a la base de donnees");

// Creation et envoi de la requete

$query = "SELECT nom,url FROM sites ORDER BY nom";

$result = mysql_query($query);

// Recuperation des resultats

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";

// Deconnexion de la base de donnees

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.

Détecter un résultat nul

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

// Déclaration des paramètres de connexion

$host = la_machine;

// Généralement la machine est localhost

// c'est-a-dire la machine sur laquelle le script est hébergé

$user = votre_login;

$bdd = Nom_de_la_base_de_donnees;

$passwd = Mot_de_passe;

// Connexion au serveur

mysql_connect($host, $user,$passwd) or die("erreur de connexion au serveur");

mysql_select_db($bdd) or die("erreur de connexion a la base de donnees");

// Creation et envoi de la requete

$query = "SELECT nom,url FROM sites ORDER BY nom";

$result = mysql_query($query);

// Recuperation des resultats

if (!mysql_fetch_row($result)) {

echo "Aucun enregitrement ne correspond\n";

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";

// Deconnexion de la base de donnees

mysql_close();

?>
Chapitre 13 : Expressions régulières

Qu'est-ce qu'une expression régulière?

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...

Construire une expression régulière

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.

"^debut": chaîne qui commence par "debut"

"fin$": chaîne qui se termine par "fin"

"^chaîne$": chaîne qui commence et se termine par "chaîne"

"abc": chaîne contenant la chaîne "abc"

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+": chaîne commençant par "ab" suivie de un ou plusieurs "c" ("abc",


"abcc" ...)

Les accolades {X,Y} permettent de donner des limites de nombre.

"abc{2}": chaîne qui contient "ab" suivie de deux "c" ("abcc")

"abc{2,}": chaîne qui contient "ab" suivie de deux "c" ou plus ("abcc" etc..)

"abc{2,4}": chaîne qui contient "ab" suivie 2, 3 ou 4 "c" ("abcc" .. "abcccc")

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 parenthèses ( ) permettent de représenter une séquence de caractères.

"a(bc)*": chaîne qui contient "a" suivie de zero "bc" ou plus


La barre verticale | se comporte en tant qu'opérateur OU

"un|le": chaîne qui contient "un" ou "le"

"(un|le) chien": chaîne qui contient "un chien" ou "le chien"

"(a|b)*": chaîne qui contient une suite de "a" ou de "b"

Le point . indique n'importe quel caractère (une fois)

"^.{3}$": chaîne qui contient 3 caractères

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.

"[abc]": chaîne qui contient un "a", un "b", ou un "c"

"[a-z]": chaîne qui contient un caractère compris entre "a" et "z"

"^[a-zA-Z]": chaîne qui commence par une lettre

"^[^a-zA-Z]": chaîne qui ne commence pas par une lettre

 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.

"[\+?{}.]": chaîne qui contient un de ces six caractères

"[]-]": chaîne qui contient le caractère "]" ou le caractère "-"

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 .. "

Les classes de caractères


Il peut également être utile de vérifier si une chaîne contient des caractères d'un certain type
(numérique, alphanumérique, ...) sans avoir à les énumérer. Pour cela les expressions régulières
définissent des classes de caractères, dont la syntaxe est:

[: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 :

chaîne composée d'un ou plusieurs caractère(s) alphanumérique(s)

"^[: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.

Les fonctions ereg() et eregi()

La fonction ereg() dont la signature est la suivante :


Booleen ereg(chaîne modele,chaîne texte[,tableau occurrences])
permet d'évaluer le texte passer en argument grâce au modèle (qui est une expression régulière) et
stocke toutes les occurrences dans un tableau passé optionnellement en paramètre. Lorsque la fonction
trouve des occurrences, elle renvoie true, sinon elle retourne false.

La fonction eregi() dont la signature est la suivante :


Booleen eregi(chaîne modele,chaîne texte[,tableau occurrences])
effectue le même travail que sa consoeur ereg(), à la différence près qu'elle n'est pas sensible à la casse
(pas de différenciation minuscules/majuscules)

<?

$fp = fopen("http://www.commentcamarche.net","r"); //lecture du fichier

while (!feof($fp)) { //on parcoure toutes les lignes

$page .= fgets($fp, 4096); // lecture du contenu de la ligne


}

$titre = eregi("<title>(.*)</title>",$page,$regs); //on isole le titre

/* Le titre commence par <title>,

puis contient n'importe quelle chaîne,

et se termine par </title> */

echo $regs[1]; // on retourne la premiere occurrence trouvée

// Les occurrences se trouvent entre parenthèses

// $regs[0] renvoie toute la chaîne

fclose($fp);

?>

Les fonctions ereg_replace() et eregi_replace()

La fonction ereg_replace() dont la signature est la suivante :


chaîne ereg_replace(chaîne modele,chaîne remplacement,chaîne texte)
Permet de retourner la chaîne texte passée en arguments avec les occurrences trouvees remplacées par
la chaîne de remplacement.
Pour utiliser les occurrences correspondant au modele dans la chaîne de remplacement, il suffit d'utiliser
des parenthèses dans la chaîne modele, puis de faire référence à ces éléments dans la chaîne de
remplacement en utilisant deux signes antislash suivi d'un numéro identifiant l'élément entre 0 et 9 (les
numéros sont donnés par ordre d'imbriquement, puis de gauche à droite, le zéro représente la chaîne
entière).
Le code suivant remplace Toto par <b>Toti Toto</b>... inutile mais formateur.

$Texte = "Bienvenue a Toto dans le mondes des expressions régulières";

$Texte = ereg_replace("To(to)","<b>\\1ti \\0</b>",$Texte);

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 = "Bienvenue sur http://www.commentcamarche.net cher ami";

$Texte = ereg_replace("(http://)(([[:punct:]]|[[:alnum:]])*)",
"<a href=\"\\0\">\\2</a>",$Texte);

La fonction eregi_replace() dont la signature est la suivante :


chaîne eregi_replace(chaîne modele,chaîne remplacement,chaîne texte)
effectue le même travail que sa consoeur ereg_replace(),
à la différence près qu'elle n'est pas
sensible à la casse (pas de différenciation minuscules/majuscules).

La fonction split()

La fonction split() possède la syntaxe suivante:

tableau split (chaîne expression, chaîne texte [, entier limite])

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.
<?

// découpe une phrase en un tableau de mots

// on utilise split au cas ou plusieurs espaces séparent les mots

$phrase = "Ceci est une phrase avec trois espaces ici";

$tableau_mots = split(" +",trim($phrase)); // un espace ou plus

?>

La fonction sql_regcase()

La fonction sql_regcase() possède la syntaxe suivante:

chaîne sql_regcase (chaîne texte)

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 ;)

<?

echo sql_regcase("un test");

// affiche [Uu][Nn][ ][Tt][Ee][Ss][Tt]

?>

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");

$sql = "SELECT * from table WHERE champ REGEXP \"[[:<:]]$motclef[[:>:]]\"";

// selectionne tous les enregistrements de la table table, contenant le MOT motclef

?>

Chapitre 14 : Génération d’images en PHP

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.

booléen imagegif(entier image, chaîne NomDuFichier);

 La fonction imagegif() ne fonctionne pas avec PHP4


 Notez que vous pouvez utiliser imagepng() et imagejpg()!

La fonction imagecreate() permet de créer un identifiant pour une image vierge possèdant les
dimensions indiquées en paramètres.

entier imagecreate(entier largeur,entier hauteur);

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.

entier createimagefromgif(chaîne NomDuFichier);

Enfin la fonction imagedestroy() permet de vider la mémoire allouée à l'image dont on a passé
l'identifiant en paramètre.

booléen imagedestroy(entier image);

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 majeure partie des fonctions de la librairie GD permettent de créer une image,


 en dessinant des formes (trait, rectangle, cercle, ...)
 en allouant des couleurs à l'image
 en dessinant des chaînes de caractères
 ...

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).

entier imagecolorallocate(entier image, entier rouge,entier vert, entier bleu);

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 tableau présentant les fonctions de génération de forme:


Fonction Description
Crée un arc de centre (x,y) dont la largeur et la hauteur
imagearc(entier image,entier x,entier y,entier
sont en pixels. Début et fin représentent les angles de
largeur,entier hauteur,entier début,entier
début et de fin (le degré 0 est à trois heures) en
fin,entier couleur)
tournant dans le sens des aiguilles d'un montre
imagedashedline(entier image,entier
Trace un trait pointillé entre les points (xdebut,ydebut)
xdebut,entier ydebut,entier xfin,entier yfin,entier
et (xfin,yfin) de la couleur spécifiée
couleur)
Crée un polygone de la couleur spécifiée, dont les
imagefilledpolygon(entier image,tableau points sont stockes dans un tableau de valeurs (x,y). Le
coordonnees,entier nonbre,entier couleur) nombre de points du tableau à utiliser est spécifié en
paramètre nombre
imagefilledrectangle(entier image,entier Crée un rectangle rempli avec la couleur spécifiée, et
xgauchehaut,entier ygauchehaut,entier dont les coins supérieur gauche et inférieur droit sont
xdroitebas,entier ydroitebas,entier couleur) spécifiés en argument
imageline(entier image,entier xdebut,entier Trace un trait entre les points (xdebut,ydebut) et
ydebut,entier xfin,entier yfin,entier couleur) (xfin,yfin) de la couleur spécifiée
Crée un polygone non rempli dont le contour est de la
imagepolygon(entier image,tableau couleur spécifiée, dont les points sont stockes dans un
coordonnees,entier nonbre,entier couleur) tableau de valeurs (x,y). Le nombre de points du
tableau à utiliser est spécifié en paramètre nombre
imagerectangle(entier image,entier Crée un rectangle nom rempli dont le contour est de la
xgauchehaut,entier ygauchehaut,entier couleur spécifiée, et dont les coins supérieur gauche et
xdroitebas,entier ydroitebas,entier couleur) inférieur droit sont spécifiés en argument

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() :

booléen imagestring(entier image,


entier police,
entier x,
entier y,
chaine texte,
entier couleur);

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() :

Entier imageloadfont(chaîne Nom_du_Fichier);

Le format du fichier de police passé en paramètre peut varier selon le système sur lequel PHP
fonctionne...

Enfin, les fonctions imagefontwidth() et imagefontheight() renvoient la largeur et la hauteur de la


police passée en unique paramètre. Ainsi, il est facile de connaître le nombre de pixels que va occuper la
chaîne entière:
$largeur = imagefontwidth($police) * strlen($text);

$hauteur = imagefontheight($police);

Voici un tableau présentant les fonctions de création de chaînes de caractères graphiques:

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")

Voici le code PHP:

<?

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++;

if( (!ereg("3(\.)([0-9]+) (\[)([a-z]+)(\])(.*)$",$row[0]))

&&(!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));

function circle_point($degrees, $diameter)

$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);

$ChartData2 = array($netscape3=>"Netscape 3",

$netscape4=>"Netscape 4",

$ie3=>"Internet Exploreur 3",

$ie4=>"Internet Exploreur 4",

$ie5=>"Internet Exploreur 5",

$autre=>"Autres Navigateurs");

$ChartWidth = $ChartDiameter + 20 + ($ChartFontWidth * 40);

$ChartHeight = $ChartDiameter + 20;

rsort($ChartData);

arsort($ChartData2);
$ChartCenterX = $ChartDiameter/2 + 10;

$ChartCenterY = $ChartDiameter/2 + 10;

$image = imagecreate($ChartWidth, $ChartHeight);

$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;

for($index=0; $index < count($ChartData); $index++)

$ChartDataReel=(int)($ChartData[$index]/10);

if( $ChartDataReel !=0)

$StartDegrees = round($Degrees);

$Degrees+= (($ChartDataReel/$total)*360);

$EndDegrees = round($Degrees);

$CurrentColor = $colorSlice[$index%(count($colorSlice))];

imagearc($image, $ChartCenterX, $ChartCenterY, $ChartDiameter,

$ChartDiameter, $StartDegrees, $EndDegrees, $CurrentColor);

list($ArcX, $ArcY) = circle_point($StartDegrees, $ChartDiameter);

imageline($image, $ChartCenterX, $ChartCenterY,

floor($ChartCenterX + $ArcX),

floor($ChartCenterY + $ArcY), $CurrentColor);

list($ArcX, $ArcY) = circle_point($EndDegrees, $ChartDiameter);

imageline($image, $ChartCenterX, $ChartCenterY,

floor($ChartCenterX + $ArcX),
floor($ChartCenterY + $ArcY), $CurrentColor);

$MidPoint = round((($EndDegrees - $StartDegrees)/2) +


$StartDegrees);

list($ArcX, $ArcY) = circle_point($MidPoint, $ChartDiameter/2);

imagefilltoborder($image, floor($ChartCenterX + $ArcX),

floor($ChartCenterY + $ArcY), $CurrentColor, $CurrentColor);

imagearc($image, $ChartCenterX, $ChartCenterY, $ChartDiameter,

$ChartDiameter, 0, 360, $colorBorder);

for($index=0; $index < count($ChartData); $index++)

$CurrentColor = $colorSlice[$index%(count($colorSlice))];

$LineX = $ChartDiameter + 20;

$LineY = 30 + ($index*($ChartFontHeight + 2));

imagerectangle($image, $LineX, $LineY, $LineX +

$ChartFontHeight, $LineY + $ChartFontHeight, $colorBorder);

imagefilltoborder($image, $LineX + 2,

$LineY + 2, $colorBorder, $CurrentColor);

$valeur=(int)($ChartData[$index]/10);

$valeur2=$ChartData[$index];

$pourcentage=round(($valeur/$total)*100);

imagestring($image, $ChartFont, $LineX + 5 + $ChartFontHeight,

$LineY, "$ChartData2[$valeur2]", $colorText);

imagestring($image, $ChartFont, $LineX + 5 + $ChartFontHeight+

23*$ChartFontWidth, $LineY, "$valeur", $colorText);

imagestring($image, $ChartFont, $LineX + 5 + $ChartFontHeight+

31*$ChartFontWidth, $LineY, "$pourcentage %", $colorText);

imagegif($image);

?>
Chapitre 15 : Entêtes http et Cookies

Les en-têtes HTTP

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:

booléen header(chaîne en-tête HTTP)

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())

Voici quelques utilisations possibles de la fonction header():

 pour rediriger le navigateur vers une nouvelle page:



 <?

 header("location: http://www.commentcamarche.net/");

 ?>

 Pour envoyer au navigateur une image créé à la volée (pour faire un compteur de statistiques ou
bien un histogramme dynamique par exemple) :

 <?

 header("Content-Type: image/gif");

 // code générant l'image

 imagegif($image); // envoi de l'image au navigateur

 ?>
Récupérer les en-têtes de la requête

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"];

?>

Présentation des cookies

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:

booléen setcookie(chaîne NomDuCookie,

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.

Les arguments suivants servent à déterminer les conditions de validité du cookie:

 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);

?>

Quelques autres exemples:

<?php

// Envoi d'un cookie qui disparaîtra après la fermeture du navigateur

SetCookie("CcmUserSessionCookie","$login:$pass");

// Envoi d'un cookie qui restera présent 24 heures

SetCookie("CcmDejaVisite","1",time()+3600*24,"/",".phpfrance.com",0);

// Envoi d'un cookie qui s'effacera le 1er janvier 2001

SetCookie("CcmAn2000","1",mktime(0,0,0,1,1,2001),"/",".phpfrance.com",0);
?>

Récupérer les valeurs d'un cookie

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);

?>

Quelques réalisations avec les cookies

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...

Chapitre 16 : Fonction Mail et IMAP

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

Entier mail(chaîne email_destinataire,

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?>

<h4>Merci <?echo $nom;??></h4?>

<?

echo "<p>Votre commentaire : $texte</p?>";

mail(

"webmaster@commentcamarche.net",

"Commentaire sur CCM",

"$nom a laissé un commentaire à propos de commentcamarche.net: \n\n$texte"

);

?>

</body?>

</html?>

Les \n à l'intérieur du corps de m'email permettent d'aller à la ligne


Chez certains hébergeurs (dont Free) la fonction mail est désactivée car elle permet de simuler
un envoi de mail à partir de n'importe quelle adresse. Ainsi elle est parfois remplacée par la
fonction email()
Les options / en-têtes
Le champ options de la fonction mail permet d'ajouter une en-tête au message que l'on envoie. On peut
par exemple y mettre la date, le logiciel utilisé pour envoyer l'email ou encore l'adresse de retour...
Voilà un exemple d'en-tête à utiliser lors d'un envoi de mail :

$from_email = "contact@phpfrance.com";

$entetedate = date("D, j M Y H:i:s -0600"); // Offset horaire

$entetemail = "From: $from_email \n"; // Adresse expéditeur

$entetemail .= "Cc: \n";

$entetemail .= "Bcc: \n"; // Copies cachées

$entetemail .= "Reply-To: $from_email \n"; // Adresse de retour

$entetemail .= "X-Mailer: PHP/" . phpversion() . "\n" ;

$entetemail .= "Date: $entetedate";

La commande précédente équivaut donc à :

mail(

"webmaster@commentcamarche.net",

"Commentaire sur commentcamarche.net",

"$nom a laissé un commentaire à propos de commentcamarche.net: \n\n$texte",

$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(chaîne compte,chaîne destinataire,chaîne titre,chaîne message[,options]);

Voici un exemple d'utilisation du site à partir du compte webmaster pour le domaine


commentcamarche.net:

email("webmaster",

"toto@wanadoux.fr",

"Bonjour Toto",

"Salut Toto\nvoici ton message");

Les fonctions IMAP

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:

Entier imap_open(chaîne boîte,

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",

"newsletter@commentcamarche.net",

"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:

Entier imap_check(chaîne Boîte);

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:

Objet imap_header(entier Boîte,

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.

Entier imap_num_msg(entier boîte);

Ainsi le script suivant permet d'afficher les mails contenus dans la boîte INBOX du compte
newsletter@commentcamarche.net 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",

"newsletter@commentcamarche.net",

"password");
$check = imap_check($mailbox);

$nMessages = imap_num_msg($mailbox);

echo "<table border=\"1\">";

for($index=1; $index <= $nMessages; $index++){

$header = imap_header($mailbox, $index);

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);

?>

Chapitre 17 Connexion à un annuaire LDAP

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 :

 établir la connexion avec l'annuaire


 rechercher des entrées
 comparer des entrées
 ajouter des entrées
 modifier des entrées
 supprimer des entrées
 annuler ou abandonner une opération
 fermer la connexion avec l'annuaire
Ainsi PHP fournit un ensemble de fonctions (pour peu que le module LDAP soit installé)
permettant de réaliser ces opérations. Ces fonctions seront explicitées au long de l'article.
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()

inrpm -ivh /home/httpd/html/ldap/consulte.php3 on line x


Il est possible de se procurer ces bibliothèques sur le serveur de l'Université du Michigan (ldap-
3.3 package) ou chez Netscape (Netscape Directory SDK).
Séquence d'interrogation avec LDAP

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 :

 Etablissement de la connexion avec le serveur LDAP


 Liaison et authentification sur le serveur (appelé bind en anglais)
 Recherche d'une entrée (ou bien une autre opération)
 Exploitation des résultats (uniquement dans le cas d'une recherche)
 Fermeture de la connexion
Connexion au serveur LDAP

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
<?

// Fichier de configuration pour l'interface PHP

// de notre annuaire LDAP

$server = "localhost";

$port = "389";

$racine = "o=commentcamarche, c=fr";

$rootdn = "cn=ldap_admin, o=commentcamarche, c=fr";

$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 :

int ldap_connect ([string hostname [, int port]])


Cette fonction admet en paramètre le nom du serveur (éventuellement le port. Par défaut le port est
389). En cas d'échec cette fonction retourne 0 sinon elle retourne un entier permettant d'identifier le
serveur et nécessaire dans les fonctions suivantes.

Voici un exemple de connexion au serveur :

<?

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 :

int ldap_bind (int identifiant [, string bind_rdn [, string bind_password]])


Cette fonction attend en paramètre l'identifiant du serveur retourné ainsi qu'éventuellement le Nom
distingué relatif de l'utilisateur (RDN - Relative Distinguished Name) et son mot de passe. Si l'utilisateur
et le mot de passe ne sont pas précisés, la connexion se fait de manière anonyme.

La déconnexion du serveur LDAP se fait tout naturellement par la fonction ldap_close() avec la syntaxe
suivante :

int ldap_close (int identifiant)


Cette fonction est similaire à la fonction ldap_unbind().

Voici un exemple complet de connexion et de déconnexion à un serveur LDAP :

<?

// Fichier de configuration pour l'interface PHP

// de notre annuaire LDAP

$server = "localhost";

$port = "389";

$racine = "o=commentcamarche, c=fr";

$rootdn = "cn=ldap_admin, o=commentcamarche, c=fr";

$rootpw = "secret";

echo "Connexion...<br>";

$ds=ldap_connect($server);

if ($ds==1)

// on s'authentifie en tant que super-utilisateur, ici, ldap_admin

$r=ldap_bind($ds,$rootdn,$rootpw);
// Ici les opérations à effectuer

echo "Déconnexion...<br>";

ldap_close($ds);

else {

echo "Impossible de se connecter au serveur LDAP";

?>
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 :

int ldap_add (int identifiant, string dn, array entry)


La fonction ldap_add() admet en paramètre l'identifiant du serveur LDAP retourné par la fonction
ldap_connect() ainsi que le nom distingué de l'entrée (c'est-à-dire son emplacement dans l'annuaire) et
un tableau contenant l'ensemble des valeurs des attributs de l'entrée.

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

$ds=ldap_connect($server); // On suppose que le serveur LDAP est sur cet hote

if ($ds) {

$r=ldap_bind($ds,$rootdn,$rootpw);

// preparation des données

$entry["cn"]="Pillou";

$entry["sn"]="Jean-Francois";

$entry["mail"][0]="webmaster@commentcamarche.net";

$entry["mail"][1]="Jeff@commentcamarche.net";

$entry["objectclass"]="person";

// Ajout des données dans l'annuaire

$r=ldap_add($ds, "cn=Jean-Francois Pillou, o=commentcamarche, c=fr", $entry);


ldap_close($ds);

} else {

echo "Connexion au serveur LDAP impossible";

?>
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);

// preparation des données

$dn="cn=Pillou Jean-Francois, o=commentcamarche,c=fr";

$valeur="MonMot2Passe";

$attribut="password";

// Comparaison du mot de passe à celui dans l'annuaire

$resultat=ldap_compare($ds, $dn, $attribut, $valeur);

if ($resultat == -1) {

echo "Erreur:".ldap_error($ds);

elseif ($resultat == TRUE) {


echo "Le mot de passe est correct";

else ($resultat == FALSE) {

echo "Le mot de passe est erronné...";

ldap_close($ds);

} else {

echo "Connexion au serveur LDAP impossible";

?>
Notez l'utilisation de la fonction ldap_error() sur laquelle nous reviendrons ultérieurement pour
afficher les détails de l'erreur !

Supprimer une entrée avec ldap_delete()

La fonction ldap_delete() permet de supprimer des entrées d'un annuaire LDAP. Voici sa syntaxe :

int ldap_delete (int identifiant, string dn)


La fonction ldap_delete() admet uniquement deux paramètres:
 l'identifiant du serveur LDAP retourné par la fonction ldap_connect()
 le nom distingué de l'entrée à supprimer.
Une fois de plus, cette fonction renvoie TRUE en cas de réussite, FALSE en cas d'échec.

L'exemple suivant illustre la suppression d'un élément de l'annuaire :

<?php

$ds=ldap_connect($server); // On suppose que le serveur LDAP est sur cet hote

if ($ds) {

$r=ldap_bind($ds,$rootdn,$rootpw);

// preparation des données

$dn="Pillou Jean-Francois,o=commentcamarche,c=fr";

// Supression de l'entrée de l'annuaire

$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() :

int ldap_modify (int identifiant, string dn, array entry)


La fonction ldap_modify() admet en paramètre l'identifiant du serveur LDAP retourné par la fonction
ldap_connect() ainsi que le nom distingué de l'entrée (c'est-à-dire son emplacement dans l'annuaire) et
un tableau contenant l'ensemble des valeurs des attributs de l'entrée à modifier.

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

$ds=ldap_connect($server); // On suppose que le serveur LDAP est sur cet hote

if ($ds) {

$r=ldap_bind($ds,$rootdn,$rootpw);

// preparation des données

$entry["cn"]="Pillou";

$entry["sn"]="Jean-Francois";

$entry["mail"][0]="webmaster@commentcamarche.net";

$entry["mail"][1]="Jeff@commentcamarche.net";

$entry["objectclass"]="person";

// Ajout des données dans l'annuaire

$r=ldap_modify($ds, "cn=Jean-Francois Pillou, o=commentcamarche, c=fr", $entry);

ldap_close($ds);

} else {

echo "Connexion au serveur LDAP impossible";

?>
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 :

int ldap_search (int identifiant, string base_dn,

string filter [, array attributs [, int attrsonly [,

int sizelimit [, int timelimit [, int deref]]]]])


La fonction ldap_search() admet en paramètre l'identifiant du serveur LDAP retourné par la fonction
ldap_connect() ainsi que le nom distingué du dossier de base (c'est-à-dire celui à partir duquel la
recherche doit s'effectuer) et le filtre de la recherche. La fonction ldap_search() est par défaut configurée
avec l'option de récursivité LDAP_SCOPE_SUBTREE ce qui signifie que la recherche se fait dans toutes les
branches filles du dossier de base.

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

$ds=ldap_connect($server); // On suppose que le serveur LDAP est sur cet hote

if ($ds) {

$r=ldap_bind($ds,$rootdn,$rootpw);
$dn = "o=commentcamarche, c=fr";

$filtre="(|(sn=$person*)(cn=$person*))";

$restriction = array( "cn", "sn", "mail");

$sr=ldap_search($ds, $dn, $filtre, $restriction);

$info = ldap_get_entries($ds, $sr);

print $info["count"]." enregistrements trouves

";

ldap_close($ds);

} else {

echo "Connexion au serveur LDAP impossible";

?>

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().

Traitement des résultats

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 :

 ldap_get_dn() permet de récupérer le DN de l'entrée


 ldap_get_entries() permet de récupérer l'ensemble des entrées
 ldap_get_option() permet de récupérer la valeur d'une option
 ldap_get_values() permet de récupérer toutes les valeurs d'une entrée
 ldap_get_values_len() permet de récupérer les valeurs binaires d'une entrée
 ldap_count_entries() permet de récupérer le nombre d'entrées retournées par la fonction
de recherche
Récupérer le nombre d'entrées retournées

La fonction ldap_count_entries() permet de connaître le nombre d'entrées retournées par la fonction


ldap_search(). Sa syntaxe est la suivante :

int ldap_count_entries (int link_identifier, int result_identifier)


La fonction ldap_count_entries() admet en paramètre l'identifiant du serveur LDAP retourné par la
fonction ldap_connect() ainsi que l'identifiant du résultat retourné par la fonction ldap_search() et
retourne un entier représentant le nombre d'entrées stockées dans le résultat de la recherche.

Voici un exemple d'utilisation :

<?php

$ds=ldap_connect($server); // On suppose que le serveur LDAP est sur cet hote

if ($ds) {

$r=ldap_bind($ds,$rootdn,$rootpw);

$dn = "o=commentcamarche, c=fr";

$filtre="(|(sn=$person*)(cn=$person*))";

$restriction = array( "cn", "sn", "mail");

$sr=ldap_search($ds, $dn, $filtre, $restriction);

$nombre = ldap_count_entries($ds, $sr);

print $nombre." enregistrements trouves

";

ldap_close($ds);

} else {
echo "Connexion au serveur LDAP impossible";

?>

Récupérer les entrées retournées

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 :

array ldap_get_entries (int link_identifier, int result_identifier)


La fonction ldap_get_entries() admet en paramètre l'identifiant du serveur LDAP retourné par la fonction
ldap_connect() ainsi que l'identifiant du résultat retourné par la fonction ldap_search() et retourne un
tableau multidimensionnel contenant le résultat de la recherche, c'est-à-dire le DN et le nom de l'entrée
ainsi que la ou les valeurs de chacune d'entre-elles.

La structure du tableau retourné (on supposera qu'il se trouve dans la variable $entrees) est la
suivante :

 $entrees["count"] : nombre d'entrées dans le résultat


 $entrees[0] : détail de la première entrée
 $entrees[i]["dn"] : DN de la ième entrée
 $entrees[i]["count"] : nombre d'attributs de la ième entrée
 $entrees[i][j] : valeur du jème attribut de la ième entrée
 $entrees[i]["attribut"] : valeur de l'attribut nommé "attribut" de la i ème entrée (pour un attribut
multivalué)
 $entrees[i]["attribut"]["count"] : Nombre de valeurs du jème attribut de la ième entrée (pour un
attribut multivalué)
 $entrees[i]["attribut"][j] : Jème valeur de l'attribut nommé "attribut" de la ième entrée (pour un
attribut multivalué)
Les noms des attributs dans le tableau associatif sont en minuscules, ainsi l'attribut givenName
devra être écrit givenname (par exemple $entrees[i]["givenname"])

Voici un exemple d'utilisation :

<?php

$ds=ldap_connect($server); // On suppose que le serveur LDAP est sur cet hote

if ($ds) {

$r=ldap_bind($ds,$rootdn,$rootpw);

$dn = "o=commentcamarche, c=fr";


$filtre="(|(sn=$person*)(cn=$person*))";

$restriction = array( "cn", "sn", "mail");

$sr = ldap_search($ds, $dn, $filter);

echo "Le nombre d'entrées retourné est de ".ldap_count_entries($ds,$sr)."<br>";

echo "Récupération des entrées ...";

$info = ldap_get_entries($ds, $sr);

echo "Affichage des données des ".$info["count"]. " entrées trouvées :";

for ($i=0; $i<$info["count"]; $i++)

echo "<p align="justify">";

echo "Le dn (Distinguished Name) est: ". $info[$i]["dn"] ."<br>";

echo "Nom (sn) : ". $info[$i]["sn"][0] . "<br>";

echo "Prénom (cn) : ". $info[$i]["cn"][0] . "<br>";

for($j=0;$j<$info[$i]["mail"]["count"];$j++) {

echo "Email numéro $j: ". $info[$i][ "mail"][$j] ."<br>";

echo "<p> ... Fermeture de la connexion";

ldap_close($ds);

} else {

echo "Connexion au serveur LDAP impossible";

?>
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/.

Installer l'extension XML

L'extension XML de PHP supporte la librairie expat disponible à http://www.jclark.com/xml/.


Sur les serveurs Apache récents (de version supérieure à la 1.3.7) la librairie expat est installée en
standard. sur les serveurs apache de version antérieure à la 1.3.7 il suffit de télécharger cette librairie :

 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.

Considérons le document XML suivant :

<debut>

Bienvenue sur CCM - http://www.commentcamarche.net

</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 fonction xml_set_element_handler() permet d'associer une action au début, à la fin d'un


élément ou bien au contenu d'un attribut
 La fonction xml_set_character_data_handler() permet d'associer un événement au contenu
textuel des balises
 La fonction xml_set_processing_instruction_handler() permet d'associer une action à la
rencontre d'une instruction de traitement
 La fonction xml_set_notation_decl_handler() associe un traitement à la détection d'une
instruction de traitement
 La fonction xml_set_external_entity_ref() permet de détecter un appel à une entité externe
Création de l'analyseur XML

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 :

Evénement Gestionnaire associé Description


ce gestionnaire gère les ouvertures et
Elements xml_set_element_handler()
fermetures de balises
Ce handler permet d'associer une fonction
Character Data xml_set_character_data_handler()
aux données textuelles (hors des balises)
Ce gestionnaire intercepte les appels à des
External Entities xml_set_external_entity_ref_handler()
entités externes
Unparsed Affecte les gestionnaires d'entités non
xml_set_unparsed_entity_decl_handler()
external entities déclarées de l'analyseur XML
Permet d'intercepter l'occurrence d'une
Processing
xml_set_processing_instruction_handler() instructrion de traitement (PI, processing
instructions
instruction)
Notation Gère les occurences de déclarations de
xml_set_notation_decl_handler()
declarations notation
Permet de gérer tous les événements pour
default xml_set_default_handler()
lesquels aucun gestionnaire n'a été défini

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().

Prenons l'exemple de la fonction xml_set_element_handler(). Cette fonction nécessite trois arguments :

 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.

Voici certains gestionnaires d'événement que nous allons définir

 la fermeture d'une balise XML :



 function fermeture ($parser, $name){

 echo "$name<BR>";

}

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

 une fonction par défaut :



 function defaut (){

 return TRUE;

}
Il suffit ensuite d'utiliser les fonctions XML fournies par PHP (appelés gestionnaires d'événement ou en
anglais event handler) pour associer les fonctions que vous avez définies à des événements XML :
 La fonction xml_set_element_handler() permet de définir les fonctions associées à l'ouverture et
à la fermeture d'une balise XML (dans notre cas il s'agit des fonctions ouverture() et
fermeture()) :
xml_set_element_handler($xml_parseur, "ouverture", "fermeture");
 La fonction xml_set_character_data_handler() définit la fonction associée à la rencontre de texte
en dehors ou entre les balises XML :
xml_set_character_data_handler($xml_parseur, "texte");
 La fonction xml_set_default_handler() permet d'associer une fonction par défaut aux
événements non traités
xml_set_default_handler($xml_parseur,"defaut");

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() :

$fp = fopen("essai.xml", "r") or die("


Fichier introuvable. L'analyse a ete suspendue");

while ($fdata = fread($fp, 2048)){

xml_parse($xml_parseur, $fdata, feof($fp)) or die(

sprintf("Erreur XML : %s à la ligne %d\n",

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

Les fonctions xml_error_string() et xml_get_current_line_number() permettent, en cas


d'erreur, d'afficher l'erreur qui a été générée ainsi que le numéro de la ligne du fichier XML où
elle se trouve !
Appel à des entités externes

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 :

<!ENTITY systemEntity SYSTEM "externe.xml">

<?

// Fichier à analyser

$file = "data.xml";

// variable de la profondeur du parcours de l'arbre

$depth = array();

// Etat de la pile de parcours du document XML

$stack = array();

// Valeur d'un dernier élément lu

$globaldata ="";

// Fonction associée à l’événement début d’élément

function startElement($parser, $name, $attrs)

global $depth;

global $stack;
for ($i = 0; $i < $depth[$parser]; $i++)

{print " ";}

array_push($stack,$name);

$depth[$parser]++;

print "Début de l'élément : ".$name."\n -- ";

print "profondeur : ".$depth[$parser]." -- Attributs de l'élément : ";

//affichage des attributs de l'élément

while (list ($key, $val) = each ($attrs))

{echo "$key => $val";}

print " ";

// Fonction associée à l’événement fin d’élément

function endElement($parser, $name)

global $depth;

global $stack;

global $globaldata;

for ($i = 0; $i < $depth[$parser]-1; $i++)

{print " ";}

print "Fin de l'élément : ".$name." avec la valeur :".$globaldata." -- ";

print "profondeur : ".$depth[$parser]." ";

$depth[$parser]--;

array_pop($stack);

// Fonction associée à l’événement données textuelles

function characterData($parser, $data)

global $globaldata;

$globaldata = $data;

// Fonction associée à l’événement de détection d'un appel d'entité externe

function externalEntityRefHandler($parser,
$openEntityNames,
$base,
$systemId,
$publicId)

if ($systemId)

{ if (!list($parser, $fp) = new_xml_parser($systemId))

printf("Impossible d'ouvrir %s à %s\n",


$openEntityNames,
$systemId);
return FALSE;

while ($data = fread($fp, 4096))

if (!xml_parse($parser, $data, feof($fp)))

printf("Erreur XML : %s à la ligne %d lors du traitement de l'entité %s\n",


xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser),
$openEntityNames);

xml_parser_free($parser);

return FALSE;

xml_parser_free($parser);

return TRUE; } return FALSE;

// Fonction de création du parser et d'affectation


// des fonctions aux gestionnaires d'événements

function new_xml_parser($file)

global $parser_file;

//création du parseur

$xml_parser = xml_parser_create();

//Activation du respect de la casse du nom des éléments XML

xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 1);

//Déclaration des fonctions à rattacher au gestionnaire d'événement

xml_set_element_handler($xml_parser, "startElement", "endElement");


xml_set_character_data_handler($xml_parser, "characterData");
xml_set_external_entity_ref_handler($xml_parser, "externalEntityRefHandler");
//Ouverture du fichier

if (!($fp = @fopen($file, "r"))) { return FALSE; }

//Transformation du parseur en un tableau

if (!is_array($parser_file))

{ settype($parser_file, "array"); }

$parser_file[$xml_parser] = $file;

return array($xml_parser, $fp);

// Appel à la fonction de création et d'initialisation du parseur

if (!(list($xml_parser, $fp) = new_xml_parser($file)))

{ die("Impossible d'ouvrir le document XML"); }

// Traitement de la ressource XML

while ($data = fread($fp, 4096))

if (!xml_parse($xml_parser, $data, feof($fp)))

{ die(sprintf("Erreur XML : %s à la ligne %d\n",


xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}

// Libération de la ressource associée au parser

xml_parser_free($xml_parser);

?>
Mise en pratique :

Créer son propre moteur de recherche

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="ROBOTS" content="all">

<META NAME="keywords" content="mot clé 1,mot cle 2,Mot clé 3, Mots clefs">

<META NAME="title" content="titre de votre page">

<title>titre de votre page</title>

</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>

<META NAME="ROBOTS" content="none">

</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.

Création de la base de données

Le but est de créer une table comportant les champs nécessaires au stockage des enregistrements, c'est-
à-dire contenant les champs suivants:

 lien : URL (absolue ou relative) de la page


 keywords : mots clés
 titre : titre de la page
Il suffit donc de créer un petit script PHP dont le seul but sera de créer cette table, que l'on appelera
search

<html>

<head>

<title>Creation de la table</title>
</head>

<body>

<?php

$host = "Votre serveur de base de données";

$user = "Votre nom d'utilisateur";

$password = "Votre mot de passe";

$bdd = "Votre base de données sur le serveur";

mysql_connect($host, $user, $password) or die ("Connexion au serveur impossible");

// on choisit la bonne base

mysql_select_db($bdd) or die ("Connexion a la base impossible");

$query = "CREATE TABLE search (

lien varchar(128) NOT NULL,

keyword text,

titre varchar(128),

id INT(11),

PRIMARY KEY (id)

)";

mysql_query($query) or die ("Erreur de modification de la table");

// on ferme la base

mysql_close();

?>

</body>

</html>

Remplissage de la base de données

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

<table bgcolor=\"#EFF2FB\" border=\"0\"


cellspacing=\"0\"
cellpadding=\"1\"
width="100%">\n

<tr><td>\n

<a name=\"#index\"><h2>Indexation du site en cours</h2></a>\n

</td></tr>\n

</table>\n

<p>\n";

$host = "Le serveur de base de données";

$bdd = "Votre base de données";

/* Connexion avec MySQL */

mysql_connect($host,$user,$password) or die ("Impossible de se connecter

au serveur de base de donnees");

mysql_select_db($bdd) or die ("Impossible d'accéder à la base $bdd");

$query = "DELETE FROM search";

mysql_query($query) or die ("Erreur de modification de la table");


function ScanDir($Directory){

$MyDirectory = opendir($Directory);

while($Entry = readdir($MyDirectory)) {

echo "<br>entry= $Entry<br>";

echo "repertoire= $Directory<br>";

echo "chemin= $Directory/$Entry<br>";

if(is_dir($Entry)&& $Entry != "." && $Entry != "..") {

echo "<b><font color=\"red\">$Entry</font>


</b> est un repertoire<br>";

ScanDir("$Entry/$Directory");

else {

if (eregi(".htm",$Entry)) {

$MetaTags = get_meta_tags($Directory."/".$Entry);

if ($MetaTags["robots"] == "all") {

$MetaKey = $MetaTags["keywords"];

$MetaKey = strtoupper($MetaKey);

echo "Meta($Directory/$Entry): $MetaKey


\n";

$MetaTitre = $MetaTags["title"];

echo "Meta($Directory/$Entry): $MetaTitre


\n";

$query = "INSERT INTO search (lien,keyword,titre)

VALUES(\"$Directory/$Entry\",\"$MetaKey\",\"$MetaTitre\")";

$mysql_result = mysql_query($query) or die ("Erreur

de modification de la table par la requete \"$query\"");

}
}

closedir($MyDirectory);

$open_basedir=".";

ScanDir(".");

mysql_close();

?>

Exploitation de la base de données

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 method="post" action="search.php3">

Entrez un mot clé:<br>

<input type="text" name="Mot" size="15">

<input type="submit" value="Rechercher" alt="Lancer la recherche!">

</form>

Voici le résultat de ce code HTML:


Entrez un mot clé:

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

$host = "Votre serveur de base de données";

$user = "Votre nom d'utilisateur";

$password = "Votre mot de passe";

$bdd = "Votre base de données sur le serveur";

mysql_connect($host, $user, $password) or die ("Connexion au serveur impossible");

// on choisit la bonne base

mysql_select_db($bdd) or die ("Connexion a la base impossible");


echo "

<html>

<head>

<title>Résultat de la recherche</title>

</head>

<body>";

if (($Mot == "")||($Mot == "%")) {

// Si aucun mot clé n'a été saisi,

// le script demande à l'utilisateur

// de bien vouloir préciser un mot clé

echo "

Veuillez entrer un mot clé s'il vous plaît!

<p>";

else {

// On selectionne les enregistrements contenant le mot clé


// dans les keywords ou le titre

$query = "SELECT distinct count(lien) FROM search

WHERE keyword LIKE \"%$Mot%\"

OR titre LIKE \"%$Mot%\"

";

$result = mysql_query($query);

$row = mysql_fetch_row($result);

$Nombre = $row[0];

// Si aucun enregistrement n'est retourné,


// on affiche un message adéquat
if ($Nombre == "0") {

echo "

<h2>Aucun résultat ne correspond à votre recherche</h2>

<p>

";

// Sinon, on affiche le nombre d'enregistrements correspondant


// et les résultats eux-mêmes

else {

$query = "SELECT distinct lien,keyword,titre FROM search

WHERE keyword LIKE \"%$Mot%\"

OR titre LIKE \"%$Mot%\" ORDER by titre ASC";

$result = mysql_query($query);

// Si un seul enregistrement est trouvé, on affiche un message au singulier

if ($Nombre == "1") {

echo "

<a name=\"#resultat\"><h2>Résultat: Un article trouvé</h2></a>

<p>";

// Dans le cas contraire le message est au pluriel...

else {

echo "

<a name=\"#resultat\"><h2>Résultat: $Nombre articles trouvés</h2></a>

<p>";

while($row = mysql_fetch_row($result))

{
echo "

<p>\n

<b>$row[2]</b>\n

<br><a href=\"../$row[0]\">Visualiser l'article</a>\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...

Chapitre 19 Administrer LDAP en PHP

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

rpm -ivh /home/httpd/html/ldap/consulte.php3 on line x


Il est possible de se procurer ces bibliothèques sur le serveur de l'Université du Michigan (ldap-
3.3 package) ou chez Netscape (Netscape Directory SDK).

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 :

 header.php3 : qui définira le haut de page de notre interface


 footer.php3 : qui définira le bas de page de notre interface
Sécurisation de l'interface

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) :

htpasswd -c ldap_admin.passwd ldap_admin


Remarque : le nom de ce fichier n'a aucune importance. L'option -c correspond à la création du
fichier.

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

Deny From All

</Files>

AuthUserFile /home/httpd/html/services/ldap_admin/ldap_admin.passwd

AuthName "Acces Restreint"

AuthType Basic
<Limit GET POST>

require valid-user

</Limit>
La sécurisation de notre interface est maintenant terminée.
Fichier de configuration

Commençons par commenter le fichier de configuration nommé config_LDAP.inc.php3 :

<?

// Fichier de configuration pour l'interface PHP pour administrer

// notre annuaire LDAP

$server = "localhost";

$port = "389";

$racine = "o=commentcamarche, c=fr";

$rootdn = "cn=ldap_admin, o=commentcamarche, c=fr";

$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.

Du point du vue du code source, elle ne comporte aucune grosse complexité.

 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 « + ».
<?

// affichage du haut de la page contenu dans le fichier header.php3

require("header.php3");

echo "Les personnes suivantes sont inscrites dans l'annuaire :<p>";

// connexion au serveur LDAP : ds est égal à 1 si la connexion est OK

$ds=ldap_connect($server);

if ($ds==1)

// on recherche les objet de type person à partir de la racine

// de notre serveur LDAP, ici : o=commentcamarche, c=fr

$sr=ldap_search($ds, $racine, "objectclass=person");

$info = ldap_get_entries($ds, $sr);

echo "<table border=1>";

echo "<tr>
<th>Nom et prénom</th>
<th>Adresse e-Mail </th>
<th>Téléphone</th>
</tr>";

// on affiche sous forme d'un tableau les personnes enregistrées

// dans l'annuaire avec un lien pour modifier et un lien pour supprimer

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);

echo" <th><a href=\"modifie.php3?cn=$mynom\">


Modifier</a></th>";

echo" <th><a href=\"supprime.php3?cn=$mynom\">

Supprimer</a></th></tr>";

echo"</table>";

echo "<center>< br><a href=\"ajoute.php3\">Ajouter une

nouvelle personne dans l'annuaire</a></center>";

// on ferme la connexion au serveur LDAP

ldap_close($ds);

// on affiche le bas de page défini dans le fichier footer.php3

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.

<?

// on affiche le haut de la page contenu dans le fichier header.php3

require("header.php3");
if (($go==1) and ($nom!="") and ($prenom!="") and ($mail!=""))

$ds=ldap_connect($server);

if ($ds==1)

// on s'authentifie en tant que super-utilisateur, ici, ldap_admin

$r=ldap_bind($ds,$rootdn,$rootpw);

// préparation des données

$info["cn"]=$nom." ".$prenom;

$info["mail"]=$mail;

$info["telephonenumber"]=$tel;

$info["objectclass"]="person";

// ajout dans l'annuaire

$r=ldap_add($ds,"cn=$nom $prenom,$racine",$info);

// fermeture de la connexion

ldap_close($ds);

$go==0;

$nom=="";

$prenom="";

$mail="";

$tel="";

echo "L'enregistrement a réussi !!!\n";

echo "<P><A HREF=\"ajoute.php3\">Ajouter

une nouvelle personne</A>\n";

echo "<P><A HREF=\"admin.php3\">Retourner

à la page d'administration</A>\n";

} else {
if ($go==1)

$mes="ERREUR ! Vous devez obligatoirement remplir les champs en gras";

echo "<FONT COLOR=FF0000>$mes</FONT>\n";

echo "<FORM ACTION=\"ajoute.php3\" METHOD=POST>\n";

echo "<TABLE BORDER=0>\n";

echo quot;<TR><TD> <B>Nom</B></TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"nom\"

value=\"$nom\" SIZE=30 maxlength=80><BR></TD></TR>\n";

echo "<TR><TD> <B>Prénom</B></TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"prenom\"

value=\"$prenom\" SIZE=30 maxlength=80><BR></TD></TR>\n";

echo "<TR><TD> <B>E-Mail</B></TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"mail\"

value=\"$mail\" SIZE=40 maxlength=80><BR></TD></TR>\n";

echo "<TR><TD> Téléphone</TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"tel\"

value=\"$tel\" SIZE=40 maxlength=255><BR></TD></TR>\n";

echo "</TABLE>\n";

echo "<INPUT type=\"hidden\" name=\"go\" value=\"1\"><BR><BR>\n";

echo "<INPUT type=\"submit\" value=\"Valider\">\n";

echo "<INPUT type=\"reset\" value=\"Annuler\">\n";

echo "</FORM>\n";

echo "<BR>Les champs en <B>gras</B> sont obligatoires.\n";

// on affiche le bas de la page contenu dans le fichier footer.php3

require("footer.php3");

?>

Modification d'une entrée de l'annuaire LDAP

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).

<?

// on affiche le haut de la page contenu dans le fichier header.php3

require("header.php3");

$cn=urldecode($cn);

if (($go==1) and ($mail!=""))

// connexion au serveur

$ds=ldap_connect($server);

if ($ds==1)

// on s'authentifie en tant que super-utilisateur, ici, ldap_admin

$r=ldap_bind($ds,$rootdn,$rootpw);

// Suppression de l'ancien enregistrement

$r=ldap_delete($ds,"cn=$cn,$racine");

// Préparation des données

$info["cn"]=$cn;

$info["mail"]=$mail;

$info["telephonenumber"]=$tel;

$info["objectclass"]="person";

// Ajout dans l'annuaire

$r=ldap_add($ds,"cn=$cn,$racine",$info);

// fermeture de la connexion à l'annuaire LDAP

ldap_close($ds);

$go==0;
$nom=="";

$prenom="";

$mail="";

$tel="";

echo "La modification a réussi !!!\n";

echo "<P><A HREF=\"admin.php3\">Retourner


à la page d'administration</A>\n";

} else {

if ($go==1)

$mes="ERREUR ! Vous devez obligatoirement remplir le champ mail";

echo "<FONT COLOR=FF0000>$mes</FONT>\n";

// connexion au serveur

$ds=ldap_connect($server);

if ($ds)

$recherche="cn=$cn";

$champs = array("cn", "telephonenumber", "mail");

// recherche les informations de la personne que l'on veut modifier

$sr=ldap_search($ds, $racine, $recherche, $champs);

$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];

echo "<FORM ACTION=\"modifie.php3\" METHOD=POST>\n";

echo "<TABLE BORDER=0>\n";


echo "<TR><TD> <B>Modification de l'utilisateur : $cn</B></TD>\n";

echo "<TR><TD> <B>E-Mail</B></TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"mail\" value=\"$myemail\"

SIZE=40 maxlength=80><BR></TD></TR>\n";

echo "<TR><TD> Téléphone</TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"tel\" value=\"$mytel\"

SIZE=40 maxlength=255><BR></TD></TR>\n";

echo "</TABLE>\n";

echo "<INPUT type=\"hidden\" name=\"cn\" value=\"$cn\"><BR><BR>\n";

echo "<INPUT type=\"hidden\" name=\"go\" value=\"1\"><BR><BR>\n";

echo "<INPUT type=\"submit\" value=\"Modifier\">\n";

echo "<INPUT type=\"reset\" value=\"Annuler\">\n";

echo "</FORM>\n";

echo "<BR>Le champ <B>mail</B> est obligatoire.\n";

} else {

echo "Erreur ! La recherche n'a pas aboutie";

} else {

echo "Erreur ! Problème à la connexion avec le serveur LDAP";

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.

Si on confirme, on rappelle la page supprime.php3 avec le paramètre go=1.


Ici, on est obligé de préciser go=1 dans l'URL car seules les variables contenues dans les formulaires
sont automatiquement passées d'une page à l'autre.
La suppression ne peut s'effectuer qu'avec le super-utilisateur ldap_admin (fonction ldap_bind()).

<?

// on affiche le haut de la page contenu dans le fichier header.php3

require("header.php3");

$cn=urldecode($cn);
if ($go==0) {

echo "Etes-vous sur de vouloir supprimer l'utilisateur $cn<br>\n";

$cn=urlencode($cn);

echo "<A HREF=\"supprime.php3?go=1&cn=$cn\">oui</A><BR>\n";

echo "<A HREF=\"admin.php3\">non</A><BR>\n";

else {

$cn=urldecode($cn);

// connexion au serveur LDAP

$ds=ldap_connect($server);

if ($ds==1) {

// on s'authentifie en tant que super-utilisateur, ici, ldap_admin

$r=ldap_bind($ds,$rootdn,$rootpw);

// Suppression de l'ancien enregistrement

$r=ldap_delete($ds,"cn=$cn,$racine");

echo "La suppression a réussi !!!\n";

echo "<P><A HREF=\"admin.php3\">Retourner


à la page d'administration</A>\n";

// on affiche le bas de la page contenu dans le fichier footer.php3

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.

Vous aimerez peut-être aussi