Vous êtes sur la page 1sur 1440

Copyright

2005

Micro Application 20-22, rue des Petits-Htels 75010 Paris

1re dition - Janvier 2005

Auteurs

Laurent GUDON, Damien HEUTE, Thomas HEUTE et Pierre-Emmanuel MULLER Toute reprsentation ou reproduction, intgrale ou partielle, faite sans le consentement de MICRO APPLICATION est illicite (article L122-4 du code de la proprit intellectuelle). Cette reprsentation ou reproduction illicite, par quelque procd que ce soit, constituerait une contrefaon sanctionne par les articles L335-2 et suivants du code de la proprit intellectuelle. Le code de la proprit intellectuelle nautorise aux termes de larticle L122-5 que les reproductions strictement destines lusage priv et non destines lutilisation collective dune part, et dautre part, que les analyses et courtes citations dans un but dexemple et dillustration.

Avertissement aux utilisateurs

Les informations contenues dans cet ouvrage sont donnes titre indicatif et nont aucun caractre exhaustif voire certain. A titre dexemple non limitatif, cet ouvrage peut vous proposer une ou plusieurs adresses de sites Web qui ne seront plus dactualit ou dont le contenu aura chang au moment o vous en prendrez connaissance. Aussi, ces informations ne sauraient engager la responsabilit de lEditeur. La socit MICRO APPLICATION ne pourra tre tenue responsable de toute omission, erreur ou lacune qui aurait pu se glisser dans ce produit ainsi que des consquences, quelles quelles soient, qui rsulteraient des informations et indications fournies ainsi que de leur utilisation. ISBN : 2-7429-3608-4 Tous les produits cits dans cet ouvrage sont protgs, et les marques dposes par leurs titulaires de droits respectifs. Cet ouvrage nest ni dit, ni produit par le(s) propritaire(s) de(s) programme(s) sur le(s)quel(s) il porte. Couverture ralise par Stefanos ATHANASSOPOULOS

MICRO APPLICATION 20-22, rue des Petits-Htels 75010 PARIS Tl. : 01 53 34 20 20 - Fax : 01 53 34 20 00 http://www.microapp.com

Support technique disponible sur www.microapp.com

Mister Onet, lhomme la rfrence, vous montre le chemin !


Rendez-vous sur le site Internet de Micro Application www.microapp.com. Dans le module de recherche, sur la page daccueil du site, retrouvez Mister Onet. Dans la zone de saisie, entrez la rfrence 4 chiffres quil vous indique sur le prsent livre. Vous accdez directement la fiche produit de ce livre.

4608

Avant-propos
La collection Bible Micro Application a t conue pour permettre aux utilisateurs avancs experts dapprofondir leurs connaissances dun thme prcis. Exhaustifs, ces ouvrages permettent dacqurir une connaissance intgrale du sujet tudi, la fois en thorie et en pratique.

Conventions typographiques
Afin de faciliter la comprhension des techniques dcrites, nous avons adopt les conventions typographiques suivantes :
j j j

gras : menu, commande, bote de dialogue, bouton, onglet. italique : zone de texte, liste droulante, case cocher, bouton radio.
Police bton : instruction, listing, texte saisir.

: indique un retour la ligne d aux contraintes de la mise en page. Au cours de votre lecture, vous rencontrerez les encadrs suivants :

Propose des trucs pratiques.

Met laccent sur un point important quil ne faut ngliger aucun prix.

Mentionne un fichier exemple ou un programme disponible sur le CD daccompagnement de louvrage.

Vous recommande une technique ou une marche suivre.

Vous indique le nom et lemplacement des fichiers tlcharger.

Renvoi un site o vous trouverez des infos complmentaires ou des outils tlcharger.

Il sagit dinformations supplmentaires relatives au sujet trait.

Fait rfrence un chapitre o vous trouverez des informations complmentaires.

Contenu en un clin dil


Chapitre 1 Chapitre 2 Chapitre 3 Chapitre 4 Chapitre 5 Chapitre 6 Chapitre 7 Chapitre 8 Chapitre 9 Chapitre 10 Chapitre 11 Chapitre 12 Chapitre 13 Chapitre 14 Chapitre 15 Chapitre 16 Chapitre 17 Chapitre 18 Chapitre 19 Chapitre 20 Chapitre 21 Chapitre 22 Chapitre 23 Introduction Prise en main Le langage PHP Les en-ttes HTTP Les techniques de programmation Les fonctions mathmatiques La manipulation des chanes de caractres La gestion des dates et des calendriers La gestion des chiers et des rpertoires Lutilisation des bases de donnes Les annuaires LDAP La messagerie : envoi et lecture de mails Les images et les animations Flash La cration de documents PDF Lutilisation de XML La gestion des protocoles HTTP, FTP, SOAP, etc. Les processus et les identiants Linteroprabilit avec COM Loptimisation des temps de rponse Lobfuscation : Distribuer ses scripts sans dvoiler son code Annexe A : des exemples dapplications Annexe B : les en-ttes HTTP et les variables externes Annexe C : les erreurs HTTP 25 49 111 251 295 325 353 433 485 633 901 959 1021 1137 1185 1263 1309 1325 1339 1379 1393 1419 1425

Sommaire
Chapitre 1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 quoi sert PHP ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Prsentation, rle et fonctionnement dun langage de script . . . . . . . . . . . 27

Les version 1 5 de PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29


Rasmus Lerdorf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Naissance et volution de PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 La cration de la communaut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

La communaut du libre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Historique . . . . . . . . . . . . La machine en marche . . . . . Cathdrale et bazar . . . . . . La scission : lOpen Source . . Le droit et les logiciels libres PHP et le libre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 36 37 37 38 39 40 41 41 42 44 44

PHP face ses concurrents (ASP, JSP, etc.) . . . . . . . . . . . . . . . . . . . . . . . . 40


PHP face aux autres langages de script web Comparatif PHP/Perl . . . . . . . . . . . . . . Comparatif PHP/ASP . . . . . . . . . . . . . . Comparatif PHP/JSP . . . . . . . . . . . . . . Perspectives . . . . . . . . . . . . . . . . . . . En bref . . . . . . . . . . . . . . . . . . . . . .

Pourquoi ont-ils choisi PHP ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45


Ils ont choisi PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 PHP lassaut du Net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

Chapitre 2 Prise en main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51


Avec Apache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Avec IIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Avec iPlanet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

Le chier de conguration php.ini . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84


Options PHP de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Scurit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Gestion des erreurs et rcupration des messages derreur . . . . . . . . . . . . 87

Sommaire

Gestion des chiers . . . . . . Gestion des donnes . . . . . . Les magic quotes . . . . . . . . Sessions . . . . . . . . . . . . . Gnration du document . . . Gestion de laffichage . . . . . Extensions dynamiques . . . . Conguration des extensions Divers . . . . . . . . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

90 91 91 92 94 95 96 96 97

Les diteurs et dbogueurs PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97


Lartillerie lourde . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 Les spcialistes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 Dreamweaver et GoLive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

Chapitre 3 Le langage PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Intgrer le code PHP au HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113


Les balises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Mon premier script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

Les commentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 Les constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Les variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118


Dnition et syntaxe . . . Les variables dynamiques Les types . . . . . . . . . . Les variables externes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 119 120 130 140 141 142 142 143 144 145 145 147 147 148 152 153 156

Les oprateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140


Arithmtiques . . . . . . . . . . . . . Binaires . . . . . . . . . . . . . . . . . Chanes de caractres . . . . . . . . Affectation . . . . . . . . . . . . . . . Incrmentation et dcrmentation Comparaison . . . . . . . . . . . . . Logique . . . . . . . . . . . . . . . . . Contrles derreur . . . . . . . . . . Excution . . . . . . . . . . . . . . . . Priorits . . . . . . . . . . . . . . . . If, else, elseif . While, do while For, foreach . . Switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Les structures de contrle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

Sommaire

Break, continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

Les fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158


La syntaxe . . . . . . . . . . . . . . . . . . La porte des variables . . . . . . . . . . Le passage des paramtres . . . . . . . . Les paramtres par dfaut . . . . . . . . Le passage de paramtres par rfrence Retourner une valeur . . . . . . . . . . . Manipuler des fonctions . . . . . . . . . La rcursivit des fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 160 163 163 166 167 168 173 175 175 176 177 178 209 210 210 211 211 213 214 219 220 221 223 227 233 234 235 238 241 246

Les tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174


Les valeurs dun tableau . . . . . . . . . . . . . Initialisation dun tableau . . . . . . . . . . . Les subtilits dinitialisation dun tableau . . Remplissage dun tableau . . . . . . . . . . . . Les fonctions de manipulation des tableaux

Les inclusions de chiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206


Inclusions multiples . . . . . . . . . . . . . . . . . . . . . . . . . . Les noms des chiers inclus . . . . . . . . . . . . . . . . . . . . . Les chiers insrs distants . . . . . . . . . . . . . . . . . . . . . Le passage de paramtres . . . . . . . . . . . . . . . . . . . . . . . Les chemins relatifs . . . . . . . . . . . . . . . . . . . . . . . . . . Cas derreur et code retour . . . . . . . . . . . . . . . . . . . . . . Un cas dutilisation pratique mais potentiellement dangereux Dnir une classe . . . . . . . . . . . . . . . Les constructeurs . . . . . . . . . . . . . . . Les attributs . . . . . . . . . . . . . . . . . . Les mthodes . . . . . . . . . . . . . . . . . Lhritage . . . . . . . . . . . . . . . . . . . . Les interfaces . . . . . . . . . . . . . . . . . Les classes abstraites . . . . . . . . . . . . Les exceptions . . . . . . . . . . . . . . . . . Les fonctions de manipulation des objets Programmation avance . . . . . . . . . . . Les tableaux en POO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Les classes, les objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216

Chapitre 4 Les en-ttes HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 Principe gnral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Gestion personnalise de len-tte HTTP . . . . . . . . . . . . . . . . . . . . . . . . . 258
Redirection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260

Sommaire

Dclaration du type MIME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 Gestion des caches (des navigateurs) . . . . . . . . . . . . . . . . . . . . . . . . . 261

Cookies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Gnralits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 En PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 Exemple utilisant des cookies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266

Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
Exemple utilisant des sessions . . . . . . . . . . . . Stockage personnalis des variables de sessions Clore une session . . . . . . . . . . . . . . . . . . . . Les autres fonctions . . . . . . . . . . . . . . . . . . Les fonctions historiques . . . . . . . . . . . . . . . Les fonctions de base . . . . . . . . . Compression des donnes . . . . . . Optimisation des temps de rponse . Gestion du cache interne . . . . . . . Les autres fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274 277 283 283 287 287 289 290 292 293

Mise en cache avant mission des donnes . . . . . . . . . . . . . . . . . . . . . . . 287

Chapitre 5 Les techniques de programmation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 Rgles de codage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297


Prsentation du code . . . . . . . . . . . . . . . . . . Programmation . . . . . . . . . . . . . . . . . . . . . . Noms de classes, fonctions, variables et constantes Commentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 299 299 301

Sparation du code et de la mise en page . . . . . . . . . . . . . . . . . . . . . . . . . 307


Utilisation des objets et de linstruction include . . . . . . . . . . . . . . . . . . 307 Utilisation des modles (templates) . . . . . . . . . . . . . . . . . . . . . . . . . 309

Chapitre 6 Les fonctions mathmatiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 Les fonctions mathmatiques et les constantes . . . . . . . . . . . . . . . . . . . . . 327
Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 Fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328

Calculs de prcision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348


Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349

Chapitre 7 La manipulation des chanes de caractres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353

Sommaire

Gnralits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
Afficher du texte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 Manipuler les caractres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363

Fonctions de gestion des chanes de caractres . . . . . . . . . . . . . . . . . . . . . 363


Extraction et substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 Fonctions statistiques (longueur et nombre doccurrences) . . . . . . . . . . . 370 Fonctions de position . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375

Comparaison de chanes de caractres . . . . . . . . . . . . . . . . . . . . . . . . . . 376


Comparaison par ordre alphabtique . . . . . . . . . . . . . . . . . . . . . . . . 377 Comparaison orthographique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381 Comparaison phonique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383

Gestion des caractres spciaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385


Ajout du caractre dchappement . . . . Suppression du caractre dchappement Conversion des caractres en code HTML Conversion dun alphabet un autre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385 386 388 394

Manipulation des balises HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395


Suppression des espaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 Modication de casse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399

Insertion de motifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 Fusion et dcoupe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402


Autres... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405 Somme de contrle et cryptage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407

Expressions rgulires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409


Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409 Posix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421

Adapter le texte la langue du visiteur . . . . . . . . . . . . . . . . . . . . . . . . . . 431 Chapitre 8 La gestion des dates et des calendriers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 Les fonctions de date et heure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
Rcuprer une date au "format informatique" Effectuer des oprations sur les dates . . . . . Afficher des dates . . . . . . . . . . . . . . . . . . Les heures GMT . . . . . . . . . . . . . . . . . . . Les microsecondes . . . . . . . . . . . . . . . . . Autres fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435 436 437 442 442 443

Les dates et calendriers particuliers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444


Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444 Pques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444 Conversion dune date dun calendrier lautre . . . . . . . . . . . . . . . . . . 446

Sommaire

Les gestionnaires dvnements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 Chapitre 9 La gestion des chiers et des rpertoires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485 Le systme de chiers POSIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 Accder au systme de chiers du serveur . . . . . . . . . . . . . . . . . . . . . . . . 490
Lire et crire le contenu dun chier . . . . . . . . . . . . . . . . . . . Lister le contenu dun dossier . . . . . . . . . . . . . . . . . . . . . . . Manipulation de chiers et rpertoires . . . . . . . . . . . . . . . . . Upload de chiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Encore plus de fonctions daccs au systme de chiers du serveur Exemple dapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lecture sur un "pipe" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Compression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Installation . . . . . . . . . . . Les gestionnaires disponibles Les ltres . . . . . . . . . . . . . Contexte de ressource . . . . . Travailler avec les ux . . . . . Ajouter des gestionnaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490 518 526 532 538 564 574 575 593 593 597 601 607 609

Les streams ou les ux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593

Chapitre 10 Lutilisation des bases de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 633 Introduction aux bases de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 635 Introduction au langage SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 636
Le typage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 636 Les contraintes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 636

Les relations entre tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 636


Cls primaires et compteurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639

Le langage SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639


Cration/suppression dune base de donnes Les types . . . . . . . . . . . . . . . . . . . . . . . Cration/suppression dune table . . . . . . . . Ajouter des donnes . . . . . . . . . . . . . . . . Mettre jour des donnes . . . . . . . . . . . . Supprimer des donnes . . . . . . . . . . . . . . Lire des donnes . . . . . . . . . . . . . . . . . . Rcuprer des informations sur une base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 640 640 643 645 646 647 648 651

Accder une base de donnes via PHP . . . . . . . . . . . . . . . . . . . . . . . . . 652

Sommaire

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652 Couches dabstraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654 ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654

Prsentation de lapplication dexemple . . . . . . . . . . . . . . . . . . . . . . . . . 654


Le modle de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657 Le contrleur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661 Les vues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677

Access (MS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683


Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683 Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686

DB2 (IBM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687


Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687 Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 690

MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 690
Installation . . . . . . . . Utilisation . . . . . . . . . Exemples dapplications En savoir plus... . . . . . . Installation . . . . . . . . Utilisation . . . . . . . . . Exemples dapplications En savoir plus... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691 699 714 723 730 731 745 754 761 775 790 792 797 800 810 812 813 824 833 836 844 859 869

ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730

Oracle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 761
Installation . . . . . . . . . . . . . . . . . . . . . . . . . Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . Mise prot des requtes prpares . . . . . . . . . . Utilisation des objets de grande taille (BLOB, CLOB) Gestion des erreurs . . . . . . . . . . . . . . . . . . . . Exemples dapplications . . . . . . . . . . . . . . . . . En savoir plus . . . . . . . . . . . . . . . . . . . . . . . . Installation . . . . . . . . Utilisation . . . . . . . . . Exemples dapplications En savoir plus... . . . . . . Installation . . . . . . . . Utilisation . . . . . . . . . Exemples dapplications En savoir plus... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

SQLite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812

SQL Server (MS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 836

Les couches dabstraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 871

Sommaire

Pear DB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 872

Chapitre 11 Les annuaires LDAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901 Le schma LDAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
Installation du serveur OpenLDAP . . . . . . . . . . . . . . . . . . . . . . . . . . 905 Installation du module LDAP pour PHP . . . . . . . . . . . . . . . . . . . . . . . 907

Linterrogation de LDAP avec PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 908


Connexion, authentication et dconnexion sur le serveur LDAP Oprations sur un annuaire LDAP . . . . . . . . . . . . . . . . . . . Recherche dans un annuaire LDAP . . . . . . . . . . . . . . . . . . . Gestion des erreurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . Opration sur le Distinguished Name (DN) . . . . . . . . . . . . . . Opration sur les options . . . . . . . . . . . . . . . . . . . . . . . . . Lauthentication sur lannuaire . . . . . . Lajout dune nouvelle entre . . . . . . . . Recherche dans lannuaire . . . . . . . . . . Modication dune entre . . . . . . . . . . . Ralisation dun arbre de navigation LDAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 908 910 918 933 934 936 939 944 947 949 952

Exemple dapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 938

Chapitre 12 La messagerie : envoi et lecture de mails . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 959 E-mail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 961


Installation . . . . . . . . . . . . . . . . . . Envoyer un e-mail simple . . . . . . . . . . Type MIME . . . . . . . . . . . . . . . . . . . Envoyer un e-mail au format HTML . . . . Envoyer un e-mail avec chiers attachs . Envoyer un e-mail multi-part . . . . . . . Envoyer un e-mail HTML avec des images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 961 962 965 965 966 968 972

Accder son compte messagerie IMAP, POP3 ou NNTP . . . . . . . . . . . . . . . . 974


Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 975 Connexion et dconnexion un serveur . . . . . . . . . . . . . . . . . . . . . . . 976 Slection dune bote lettres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 979 Aperu du contenu de la bote lettres . . . . . . . . . . . . . . . . . . . . . . 983 Lecture des en-ttes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986 Lecture des messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 995 Recherche et tri des messages . . . . . . . . . . . . . . . . . . . . . . . . . . 1000 Modication des drapeaux et suppression des messages . . . . . . . . . . . . 1002 Ajout et dplacement de messages . . . . . . . . . . . . . . . . . . . . . . . . 1004

Sommaire

Inscription/dsinscription un serveur de nouvelles Identiants ........................ Composition et dcomposition dadresses e-mail . . Gnration et envoi de mails . . . . . . . . . . . . . . . Coder / dcoder ..................... Grer les erreurs . . . . . . . . . . . . . . . . . . . . . . Administration des botes lettres

. . . . .

. . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

1005 1006 1006 1008 1009 1011

Application dexemple : le webmail . . . . . . . . . . . . . . . . . . . . . . . . . . . 1012


. . . . . . . . . . . . . . . . . . . . . . . 1017

Chapitre 13 Les images et les animations Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1021 Images (utilisation de la bibliothque GD) . . . . . . . . . . . . . . . . . . . . . . . 1023
Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . Dnition de limage de base . . . . . . . . . . . . . . . . Du texte dans les images . . . . . . . . . . . . . . . . . . . Dessiner des formes gomtriques . . . . . . . . . . . . Utiliser les couleurs . . . . . . . . . . . . . . . . . . . . . Copier des parties dimage . . . . . . . . . . . . . . . . . Taille dune image . . . . . . . . . . . . . . . . . . . . . . Un exemple : lhistogramme . . . . . . . . . . . . . . . . Rcuprer des informations sur un chier image . . . Rcuprer des informations EXIF sur un chier image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1023 1026 1041 1053 1065 1065 1072 1073 1078 1078

Les animations Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1082


Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1083 Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1084

Chapitre 14 La cration de documents PDF . . . . . . . . . . . . . . . . . . . . . . Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . Crer la base dun document PDF . . . . . . . . . . . . . Prciser les attributs (mots-cls) du document . . . . . Prciser les paramtres de la page . . . . . . . . . . . . . Afficher du texte . . . . . . . . . . . . . . . . . . . . . . . . Dessiner des formes gomtriques . . . . . . . . . . . . Modier les paramtres du trac . . . . . . . . . . . . . . Inclure une image . . . . . . . . . . . . . . . . . . . . . . Ajouter des liens et des annotations . . . . . . . . . . . . Ajouter des chiers attachs et aperus (thumbnails) . Modier le systme de coordonnes . . . . . . . . . . . Lire, sauvegarder et restaurer les paramtres courants

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

1137 1139 1140 1144 1144 1146 1152 1157 1163 1166 1170 1171 1173

Sommaire

Crer un modle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1178 Chapitre 15 Lutilisation de XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1185 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1187


Prsentation du langage XML . . Le format XML . . . . . . . . . . . Exemple de document XML . . . Utilisation des documents XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1187 1187 1189 1191

Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1192 Les parseurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1192


Le parseur SAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1192 Le parseur DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1215 Le parseur SimpleXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1232

XSLT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1241
Prsentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1241 Les transformations de documents XML . . . . . . . . . . . . . . . . . . . . . . 1243

Gnration de messages XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1254


Les messages WDDX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1254

Chapitre 16 La gestion des protocoles HTTP, FTP, SOAP, etc. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1263 Fonctions rseau (de base) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1265 Rseau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1265
Adresses IP et DNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1265 Protocoles et services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1269

Les sockets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1270 FTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1275


Installation . . . . . . . Les fonctions de base . Exemple dapplication Autres fonctions .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1275 1276 1281 1286

CURL (client URL Library) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1288


Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1289 Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1290 Exemples dapplications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1295

SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1299
Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1303 Utiliser les classes PEAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1303 Interroger Google via PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1304

Sommaire

Chapitre 17 Les processus et les identiants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1309 Excution dun programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1311 POSIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1313 Chapitre 18 Linteroprabilit avec COM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1325 COM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1327
Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1327 Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1327

Chapitre 19 Loptimisation des temps de rponse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1339 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1341 Environnement de test des solutions "bas niveau" (modules PHP) . . . . . . . . . 1342
Conguration matrielle Pages testes . . . . . . . . Instrument de mesure . . Prsentation des mesures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1342 1343 1345 1345

En labsence de solution doptimisation . . . . . . . . . . . . . . . . . . . . . . . . 1346


Mesures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1346

Avec Zend Optimizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1349


Description . Installation . Mesures . . . Conclusion . Description . Installation . Mesures . . . Conclusion . Description . Installation . Mesures . . . Conclusion . Description . Installation . Mesures . . . Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1349 1350 1354 1357 1358 1358 1359 1362 1362 1363 1363 1366 1366 1367 1373 1376

Avec Alternative PHP Cache (APC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1358

Avec PHP Accelerator (PHPA) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1362

Avec Zend Accelerator (Zend Performance Suite) . . . . . . . . . . . . . . . . . . 1366

Sommaire

Conclusion sur les solutions "bas niveau" (modules PHP) . . . . . . . . . . . . . . 1376 Les solutions "haut niveau" (programmation PHP) . . . . . . . . . . . . . . . . . . 1377 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1378 Chapitre 20 Lobfuscation : Distribuer ses scripts sans dvoiler son code . . . . . . . . . . . . . . . . . . . . 1379 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1381 Avec Zend Encoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1381
Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1382 Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1386 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1388

Avec ionCube PHP Encoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1388


Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1389 Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1389

Avec PHP guardian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1389 Avec POBS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1390


Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1390 Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1390 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1392

Autres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1392 Chapitre 21 Annexe A : des exemples dapplications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1393 Administration de bases de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . 1395
phpMyAdmin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1395 Autres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1400

Cration de sites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1401


PHPNuke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1401 SPIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1405 Autres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1407

Forums de discussion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1407


PHPbb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1407

Phorum : un moteur de forums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1409


Autres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1411

Annuaires de liens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1412


Netref . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1412 Autres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1413

Solutions de travail collaboratif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1413


Moregroupware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1413 Autres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1416

Sommaire

Graphiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1416
JPGraph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1416

Chapitre 22 Annexe B : les en-ttes HTTP et les variables externes . . . . . . . . . . . . . . . . . . . . . . . . 1419 Chapitre 23 Annexe C : les erreurs HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1425 Chapitre 24 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1429

Laurent GUEDON Je ddie ce livre tous mes amis et plus particulirement...


j j j j

Philippe, Amiel (les comptences) et lquipe de Felix ainsi qu la socit Cyberbrain (mon couffin) ; Myriam, si adorable ; mes parents pour leur soutien ; la winwin team, Zou et Syl.

Damien HEUTE Parce quil y a des choses plus faciles crire qu dire, je ddie ce livre :
j j j j

mes parents que jaime et qui mont toujours apport un soutien indfectible ; mes frres et mon neveu qui peut-tre, un jour, sintressera la version 2015 de PHP ; mes collgues qui par leur bonne humeur leur et professionnalisme mont beaucoup appris durant ma premire exprience professionnelle ; mes amis que jai un peu dlaisss pour crire ce livre.

Thomas HEUTE Je ddie lnergie apporte dans ce livre :


j j j j

mes parents et frres que jai peu vus durant la dernire anne ; Mon filleul Adrien, star du chapitre sur GD, et qui a encore le temps avant dapprendre le PHP ; Mes amis de France et des tats-Unis, que jai quelque peu dlaisss (Id like to thank my US friends and to apologize about having been so busy. By the way, well keep in touch) ; Aux membres actifs de lESIAL Roller Dream Team 1999-2000.

Pierre-Emmanuel MULLER
Merci Amiel, Sylviane, Pierre, Rgis Priqueler (http://www.aizenko.com) et Steph Pineau (http://steph.pineau.free.fr/php/).

Prface
qui sadresse ce livre ?
Ce livre a t crit avec, en constante toile de fond, les attentes des lecteurs lgard de ce que doit tre la Bible dun langage de programmation ; savoir quelle doit pouvoir rpondre aux interrogations du novice comme celles de lutilisateur expriment. Une brve histoire du PHP, ainsi quune introduction la philosophie du logiciel libre, vous montreront quautant PHP aide au dveloppement de lInternet autant Internet contribue lvolution de PHP et offre quantit de ressources qui lui sont lies. Les dbutants ne seront pas laisss sur le bord du chemin ds les premires pages puisque les diffrentes possibilits dinstallation de PHP font lobjet dun chapitre complet et dtaill o les principaux diteurs du march sont galement passs en revue. De trs nombreux aspects de PHP sont couverts dans cet ouvrage et la majeure partie des fonctions prsentes sont illustres par des exemples mettant bien en avant leur utilisation et comportement. Voil pourquoi ce livre est plus quune simple documentation de base. Le PHP est replac dans une optique dapprentissage, ainsi que dans une ide dutilisation au quotidien. Le lecteur apprendra vite produire des formulaires, crer des images, manipuler des fichiers ainsi que des bases de donnes, ou encore envoyer des e-mails. Le novice sera pris par la main pour quaucune zone dombre ne puisse subsister. Mme si la prsentation de la programmation procdurale nest pas dlaisse, ce qui peut vous permettre de tirer partie de ce livre si vous restez attachs la version 4 de PHP, la programmation oriente objet est bien videmment prsente minutieusement afin de tirer pleinement partie de PHP5. Une fois acquis les premiers rudiments, lutilisateur devenu initi, trouvera dans ce livre de quoi aller plus avant dans sa matrise du PHP. Il pourra apprendre utiliser des bases de donnes professionnelles ainsi que les annuaires LDAP. Il pourra manipuler les documents XML, crer des animations flash ou des fichiers PDF, accder aux fonctionnalits rseau dont SOAP voire utiliser PHP en conjonction avec COM. Enfin, pour une utilisation vritablement professionnelle, il aura tout intrt consulter les comparatifs de solutions doptimisation et dobfuscation du code. Comme le dmontrent les tmoignages dutilisateurs qui ont fait le choix du langage PHP, bien quhistoriquement cr pour les besoins dune page "perso", PHP a dsormais sa place dans le monde de lentreprise.

Les auteurs
Les quatre auteurs de cette Bible disposent tous dune exprience diffrente de PHP. Venant dhorizons divers, ils ont tenu mettre en commun leurs approches pour balayer le maximum daspects relatifs au PHP.

21

Prface

Damien HEUTE
N en 1972, ingnieur E.N.S.P.S. (cole nationale suprieure de physique de Strasbourg), spcialit traitement dimages, Damien a travaill trois ans et demi en tant quingnieur tude et dveloppement pour un grand groupe europen daronautique et de dfense. Il y a mis en uvre les technos C, C++/CORBA, Java, et, dans une moindre mesure, des technologies relatives lInternet et aux bases de donnes professionnelles. Il a ensuite pass dix mois en tant quingnieur tude et dveloppement pour une start-up spcialise dans laide la navigation via Internet sur des supports "sans fil", o il a mis en uvre des technologies Java et JSP/Servlet. Maintenant dans un grand groupe franais acteur majeur de la tlphonie mobile, de la biomtrie et de la dfense, il conoit et dveloppe, dans le cadre de gros projets, des applications web bases sur le langage Java. Il pratique le PHP titre personnel, en particulier pour les sites http://www.ootoogo.com et
http://www.toutestfacile.com

Il aime le VTT et le cyclisme sur route, il fait un peu de photo et beaucoup dinformatique.

Thomas HEUTE
N en 1977, il a suivi ses tudes lESIAL (cole suprieure dinformatique et applications de Lorraine) et possde de nombreuses comptences dans le domaine informatique. Thomas connat bien les systmes Windows, Linux ou UNIX. Les langages dans lesquels il est le plus laise sont Java et PHP. Il matrise galement de nombreuses bases de donnes, ainsi que des outils de conception de logiciels (UML ou MERISE). Il a travaill trois ans au National Institute of Standards and Technology (USA), o il a effectu des recherches sur la scurit et les PDA aprs avoir travaill sur les systmes denregistrement dobjets par XML (ebXML). Il est galement lorigine du site http://www.toutestfacile.com, site vocation denseignement du PHP, du SQL et du XML. Il sinvestit dans le dveloppement Open Source avec "Nukes the JBoss Portal" en Java/J2ee. Il aime la batterie, la guitare et la photographie mais surtout linformatique.

Laurent GUEDON
N en mai 1975, ce qui, pour lui, est dj trs (trop) loin. Aprs une formation E.E.A (lectronique), Laurent, vouant une grande passion au dveloppement Internet, a rejoint en 1999 une SSII spcialise dans le dveloppement dapplications et de sites Internet. Laurent est dveloppeur PHP depuis PHP 2, ses premiers pas ayant t effectus sur lex-hbergeur AlternB. Dveloppeur indpendant depuis septembre 2002, il est charg denseignement la facult de Rennes. Il pratique (plutt mal) la guitare, fait du roller et se fait de petits trous dans la peau avec des piques en mtal (il appelle a le piercing). Mais, surtout, il ne se spare jamais de son Psion qui lui permet de dvelopper pendant ses dplacements.

22

Prface

Pierre-Emmanuel Muller
Journaliste spcialis dans linternet et les nouvelles technologies, il a un intrt marqu pour tout ce qui touche la protection de la vie prive ainsi quaux logiciels libres. Il a particip diverses traductions dapplications libres. Il est lauteur ou coauteur de plusieurs ouvrages de vulgarisation informatique (Scurisez votre PC, Montez votre serveur de A Z, Utiliser les logiciels libres, etc.).

23

Chapitre 1

Introduction
1.1 1.2 1.3 1.4 1.5 quoi sert PHP ? . . . . . . . . . . . . . . . . . Les version 1 5 de PHP . . . . . . . . . . . . La communaut du libre . . . . . . . . . . . . PHP face ses concurrents (ASP, JSP, etc.) Pourquoi ont-ils choisi PHP ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 29 35 40 45

quoi sert PHP ?

1.1.

quoi sert PHP ?


1. Introduction

Prsentation, rle et fonctionnement dun langage de script


Avant de prsenter le langage PHP, il est utile de situer brivement sa place sur linternet. Comment, en effet, bien comprendre lutilit dun langage de script si la notion de "serveur" est encore floue ? LInternet est un rseau de rseaux, constitu dordinateurs connects entre eux. Sa structure est maille, non pyramidale. Il y a bien des chelons, mais les chelons les plus levs sont, en fait, assez proches de la base, et sont, surtout, en trs grand nombre. Ces chelons sont interchangeables. Quand votre chelon suprieur est absent, en panne, ou disparu, vous pouvez utiliser un autre chelon de mme type. En bref, deux machines sont gnralement interchangeables. Il est ainsi trs difficile de "diriger" lInternet. Comme tout bon processus de communication, Internet dispose dun langage (en fait de plusieurs langages) qui dpend du service que vous dsirez utiliser (web, mail, ftp, etc.). Quel que soit le service en question, ce langage est commun toutes les machines informatiques, et est indiffrent aux plateformes. Les donnes provenant dInternet sont donc, moyennant parfois quelques retraitements, rutilisables par tout ordinateur. Ainsi, un site web est construit indpendamment de la plateforme sur laquelle il est conu. Ce sont les logiciels qui sadaptent aux machines. Il existe un navigateur web (Netscape) pour PC et une autre version pour Mac. Les donnes quils exploitent, en revanche, sont indpendantes des systmes dexploitation (Windows, MacOs, Linux, etc.). Les composantes les plus connues de lInternet sont le Web (World Wide Web) ou le courrier lectronique (e-mail). Concentrons-nous sur le Web, car cest de cela quil est question avec PHP. Admettons que vous dsirez consulter le site web du moteur de recherche Google. Vous donnez ladresse http://www.google.com votre navigateur, vous lancez la recherche, et, quelques secondes plus tard, la page daccueil du site saffiche sur votre cran. En fait, derrire cette action se cache toute une interaction client-serveur, primordiale intgrer pour bien saisir le fonctionnement de PHP. Votre navigateur, le client, interroge un serveur, en lui demandant la page daccueil dun site. Le serveur est une machine qui hberge le site web en question. Cette machine doit tre, en principe, connecte en permanence au rseau. Concrtement, ce sont les disques durs de cette machine qui stockent les pages HTML ou PHP qui seront demandes par les internautes. Pour que le serveur soit en mesure de vous rpondre, il faut que certains programmes et services soient prsents et fonctionnels en son sein. Dans le cas dun site web, il faut que le serveur dispose dun serveur web, cest--dire dun programme permettant linterprtation et la diffusion des pages demandes par les internautes. Votre navigateur demande la page, le serveur web reoit et comprend votre requte, il recherche la page en question et, si elle est disponible, vous la retourne. En fait, il ne vous retourne que le code source de la page, en gnral du HTML, mais ce peut tre une image ou une animation. La mise en forme, la construction et laffichage de la page incombent votre navigateur. PHP est un langage de script HTML, cest--dire quil fonctionne en relation avec le langage HTML (HyperText Markup Language). Il fonctionne du ct du serveur, et non pas du ct du client, et permet de gnrer des pages web " la vole". Concrtement, un script PHP est intgr au code source dune page HTML. Lorsque la page est appele, le script PHP est interprt, et le tout est livr au serveur web qui, au final, rpond au navigateur de linternaute. Le surfeur obtient une page HTML tout ce quil y a de plus classique, la diffrence que cette page

27

Chapitre 1

Introduction

nexistait pas en tant que telle sur le serveur web. On dit alors que la page a t cre " la vole", ou dynamiquement.

1. Introduction

Plus concrtement, prenons une page HTML toute simple dont voici le code source :
<html> <head> <title>Je teste le langage PHP</title> </head> <body> </body> </html>

Voici un script PHP sans prtention :


<?php echo ("PHP est un palindrome."); ?>

Pour intgrer ce script la page HTML, il suffit, ici, dinsrer le code entre les balises <body> et </body> de la page. Ce qui nous donne alors ceci :
<html> <head> <title>Je teste le langage PHP</title> </head> <body> <?php echo "PHP est un palindrome."; ?> </body> </html>

Cest aussi simple que a. Comme vous pouvez le constater, le script PHP est encadr par une balise de dbut et une de fin ( savoir <?php et ?>). Ce sont des informations qui, la lecture de la page, indiquent au serveur quil doit interprter ces informations comme de PHP, et non plus comme du HTML. Un script est dfini comme suit par le jargon Linux France : "Une suite dinstructions simples, peu structures, permettant dautomatiser certaines tches [...]". Dit ainsi, cest assez cinglant. En clair, un script PHP vous permet non seulement de gnrer du texte ou du code HTML, mais galement denvoyer un courriel, daccder une base de donnes, de lancer un programme sur le serveur, etc. Il est donc ainsi possible de compter le nombre de visiteurs sur votre page, de grer un livre dor ou bien mme de raliser des applications web part entire, comme des gestionnaires de contenus (PHPNuke, DaCode, SPIP, etc.) ou des outils de travail collaboratifs (PHPGroupware, par exemple). En fait, PHP possde les mmes fonctionnalits que les autres langages de script. Son gros atout rside dans son fonctionnement rsolument tourn vers le Web. En natif, ce sont plus de vingt bases de donnes qui sont supportes par PHP, sans que lutilisateur ait faire quoi que ce soit. Tous les grands protocoles de linternet fonctionnent, eux aussi, sans autre forme de procs avec PHP : SMTP, POP3, IMAP, FTP, SNMP, etc.

28

Les version 1 5 de PHP

1.2.

Les version 1 5 de PHP


1. Introduction

Rasmus Lerdorf
Chaque grand projet libre a un pre ou un leader charismatique. PHP ne droge pas la rgle. Qui plus est, lhistoire de PHP facilite les choses, ses premiers pas tant tout ce quil y a de plus simple narrer. Les premires esquisses de PHP sont le fait dun seul homme : Rasmus Lerdorf. Sur son site personnel, Rasmus Lerdorf reste assez discret. Les rares lments que lon peut glaner sur son parcours personnel se limitent des expriences professionnelles ou quelques hauts faits de programmation. On en apprend mme plus en suivant lhistoire de PHP, intimement lie celle de son crateur, tout au moins dans les premires annes. Rasmus Lerdorf est n en 1969 sur lle de Greenland. On comprend que le petit Rasmus ait prfr linformatique lagriculture, tant lle de Greenland est peu clmente : les terres arables, les forts et les pturages permanents reprsentent peine 1 % de la superficie totale de lle. Lle de Greenland est tout de mme dune superficie trois fois suprieure celle du Texas (2 170 000 km_) pour une population infrieure celle de lle de Guernesey qui ne fait que 78 km_ (56 300 personnes).
Figure 1.1 : Rasmus Lerdorf

Rasmus Lerdorf ne se dfinit pas comme un programmeur, mme si le fait quil soit capable de faire fonctionner PHP sur son magntoscope conduit le spectateur penser le contraire. Il na pas de diplme dinformaticien, mais une formation dingnieur. Il a travaill pour des socits comme Bell, IBM ou Linux Care. Selon une tude mene grands coups de scripts Perl par Per Abrahamsen, Rasmus Lerdorf est lun des Danois les plus clbres. Il arrive mme, dans le classement, avant le penseur Soren Kierkegaard. Signalons enfin que Rasmus Lerdorf, en bon dveloppeur du logiciel libre, nest pas dnu de sens de lhumour. Le petit dernier des Lerdorf a pour nom Carl Alexander Lerdorf. Sur le site de la famille Lerdorf, son nom se lit : Carl AlexandeR Lerdorf Rcursif, quand tu nous tiens !

Quelques sites (en anglais) Site officiel de la famille Lerdorf (avec les photos du petit Carl Alexander Lerdorf) :
http://www.lerdorf.com

Les Danois clbres :


http://www.dina.kvl.dk/~abraham/fame/fame.html

29

Chapitre 1

Introduction

Naissance et volution de PHP


1. Introduction

Naissance et premire version


La premire version de PHP nen tait pas une. Ce ne furent que quelques outils dvelopps par Rasmus Lerdorf pour les besoins de son site personnel. Dans le courant de lanne 1993, M. Lerdorf avait commenc dvelopper des scripts en langage C et en Perl. partir de l a pu tre constitue, en septembre 1993, une premire librairie. Lass de devoir rcrire encore et toujours les mmes portions de code, M. Lerdorf eut lide de sparer sa logique de programmation de celle du HTML, afin de pouvoir rutiliser plus facilement certaines portions de code. Pour quune premire version de PHP comme langage de script voie le jour, il ne manquait plus la librairie quun interprteur capable danalyser le code HTML, pour y reprer des balises particulires et appeler les fonctions qui y sont lies. Cela fut fait en novembre 1993, date laquelle M. Lerdorf situe la naissance de la toute premire version de PHP. La premire mouture du langage navait donc pas de trs grandes ambitions. PHP se limite alors un interprteur qui analyse une page HTML, en ressort des balises (inspires du SGML), et appelle les fonctions correspondantes ces balises. Tout cela dans quel but ? Afin de compter et denregistrer le nombre de visiteurs consultant un curriculum vitae sur son site personnel. Rasmus Lerdorf rsume ses motivations une lassitude face Perl, jug comme tant trop lent et dot dun analyseur trop restrictif. Cette premire version neut quun succs trs limit, et pour cause elle ne fut jamais publie. Il faut attendre fvrier 1994 pour quune premire version de PHP soit enfin diffuse.

Interviews de Rasmus Lerdorf Interview de Rasmus Lerdorf dans le Journal du Net :


http://developpeur.journaldunet.com/itws/it_phpnexen_rasdorf.shtml

Interview de Rasmus Lerdorf pour OReilly (en anglais) :


http://web.oreilly.com/news/lerdorf_0200.html

PHP 2 et louverture sur le monde


La premire utilisation plus large de PHP remonte au site http://www.io.org. Rasmus Lerdorf rutilisa son langage de script pour installer divers petits outils en ligne (un compteur de visiteurs, laffichage de la dernire personne connecte, etc.). Alors, le succs de PHP fut immdiat. Dautres utilisateurs du site voulurent utiliser PHP, et les scripts poussrent dans le HTML comme les champignons dans un sous-bois humide. tant donn que linterprteur voqu plus haut tait lui-mme un CGI, les administrateurs du site reprrent rapidement le changement. PHP se rvlait fort gourmand en ressources. Pour remdier cela et viter une mort certaine du langage, Rasmus Lerdorf se pencha alors sur le serveur web pour y inclure PHP comme module interne plutt que de le conserver en module externe (CGI), beaucoup plus lourd. Le serveur utilis tait HTTPD NCSA, de lUniversit de lIllinois. Une fois PHP ajout au serveur, M. Lerdorf convainquit tout de mme les administrateurs de passer sous Apache, serveur web beaucoup plus souple utiliser et programmer.

30

Les version 1 5 de PHP

Cest cette poque que M. Lerdorf obtint un emploi luniversit de Toronto. Sa mission tait de mettre en place un systme de connexion lInternet gr depuis une interface web. Le tout faisait intervenir une base de donnes des tudiants, des serveurs, des terminaux Cisco ainsi que quelques autres composants. En recherchant un outil utilisable dans la mise en place de cette architecture, Rasmus Lerdorf se rendit compte quil ny avait rien qui lui plaisait rellement. Il dcida donc de rcrire linterprteur de PHP et ses outils connexes, pour les rendre plus facilement multi-usages et gnralistes. PHP devait tre capable de dialoguer avec des bases de donnes ou dautres sources extrieures (comme, par exemple, des formulaires HTML). Ce sera nouveau, pour Rasmus Lerdorf, loccasion dutiliser PHP et de le faire progresser. Anciennement Personal Home Page, PHP sappelle alors PHP/FI (PHP/Form Interpreter, interprteur de formulaires), du fait des nouveaux outils ajouts par M. Lerdorf pour interfacer PHP avec des bases de donnes. La syntaxe de PHP/FI reste simple, encore un peu incohrente et assez proche du Perl. PHP/FI connat alors un trs large succs. De nombreux dveloppeurs utilisent PHP, et non pas seulement pour interroger des bases de donnes. PHP/FI sert dj crer des pages web au contenu dynamique, ce qui sera lune des applications les plus populaires du langage par la suite. Il prsente dj certaines des principales fonctionnalits de PHP. En 1997, ce sont dj plus de 50 000 sites qui utilisent PHP.

1. Introduction

PHP 3
Publie en juin 1998, aprs neuf mois de tests, la troisime version du dsormais officiellement nomm PHP (PHP : Hypertext Preprocessor, le premier P faisant rfrence PHP lui-mme. Rcursif quand tu nous tiens...) fait un grand bond en avant. La sortie de cette nouvelle version correspond galement une solide refonte du moteur de PHP. Deux dveloppeurs, Zeev Suraski et Andi Gutmans jugeaient que PHP/FI ntait pas assez performant pour leurs applications de commerce en ligne, et dcidrent donc de le rcrire. PHP 3 fut annonc comme le successeur officiel de PHP/FI. Lune des principales nouveauts de PHP 3 principale en tout cas au regard de son dveloppement fut une API (Application Programming Interface, interface de programmation dapplication) qui permit de nombreux dveloppeurs de participer au dveloppement du langage. De plus, PHP supportait dsormais la syntaxe objet, sa syntaxe propre devenant, elle, plus cohrente et solide. La version finale de PHP 3 fonctionnait sur de nombreuses plateformes, avec de nombreux serveurs web et bases de donnes. Les protocoles SNMP ou IMAP taient alors supports moyennant une compilation approprie. PHP pouvait tre utilis en mode CGI avec la plupart des serveurs HTTP, ou bien tre charg en module, comme par exemple avec Apache. De nombreuses fonctionnalits avaient t ajoutes PHP 3, mais, en plus, cette sortie concidait avec lattente de nombreux nouveaux webmestres qui avaient besoin dun outil simple pour ajouter une touche de dynamisme leurs sites web. La fin des annes 1990 fut, en effet, une priode faste pour le Web, port dans sa croissance par larrive de lInternet dans le grand public. PHP permettait alors de mettre en place trs facilement une solution de commerce en ligne, des albums photo, des systmes de gestion de contenus, etc. Sa facilit daccs et dusage, ainsi quune gamme doutils rsolument tourns vers le Web, faisaient de ce langage la solution idale pour de nombreux webmestres. la fin de lanne 1998, plus dun million de serveurs web devaient utiliser PHP 3. Le langage de script avait conquis plusieurs dizaines de milliers dutilisateurs.

31

Chapitre 1

Introduction

PHP 4
Fidle la toute jeune tradition, PHP 4 allait une nouvelle fois entraner une rcriture complte de son moteur. Ds lhiver 1998, Andi Gutmans et Zeev Suraski se penchrent sur le moteur interne du langage pour le reprendre de fond en comble. Leur objectif tait de rendre PHP encore plus performant (ce que lon comprend aisment), et de rendre le code encore plus modulaire. Il fallait galement permettre au PHP dtre plus laise avec des applications complexes. PHP 3 posait problme face ces applications complexes. Sa syntaxe permettait leur excution, mais le moteur du langage navait pas t conu pour les faire fonctionner efficacement. Lcriture dun nouveau moteur semblait alors ncessaire pour permettre au PHP de passer une nouvelle tape de sa croissance. Ce nouveau moteur devait porter le nom de ses deux crateurs : le Zend Engine, combinaison de ZEev et ANDi. Une premire version de PHP dot de ce nouveau moteur sortit dans le courant de lanne 1999. La publication officielle de la version finale fut annonce en mai 2000, six ans aprs le premier PHP. PHP 4 assurait une compatibilit ascendante par rapport PHP 3, et la migration de PHP 3 PHP 4 fut encore plus souple que celle de la version 2 la version 3. Outre un cur neuf, PHP disposait dune plthore de nouveaux membres. Dans sa quatrime version, PHP supporte quasiment tous les serveurs web du march, les bases de donnes les plus rpandues, plusieurs nouvelles structures de langage ou encore la bufferisation de sortie. On compte galement des amliorations en matire de scurit. Larchitecture de PHP 4 est encore plus ouverte et volutive que celle de PHP 3. On remarque notamment la cration dune interface ISAPI (Internet Server Application Programming Interface, outil de spcification des DLL pouvant tre utilis par les serveurs web de Microsoft). PHP 4 permet galement dinstancier et de manipuler des classes Java comme si elles taient de simples classes PHP. PHP peut aussi excuter des servlets. Autre amlioration majeure de PHP 4 : lintroduction des sessions en mode natif. Limpossibilit pour PHP 3 de grer les sessions constituait une grosse lacune pour un langage tout entier tourn vers le Web. Cette faiblesse ne jouait pas en faveur de PHP, tout particulirement face lASP qui, lui, savait dj grer les sessions. La lacune de PHP 3 pouvait certes tre comble via des solutions comme PHPLib, mais linclusion en mode natif dans PHP 4 rglait dfinitivement la question. PHP 4 marque galement lentre du langage dans le monde des socits commerciales. Les deux pres fondateurs de PHP 3, Zeev Suraski et Andi Gutmans, crrent la socit Zend pour distribuer et vendre des produits gravitant autour de PHP. Si le Zend Engine reste libre, bien que sous une licence assez critique jusque dans sa seconde version, certains produits commercialiss par Zend sont des logiciels propritaires. Signe vident dune maturit du langage, PHP devient alors le support dun commerce tourn vers les grands comptes de lInternet. Belle volution pour ce qui ntait, au dpart, quune petite collection de scripts Perl destins compter des visiteurs... La communaut PHP ne compte plus seulement des dveloppeurs ou des webmestres. Dsormais, de nombreux internautes participent la documentation de PHP, sa traduction ou son annotation. En France, par exemple, la socit Nexen hberge la documentation officielle de PHP en franais, dont elle a produit une version annote. Le projet Pear regroupe, lui aussi, de nombreux participants, qui ne sont pas directement impliqus dans le dveloppement de PHP. On compte aujourdhui plusieurs millions de sites web qui utilisent PHP. En se basant sur ce comptage des noms de domaines, on peut dire que cela reprsente 20 % de lInternet. Les dveloppeurs, eux, sont des centaines de milliers lutiliser. Le site Security Space tient jour une liste des modules Apache les plus utiliss. En juin 1998, PHP tait prsent sur 8 % des sites audits par Security Space. En mars 2002, presque 45 % des sites audits avaient install le

1. Introduction 32

Les version 1 5 de PHP

module PHP pour Apache. Perl, lui, tait, la mme date, prsent sur 20 % de ces sites (rappelons que Perl date de 1987 et PHP de 1994).

1. Introduction

Figure 1.2 : Le nombre de sites utilisant PHP crot de jour en jour

PHP 5
La tant attendue version 5 de PHP est sortie le 13 juillet 2004. Elle apporte de trs nombreuses nouveauts tout en conservant une large compatibilit avec PHP4. Si la grande nouveaut de la version 5 reste le nouveau modle orient objet, les dveloppeurs de PHP nont pas oubli lhritage des 4 prcdentes versions qui ont permis de trs nombreux dveloppeurs de faire leurs premiers pas dans le monde du script pour le web. La plupart des scripts crits pour PHP4 devraient fonctionner sans modifications avec PHP5. Il existe toutefois quelques diffrences dont la liste est disponible sur le site officiel du projet PHP.

Incompatibilits entre PHP4 et PHP5 Mme si vos scripts crits pour PHP4 ont de trs larges chances dtre compatibles avec PHP5, certaines incompatibilits ou modifications sont connues et listes. Le site officiel PHP en dnombre une dizaine. Vous les trouverez cette adresse :
http://www.php.net/manual/fr/migration5.incompatible.php

Lvolution de PHP
PHP, et avec lui toute la communaut de dveloppeurs, doit faire face des questions indites. Sa taille provoque des soucis dchelle, dj rencontrs par dautres projets (comme Linux, par exemple). Jusqu prsent, les rponses apportes par la communaut aux problmes apparus furent satisfaisantes, tout au moins assurrent-elles sa survie et sa croissance, sans nuire la qualit du langage. On peut citer, titre dexemple, la mise en place dune quipe dassurance qualit durant lt 2000 pour faire face aux nombreuses critiques suscites par la pitre qualit des premires versions de PHP 3. Le langage avait, en effet, t test sur trop peu de plates-formes diffrentes. Dsormais, une quipe complte de dveloppeurs a pour objectif principal de chasser le bug au sein du projet PHP.

33

Chapitre 1

Introduction

1. Introduction

Alors que PHP est un langage de script n du Web pour le Web, lon voit mme natre des projets impliquant PHP, qui nont plus rien voir avec les objectifs premiers du langage. PHPGtk est ainsi une solution permettant de dvelopper des applications en PHP partir dune interface graphique ct client. De mme, lentre en jeu de socits commerciales a amen des questionnements soulevs par des acteurs du monde du libre, comme la FSF (cf. problme de la licence du moteur Zend). Encore une fois, la communaut PHP a su faire preuve de beaucoup de pragmatisme dans ses rponses. Rsultat des pressions de la FSF, Zend a chang la licence de son moteur. PHP 4 reste, pour sa part, sous une licence Apache, juge plus souple pour les dveloppeurs. Et, quand on demande aux dveloppeurs de PHP comment ils prennent les critiques que lon peut leur adresser parce que PHP 4 nest pas GPL, ils vous rpondent avec des frites. Si Rasmus Lerdorf a pu tre, un moment, une figure de proue de PHP, et quil reste aujourdhui encore son reprsentant le plus mdiatique, on peut tout de mme remarquer que la communaut PHP ne bnficie pas dune structure centralisatrice qui ferait linterface entre le langage et les entreprises ou les institutions. Le logiciel libre a lOpen Source Initiative ou la FSF, un projet comme Kde dispose de toute une infrastructure qui assure sa promotion ou sa reprsentation, Linux a Linus Torvalds. Vu de lextrieur, le monde de PHP parat encore flou.

PHP La socit Zend, ditrice du Zend Engine (en anglais) :


http://www.zend.com

La socit Nexen :
http://www.nexen.net

Nombre de sites utilisant PHP (en anglais) :


http://www.php.net/usage.php

Modules Apache les plus utiliss (en anglais) :


http://www.securityspace.com/s_survey/data/man.200203/apachemods.html

Des projets attachs au PHP :


http://php3.de/manual/fr/html/history.php.related.html

Interview du crateur de PHPGtk (en anglais) :


http://beta.usephp.net/article.php3?id_article=3p

La cration de la communaut
Si PHP a pu crotre et prosprer jusqu devenir lun des langages de script les plus utiliss, cest en grande partie grce une communaut de dveloppeurs qui, ds la version 3, fut la cheville ouvrire de ses amliorations. PHP/FI, seconde version du langage, reste luvre dun seul homme, Rasmus Lerdorf, pre de PHP. partir de la version 3, Rasmus Lerdorf nest plus seul la tte de PHP. Zeev Suraski et Andi Gutmans prirent en main, par deux fois, la refonte complte du moteur de PHP. Cette ouverture de PHP est due une interface API mise en place trs tt, mais, surtout, la volont de son crateur de partager son travail avec dautres dveloppeurs. Rasmus Lerdorf le dit lui-mme : il a toujours appris en regardant le code dautres programmeurs. Ne pas faire profiter, en retour, la communaut de son travail ne lui a mme pas travers lesprit.

34

La communaut du libre

Comment cette communaut est-elle ne ? Dans une interview, Rasmus Lerdorf situe sa date de naissance au jour o, alors employ par luniversit de Toronto, il avait mis en ligne son code source disposition sur une page web. Cela dans loptique vidente que dautres puissent en profiter. Il navait alors aucune ide de qui utilisait PHP de par le monde, ni pour quelles applications. Un beau jour, il reut un courriel dun utilisateur japonais, qui lui faisait parvenir un patch. Le patch tait tout fait fonctionnel et pertinent. Il rsolvait un problme auquel Rasmus Lerdorf navait pas encore eu affaire, mais qui allait se poser inluctablement. PHP bnficiait dune aide extrieure, la communaut tait ne ; elle compte aujourdhui plus de 300 dveloppeurs.

1. Introduction

La communaut PHP Rasmus Lerdorf raconte la naissance de la communaut :


http://developpeur.journaldunet.com/itws/it_phpnexen_rasdorf.shtml

1.3.

La communaut du libre

Pourquoi prsenter le monde du logiciel libre dans un livre traitant de PHP ? Simplement parce que, sans cette communaut, PHP ne serait pas ce quil est aujourdhui. Si la marque du monde du libre nest pas particulirement visible sur le langage lui-mme, sa philosophie et son mode de dveloppement ont eu, et ont toujours, une influence notable sur le langage PHP et sa croissance. Il suffit de voir le rle prpondrant que joue le triptyque Apache-MySQL-PHP dans le monde du Web face des solutions comme IIS-ASP-Access. PHP est indissociable du monde du libre. Cette partie na pas pour objectif de faire lapologie du logiciel libre, ni mme de faire un comparatif entre code source ouvert ou code source ferm ; tout comme le souligne Linus Torvalds lui-mme, les deux existent et cest tant mieux. Il nous a pourtant sembl utile de prsenter le monde du libre, pour permettre celui qui dcouvre PHP, dune part de comprendre le contexte de sa croissance et de son volution, et dautre part de savoir vivre dans le monde de PHP. Celui qui ne sait pas que les dveloppeurs qui travaillent avec PHP distribuent largement leurs sources et discutent massivement en ligne de lvolution du langage et des questions techniques qui sy rattachent sera vite perdu et passera ct de lun des principaux atouts de PHP : sa communaut.

Historique
Le monde du logiciel libre plonge ses racines dans lhistoire des hackers (au sens premier du terme). Toute la culture du logiciel libre et son folklore doivent beaucoup aux pionniers de linformatique, ces "vrais programmeurs" : les hackers (selon la dfinition dEric S. Raymond). Pour une histoire complte et documente de cette culture, on se reportera Une brve histoire des hackers, par M. Eric S. Raymond. Disons simplement que les logiciels libres ne sont pas ns avec Linux. Leur histoire est bien plus riche et complexe. Cest dans lun des plus prestigieux laboratoires dinformatique du monde, celui dintelligence artificielle du MIT (Institut de technologie du Massachusetts) que sest cristallise lopposition entre logiciels libres et logiciels propritaires. Chef de file du laboratoire, et froce opposant la commercialisation des techniques mises au point dans ce laboratoire, Richard M. Stallman cra, en 1984, la Fondation du logiciel libre (Free Software Foundation, FSF). Hacker au sens

35

Chapitre 1

Introduction

propre du terme, il dveloppa alors des logiciels libres, dont le clbre diteur Emacs. M. Stallman entrepris alors de recrer un clone complet libre du systme dexploitation propritaire UNIX. Cest ainsi que naquit le projet GNU (GNU is not UNIX. Dcidment, acronyme rcursif quand tu nous tiens). La FSF avait pour objectif de soutenir et daccompagner des projets libres. Sa cration formalisait les thses et ides des dfenseurs du logiciel libre. Fortement imprgne de la culture de lchange et de la transmission libre des savoirs des milieux universitaire et scientifique, la FSF estime que "tout comme les ides, les logiciels ne sont pas tangibles et peuvent tre copis sans perte. Les transmettre est la base dun processus dvolution qui alimente le dveloppement des rflexions." (site de la FSF Europe, Quest-ce quun logiciel libre ?). Pour tre qualifi de libre, un logiciel doit, selon la FSF, rpondre quatre critres de libert. Tout dabord, un programme doit pouvoir tre excut pour nimporte quel usage. Ensuite, un utilisateur doit pouvoir tudier le fonctionnement du programme et ladapter ses besoins. Il doit galement tre possible de redistribuer des copies et, enfin, damliorer le programme en rendant publiques les modifications pour que lensemble de la communaut en bnficie. Pour assurer ces liberts aux logiciels libres, M. Stallman tablit la GPL : GNU General Public License.

1. Introduction

La machine en marche
Les logiciels de la FSF ne sont pas les seuls produits libres. De trs nombreux logiciels libres sont en rapport avec linternet. Sils ny sont pas directement lis, cest leur dveloppement qui en a profit. On peut citer Sendmail, dvelopp en 1981 par Eric Allman. Aujourdhui encore distribu gratuitement par la socit Sendmail Inc., Sendmail est lagent de transport de mails le plus utilis sur Internet. Il dtient plus de 75 % des parts de march. Autre figure historique et emblmatique du monde du libre : Perl. Perl signifie Pratical Extraction and Report Language (langage pratique dextraction et de rapport). Cest un langage de programmation trs largement utilis sur lInternet. Il sert principalement aux administrateurs de systmes et de rseaux. Il sert galement dans le dveloppement de CGI. On estime quune centaine de programmeurs participe au dveloppement de Perl. Les programmeurs utilisant Perl seraient 500 000 et les utilisateurs, eux, plusieurs millions. En se basant sur les ventes douvrages ddis chaque langage, les ditions OReilly estiment que Perl est aussi souvent utilis que Java. Apache est un projet libre denvergure ; peut-tre celui qui a dmontr le premier quun logiciel libre pouvait faire jeu gal avec les grandes entreprises de dveloppement de logiciels. Il dtient aujourdhui la plus importante part de march pour les serveurs web (source Netcraft), et cela face des acteurs aussi puissants que Microsoft ou Netscape. En juin 1998, le gant de linformatique IBM annonait soutenir officiellement le groupe Apache. Ce choix dApache par IBM fut une tape importante dans lhistoire des logiciels libres. Les impratifs commerciaux et conomiques qui prsident aux dcisions dIBM donnaient ce soutien Apache une valeur toute particulire. Un logiciel libre pouvait servir les intrts du monde commercial sans se galvauder ni perdre ses ambitions. Lhistoire de la FSF nest pas jonche seulement de russites. Lun des principaux checs de la FSF fut de mettre beaucoup trop de temps pour fournir un noyau son systme dexploitation (GNU). Cependant, lune de ses principales russites fut de fournir une trousse outils celui qui allait dvelopper le noyau libre le plus connu : Linus Torvalds. Cest en effet grce aux

36

La communaut du libre

logiciels de la FSF que le jeune tudiant de luniversit dHelsinki a pu dvelopper son propre UNIX libre, Linux. Linus Torvalds voulait dvelopper un UNIX pour son ordinateur personnel. Aprs avoir tabli les premiers lments de son systme dexploitation, il mit rapidement le code source la disposition des internautes du monde entier. Cest l que rside lune des particularits les plus importantes de Linux. Il est dvelopp et maintenu par des programmeurs du monde entier, grce lInternet. De grands acteurs de lindustrie informatique font dsormais confiance Linux (IBM, Sun, Dell, HP, etc.).

1. Introduction

Cathdrale et bazar
Ayant observ le dveloppement de Linux, Eric S. Raymond a voulu thoriser ce nouveau modle de dveloppement. Schmatiquement, il oppose deux modles : la cathdrale et le bazar. Le modle en cathdrale est un modle classique. Cest celui des entreprises et administrations classiques : centralis, trs hirarchis, il met beaucoup de temps ragir, et les dcisions sont soumises de multiples validations. Dans le modle bazar, tout est beaucoup plus horizontal, mouvant et flexible. Un modle ouvert et collaboratif comme le bazar permet une volution rapide et pertinente. Chacun est libre de soumettre un correctif ou une amlioration, ce qui vite de brider les initiatives.

La scission : lOpen Source


Richard Stallman na jamais fait lunanimit dans le monde du logiciel libre. Son dogmatisme et ses prises de position fermes taient vues par beaucoup comme des freins au dveloppement plus rapide du monde du libre, tout particulirement en direction des entreprises. Mme si la licence GPL ninterdit pas du tout la commercialisation dun logiciel libre, la FSF vhiculait une image hostile au monde du commerce. Daucuns pensaient que les ides dveloppes par la FSF nuiraient plus la croissance de la communaut du libre quelles ne la serviraient. De ce fait, des programmeurs et dautres acteurs du logiciel libre dcidrent de substituer le terme Open Source celui de Free Software, le terme "free" tant jug trop ambigu (en anglais, il dsigne aussi bien ce qui est gratuit que ce qui est libre). Afin de ne plus effrayer le monde de lentreprise, le mouvement Open Source vit donc le jour. On retrouvait sa tte certains des plus prestigieux acteurs du monde du libre comme, par exemple, Bruce Perens (ancien mainteneur du systme dexploitation Debian http://www.debian.org et fondateur du projet de standardisation Linux Standard Base) ou Eric S. Raymond. Lobjectif de ce nouveau mouvement tait clairement exprim : il sagissait de mieux vendre et promouvoir le logiciel libre. Il est important de bien comprendre que le courant de lOpen Source et celui des logiciels libres ne sont pas antinomiques, mais, quau contraire, ils sont complmentaires. Ils font la promotion du logiciel libre dans diffrentes directions. Toutefois, la FSF voit en lOpen Source un danger potentiel pour les logiciels libres. En effet, les points de divergence ne se situent pas seulement dans les termes, mais galement dans les licences, la dfinition du logiciel libre et lutilisation qui peut en tre faite. Pour quun programme soit dit open source, il faut quil respecte un certain nombre de critres dfinis comme suit par le mouvement Open Source. Tout dabord, le logiciel open source doit pouvoir tre librement donn ou vendu, sans que cela entrane lacquittement dune redevance ou de droits dauteur, et ce pour tous les utilisateurs de ce logiciel, sans distinctions. Le logiciel doit tre distribu avec son code source, qui peut tre modifi ou rutilis par lutilisateur condition que ce dernier respecte la licence du programme originel. Un logiciel peut tre open source mme si sa licence nautorise pas explicitement la rutilisation de son code source. ce

37

Chapitre 1

Introduction

moment l, la diffusion de patches (fichiers de modification) doit tre autorise. Une licence open source peut galement demander ce quune version modifie dun logiciel nait pas le mme nom que le logiciel "modle". Elle ne doit pas non plus tablir de discrimination lencontre de personnes ou de groupes de personnes, ni mme de distinctions relatives aux domaines dutilisation du logiciel (il peut tre commercial ou exploit dans des domaines qui sont sujets dbat, comme la recherche gntique par exemple). La licence ne doit pas tre limite un ensemble de logiciels. Chaque logiciel formant une "suite" doit bnficier de la licence open source. Cest la neuvime clause de la dfinition officielle de lOpen Source qui diffrencie principalement le mouvement Open Source de celui du logiciel libre. Elle dit : "La licence ne doit pas imposer de restrictions dautres logiciels distribus avec le programme. Par exemple, la licence ne doit pas exiger que tous les programmes distribus sur le mme support soient des logiciels open source." Malgr cela, lOpen Source reconnat la GPL comme tant compatible avec ses dfinitions : "La licence GPL est bien conforme cette clause. Les bibliothques sous licence GPL "contaminent" seulement les logiciels avec lesquels elles sont lies statiquement lors de la compilation, pas les logiciels avec lesquels elles sont distribues" (justification de la clause 9 dans la dfinition de lOpen Source). Mme si la porte reste ouverte, la FSF, elle, ne se reconnat pas dans lOpen Source. Elle continue daffirmer son attachement la porte philosophique du logiciel libre et considre lOpen Source comme "quelque chose de proche (mais pas didentique) au "logiciel libre"(cf. site de la FSF).

1. Introduction

Quelques liens La dfinition de lOpen Source :


http://www.idealx.org/fr/doc/fr-osd/fr-osd.html#toc1

La dfinition du logiciel libre :


http://www.fsfeurope.org/documents/freesoftware.fr.html

Licences compatibles avec la dfinition de lOpen Source :


http://www.idealx.org/fr/doc/fr-licences/fr-licences.html

Licences compatibles avec la dfinition de la FSF :


http://www.gnu.org/licenses/license-list.fr.html

Le droit et les logiciels libres


Signe de sa richesse et de sa complexit, le monde du logiciel libre regorge de licences sous lesquelles un dveloppeur peut placer son travail. On compte plus dune dizaine de licences dites "libres" ou apparentes. Pourquoi un tel foisonnement ? Parce que le logiciel libre ne date pas dhier et que les acteurs sont nombreux. Rien nempche une entreprise ou un particulier de crer sa propre licence se voulant libre. On peut citer les cas de Sun, Netscape, ou Apple, qui crrent leurs propres licences. Parmi toutes ces licences, on peut tout de mme noter que les plus rpandues sont : la GPL et la LGPL, la licence FreeBSD ou la MPL. PHP est un langage de programmation libre et ouvert. Il propose, par exemple, une API (Application Programming Interface, une interface de programmation dapplications) qui permet des dveloppeurs dajouter des fonctions au langage. Mais, encore une fois, rien nest simple. Les diffrentes versions de PHP nont pas t diffuses sous la mme licence. PHP 3 a t diffus sous licence GPL, tandis que PHP 4 nest pas

38

La communaut du libre

compatible avec la GPL. La licence actuelle (2.02) fait de PHP 4 un logiciel libre, mais il nest pas reconnu comme compatible avec la GPL. La FSF encourage lutilisation de PHP 3, diffus sous GPL. Les responsables de PHP expliquent leur choix en raison des aspects trop contraignants de la GPL. Les dveloppeurs ont dcid de publier PHP 4 sous une licence plus souple, pour permettre au PHP dtre le plus populaire possible. La licence de PHP 4 se rapproche de la licence dApache (PHP fait partie de la fondation Apache). Autre pomme de discorde : le Zend Engine, distribu avec PHP 4. Jusquen novembre 2001, le Zend Engine tait publi sous une licence QPL, non compatible avec la GPL. Depuis, Zend a chang la licence de son moteur pour une licence de type BSD, compatible, elle, avec la GPL. En tout tat de cause, avant de faire quoi que ce soit avec PHP, lisez attentivement sa licence et celle de tout produit connexe que vous utiliseriez, pour savoir sils sont compatibles avec ce que vous voulez en faire.

1. Introduction

Le texte (en anglais) des licences Licence PHP 4 :


http://www.php.net/license/2_02.txt

Licence Zend Engine :


http://www.zend.com/license/2_00.txt

PHP et le libre
Et la communaut PHP dans tout a ? Comme tout projet libre, PHP bnficie de nombreuses contributions apportes par des dveloppeurs bnvoles impliqus partout dans le monde. On estime plus de 300 membres la communaut des dveloppeurs PHP. Projet collaboratif, il tire avantage de tous les aspects positifs dun dveloppement libre. Les bugs dcouverts peuvent notamment tre corrigs rapidement. Cest grce son ouverture que PHP a pu crotre aussi vite. De par son API, il sest enrichi de nombreuses fonctionnalits comme, par exemple, le support des protocoles les plus utiliss sur linternet (comme POP3, IMAP, ou NNTP), un accs aux annuaires LDAP, ou bien encore un parseur XML. Langage n pour le Web, PHP dispose dune communaut en ligne trs active. Le pre de PHP, Rasmus Lerdorf, le dit lui-mme : PHP a t dvelopp par la communaut, et non pas par moi (interview Nexen pour le Journal du Net). Dune certaine manire, on peut comparer le dveloppement de PHP celui de Linux. Rasmus Lerdorf a eu le mme rle que Linus Torvalds. Il a initi le mouvement, a pos les premires bases, puis a permis des internautes dutiliser sa cration et den connatre le code source. Ces tapes pralables runies, la cration spontane dune communaut de dveloppeurs ntait plus trs loin. De nombreux sites proposent des centaines de scripts au tlchargement. Les dveloppeurs qui utilisent PHP nhsitent pas faire profiter le reste de la communaut de leurs crations. Que ce soit sur des sites "perso" ou des sites connus, un programmeur qui veut mettre en place un forum, un site de gestion de contenus, ou mme un freemail (de type Hotmail ou Caramail) ou un systme de knowledge managment trouvera, coup sr, des programmes en PHP qui rpondent dj ses attentes. Lun des premiers rflexes dun programmeur en PHP qui travaille sur un nouveau projet sera daller chercher en ligne ce qui a dj t fait dans son domaine, pour sen inspirer ou pour adapter une solution. Le projet PEAR (PHP Extension

39

Chapitre 1

Introduction

1. Introduction

and Add-on Repository, ou dpt dextension et dadd-on PHP pear signifie poire en anglais) reprsente bien lesprit open source et "opportuniste" de PHP. Largement inspir du systme CPAN (Comprehensive Perl Archive Network) pour le langage Perl, Pear est une base de donnes en ligne de programmes ou dextensions en PHP. Les dveloppeurs partagent ainsi leurs crations. PHP a su rcuprer lun des aspects les plus intressants du monde Perl. La communaut dispose, en plus, du soutien dentreprises qui participent au dveloppement de PHP, ou qui en sont de fervents supporters. La socit Zend propose de nombreuses solutions logicielles autour de PHP, en plus du Zend Engine, interprteur gnrique intgr PHP 4. On peut galement citer la socit franaise Nexen, spcialise dans les services Internet, qui, en plus de ses activits, soutient activement PHP (hbergement de miroirs, diffusion de documentation, etc.).

Quelques liens Pear (en anglais) :


http://pear.php.net/

CPAN (en anglais) :


http://www.cpan.org

Interview de Rasmus Lerdorf :


http://developpeur.journaldunet.com/itws/it_phpnexen_rasdorf.shtm

1.4.

PHP face ses concurrents (ASP, JSP, etc.)

PHP face aux autres langages de script web


"PHP nest pas un langage neuf ou rvolutionnaire. Il emprunte une grande partie de sa syntaxe des langages comme le C, Perl ou Java". Qui est lauteur de ce jugement dfinitif sur la prtendue rvolution ou sur le caractre novateur de PHP ? Bill Gates, Scott McNeally ou Larry Wall ? Aucun dentre eux ! Cest bien le pre de PHP lui-mme, Rasmus Lerdorf, dans une interview au journal en ligne Computerworld. Et ce nest pas tout. Quelle est la diffrence entre PHP et son grand rival propritaire, ASP, de Microsoft ? Il ny en a pas vraiment. "Au fond, ils font les mmes choses", nhsite pas ajouter Rasmus Lerdorf. Encore un peu, et lon va apprendre que M. Lerdorf code en VisualBasic et quil en est trs content... Non, la cure sarrte l. Mais Rasmus Lerdorf a raison. PHP nest pas une rvolution proprement parler et, sur le fond, PHP napporte rien de bien particulier par rapport ASP, Java ou Perl. Envoyer des mails, gnrer des pages la vole, tout cela, PHP le permet tout comme ASP, par exemple. Comparer PHP ses grands rivaux nest pas toujours chose aise, voire admissible. Ainsi, la comparaison avec Perl nest pas forcment fonde. Perl est un langage de script, alors que PHP est un langage de script fait pour lInternet. On ne compare alors quune portion de Perl la totalit de PHP. De mme, ASP sintgre de plus en plus dans la plateforme .Net de Microsoft, ce qui lui ouvre dautres horizons. PHP, lui, nest pas infod une plateforme. Idem pour Java. Java a t conu pour voluer dans une architecture dite "n-tiers", alors que PHP, lui, reste dans un environnement "2 tiers" (voir schma).

40

PHP face ses concurrents (ASP, JSP, etc.)

Se servir de Java pour dynamiser un site personnel, cela revient quelque chose prs se servir dun lance-flammes pour dsherber un parterre de rosiers ! Ceci tant dit, il est tout de mme possible de se pencher sur ces langages de script pour voir quels sont leurs avantages et leurs inconvnients sur les points quils ont en commun.

1. Introduction

Comparatif PHP/Perl
Perl est avant tout un langage de script systme, n pour remplacer sed et awk. Face lui : PHP, un langage de script n du Web pour le Web. Les points de comparaison, sils existent, ne doivent pas faire oublier que Perl na pas pour objectif premier la cration de sites web. De base, PHP inclut beaucoup plus de bibliothques que Perl. Pour Perl, il faut souvent aller chercher une librairie souhaite sur CPAN. En revanche, Perl, dispose, au final, de beaucoup plus de bibliothques que PHP. L, PHP fait les frais de son jeune ge face un langage dge dj vnrable. Sans parler des librairies, les solutions en Perl sont dj trs nombreuses. Toutefois, le dynamisme tout particulier de la communaut PHP est en passe de combler cette lacune. Langage orient web, PHP est plus facile maintenir et faire voluer que Perl. Retoucher ou adapter rapidement un site tout entier tourn vers Perl reste plus ardu que si le site dispose dune architecture en PHP. Perl a aussi su sadapter au Web. Alors quil crait un nouveau processus sur le serveur chaque nouvelle requte, Perl a, depuis, su normaliser ses rapports avec le serveur web. Le problme a en effet t rgl par lapparition de mod_perl ou FastCGI.

Comparatif PHP/ASP
ASP (Active Server Pages) est un langage de script dvelopp par Microsoft. PHP et ASP sont assez proches dans leur philosophie et dans leur mise en uvre. Dans les deux cas, le code du script est insr directement dans la page web. Jusqu PHP 3, ASP disposait dun trs net avantage sur PHP : PHP ne grait pas les sessions. Avec lintroduction de cette gestion en mode natif dans PHP 4, lavantage est perdu. Si PHP 3 doit imprativement tre utilis, pour des raisons de licence par exemple, il existe de toute faon des alternatives, comme PHPLib, qui permettent de grer les sessions malgr tout. Le gros inconvnient dASP par rapport PHP rside dans sa trs forte dpendance la plateforme Windows. ASP ne se dploie en effet que dans un environnement Microsoft. Il existe certes un portage sous UNIX, grce la solution mise en place par Sun avec Chilisoft ASP, mais cela reste en de de ce que peut offrir PHP. PHP na pas t dvelopp pour une plateforme en particulier, ce qui ouvre de bien plus vastes horizons en matire de portabilit des applications ainsi quen volutivit. PHP fonctionne sous Linux comme sous Windows NT, sans avoir recourir des programmes tiers. Un script en PHP pourra tre rutilis bien plus facilement quun script en ASP. Il a souvent t reproch PHP daccuser des temps de rponse assez longs. Ce point peut tre amlior grce des solutions logicielles de cache. Zend Accelerator ou PHP Accelerator rduisent ainsi nettement les temps de rponse de PHP. Autre grosse diffrence entre PHP et ASP : PHP sinterface en natif avec lensemble des systmes de gestion de bases de donnes standard du march, alors quASP doit passer par

41

Chapitre 1

Introduction

ODBC. Cette diffrence peut tre envisage de deux faons. Dun ct, une meilleure matrise de la base de donnes et peut-tre mme de meilleures performances jouent en faveur de PHP. Dun autre ct, les fonctions varient dune base de donnes lautre, ce qui ncessite dadapter le code pour chaque base de donnes, alors quen thorie, ASP ne demandera que quelques modifications. En fait, mme si rien nest propos en standard, il existe des solutions (prsentes dans ce livre) de couches dabstraction pour PHP, mais, surtout, limplmentation du langage SQL variant grandement dun serveur de bases de donnes lautre, ladaptation du code en fonction du serveur de bases de donnes est invitable (cest dailleurs pour cette raison que Rasmus Lerdorf nest pas favorable lintgration dune couche dabstraction dans PHP). Aujourdhui, ASP va trs largement vers .Net, la plateforme "n-tiers" de services web de Microsoft. Il se rapproche en cela de Java avec J2EE de Sun. De son ct, PHP deviendra de plus en plus un langage "srieux", incluant dclaration de variable, typage, etc. Face lASP, PHP peut galement jouer la carte du prix. Prenons le cas dune entreprise qui veut dvelopper une solution Microsoft. Windows 2000 Server lui cotera 934 euros, Internet Security and Acceleration Server, 8 000 euros, SQL Server 2000 Entreprise Edition, 2 300 euros, Microsoft Proxy Server, 900 euros et, enfin, la souscription au MSDN, 2 100 euros par dveloppeur. Ce qui fait un total de 14 234 euros. Face cela, une architecture similaire autour de PHP peut tre construite avec Linux, Apache et SSL, PostgreSQL et Squid, le tout pour zro euros (hormis le cot de bande-passante requis pour tlcharger les produits). Pour une jeune entreprise, une telle manne financire peut se rvler trs utile dans dautres domaines

1. Introduction

Comparatif PHP/JSP
Encore une fois, comparer PHP JSP est un exercice prilleux. Le principe de fonctionnement est un peu diffrent : PHP a t conu pour sintgrer au code HTML, tandis que JSP est une utilisation de Java permettant de faire grer des scripts intgrs au code HTML. En fait, une page JSP est systmatiquement convertie en servlet. Alors que lexcution dun script PHP est compose de lanalyse du document, de la compilation (en opcode) et de lexcution proprement dite, celle dun script JSP est compose de lanalyse du document, de la gnration de la servlet (qui consiste principalement convertir le code HTML en appels Java "affichant" ce mme code), de la compilation de la servlet et, enfin, de lexcution proprement dite. Il est possible dimaginer que cest la "lourdeur" de ce travail qui fait que les servlets sont systmatiquement mises en cache (ce qui cre parfois des surprises aux dveloppeurs dbutants), alors que lutilisation de caches nest quoptionnelle avec PHP (il est donc important de tenir compte de cette diffrence lors dun comparatif de performances). Alors quavec PHP, tout passe par lutilisation de scripts PHP, avec JSP, lutilisation des scripts (scriptlets) doit tre rduite au minimum. Ces scriptlets doivent autant que possible se contenter dappeler des mthodes de Beans. Cela prsente linconvnient de devoir systmatiquement travailler de front dans deux espaces diffrents : dun ct les pages web, de lautres les Beans. Chaque modification entranera une nouvelle compilation des Beans et, ventuellement, la gnration dune nouvelle archive dployer dans lespace du serveur. Avec PHP, une simple modification du script dans lespace du serveur suffit. En revanche, la compilation des Beans vous assure de ne pas rencontrer de stupides erreurs de syntaxe lors de lexcution du code (problme que lon rencontrera avec PHP). Mais ce nest toutefois pas a qui vous assurera davoir un code qui fonctionne (mme sil est vrai que cela y contribue grandement). En fait, JSP se conoit comme un lment parmi dautres dans une architecture J2EE. Pour des sites de grande envergure, lavantage est indiscutable : on peut plus facilement partager les tches et les comptences dune quipe sur llaboration dun code en Java. De

42

PHP face ses concurrents (ASP, JSP, etc.)

mme, larchitecture "n-tiers" de Java (permettant lappel dobjets mis disposition sur un serveur distant) offre un ventail de solutions plus large (et avec des solutions plus robustes) pour des sites forte audience et trafic dense. Mais pour aboutir ce rsultat, nombreuses sont les normes ou rgles de conceptions respecter ce qui ne facilite pas lapprentissage du langage. Il est noter toutefois que bon nombre de ces rgles peuvent trs bien tre appliques PHP (comme par exemple le modle MVC). Dans ce cas, il est juste de la responsabilit de lquipe de dveloppeurs de simposer ou nous ces choix de conception.

1. Introduction

Figure 1.3 : Architecture en "n-tiers" de Java face PHP

Via J2EE, Java rend lclatement dune plateforme applicative beaucoup plus facile et simple que dans le cas de PHP. Pour PHP, le script doit thoriquement tre excut sur la machine qui reoit la requte (traitement du script sur la machine qui hberge le serveur web). Aussi est-il plus ardu de mettre en place une structure clate, plus modulaire, et tenant de lourdes charges. Linterfaage avec les bases de donnes seffectue grce aux pilotes JDBC, ce qui permet de communiquer avec tout type de serveur de bases de donnes avec un langage commun, mais, comme nous lavons dit prcdemment, ce nest pas le cas par dfaut pour PHP (mme si des solutions existent). Toutefois, comme cela a galement t dit, le langage SQL varie sensiblement dun serveur de bases de donnes lautre, rendant ncessaire lutilisation de code ddi (ce qui rduit grandement lintrt dune telle interface). Pour une application spcifique, le choix de Java peut se rvler judicieux. Par exemple, on ne peut pas parler de vritable pool de connexion en PHP, alors que, pour Java, il est prsent dans le container de EJB-J2EE. Dans le mme esprit, il est possible de partager des Beans en commun avec tous les scripts excuts (ce que ne propose pas PHP). Il est noter que Java a t conu comme tant orient objet (comme Smalltalk ou ObjectiveC). PHP, lui, na pas t cr pour la programmation objet, mais il est tout de mme possible de programmer de la sorte, mme si toutes les proprits auxquelles nous pourrions nous attendre ne sont pas disponibles. Aujourdhui les choses sont en train de changer, et le moteur Zend 2 va plus loin dans le sens de la programmation objet. Heureusement, comme pour PHP, il existe des solutions open-source plus ou moins compltes comme par exemple Tomcat et JBoss.

43

Chapitre 1

Introduction

Perspectives
1. Introduction
PHP a pour lui une trs grande facilit dinstallation. Il est propos de base sur quasiment toutes les distributions Linux. De trs nombreux kits dinstallation existent, qui permettent de faire rapidement ses premiers pas. Ces kits offrent galement une solution de mise jour pratique et facile mettre en uvre. PHP fait partie de la fondation Apache, ce qui garantit un interfaage entre le langage de script et le serveur web, sinon parfait, du moins tenu jour. Comme nous lavons dj dit plusieurs reprises, PHP dispose dune trs large et dynamique communaut de dveloppeurs, et les tutoriels en PHP sont trs nombreux. Entirement traduite en franais, la documentation officielle est disponible gratuitement sous de nombreux formats. PHP a galement su sinspirer des points positifs de ses concurrents. Le CPAN de Perl avait ainsi donn naissance son quivalent PEAR (base de ressources centralises pour PHP). Il est trs largement reconnu que PHP est dune prise en main facile. Sa syntaxe simple permet dapprocher beaucoup plus vite de la solution. Pour une entreprise, PHP peut galement tre intressant par son faible cot de dploiement. Par rapport ASP, par exemple, qui sous-entend une plateforme Microsoft avec de nombreuses licences acheter, PHP aligne des quivalences libres, et bien souvent gratuites, tout aussi fonctionnelles. Petit point ngatif pour PHP, les comparatifs sont bien peu de choses face une culture dentreprise. Mme si PHP offre, dans certains cas, une solution tout fait satisfaisante et bien meilleur march, il sera souvent plus simple de lui prfrer une solution ASP ou JSP pour des raisons historiques propres lentreprise. Cest l que PHP peut avoir un caractre rvolutionnaire. Ladopter, cest faire confiance une technologie atypique par son histoire et sa porte. Cest l que le plus gros travail reste faire pour les dveloppeurs. Si, sur le papier, les dcideurs informatiques acceptent bien volontiers les avantages de PHP, basculer une plateforme vers PHP reste une dcision importante. La tendance semble pourtant sinverser du fait du passage de certains grands comptes vers PHP (liberation.fr par exemple) : on fait de plus en plus fait confiance au PHP. Cette confiance associe une recherche dconomie dans le monde de lInternet font que cest tout naturellement que PHP dpasse ASP en terme dquipement de sites web (avril 2002, sur les sites tudis par Netcraft).

Documentation officielPHP
http://www.php.net/docs.php

En bref
Pour des langages de script, il est possible de discerner quelques grands facteurs prendre en compte lors du choix de lun dentre eux : la facilit dapprentissage (accessibilit), la puissance au regard de la complexit, la portabilit et lenvironnement disponible (ressources en ligne, outils, etc.). Pour ASP, PHP, Java, Perl et PHP, la situation peut se rsumer comme suit :

44

Pourquoi ont-ils choisi PHP ?

Tableau 1.1 : Tableau comparatif des langages de script


PERL Accessibilit Puissance Portabilit Environnement + ++ ++ ++ ASP ++ ++ ++ JSP +++ +++ +++ PHP

1. Introduction

+++ ++ +++ +++

Au regard des critres que nous avons dfinis, PHP semble bien avoir le plus davantages. Il nimporte pas de savoir si, dans labsolu, PHP est plus puissant que Java, par exemple. Mais, en revanche, il sagit de savoir si, dans le cas de lutilisation dun langage de script pour rendre un site web dynamique, linvestissement en temps requis pour matriser Java est justifiable au regard de la facilit dusage de PHP. Le Jargon franais dfinit les objectifs dun langage de script comme suit : "Faire simple, rapide, utilitaire". Dans cette optique, PHP est clairement le plus adapt.

Le Jargon
http://www.linux-france.org/prj/jargonf

1.5.

Pourquoi ont-ils choisi PHP ?

Ils ont choisi PHP


De nombreuses applications ont dj t crites en PHP et les sites webs ("perso" comme professionnels) qui passent au PHP ne se comptent plus. Pourquoi un webmestre fait-il le choix de PHP ? Entre ambition de dveloppement et prfrence politique, les atouts de PHP sont varis. De plus, les performances alignes par PHP dans ses multiples applications grand public peuvent galement sduire. Nous avons recueilli les tmoignages de deux dveloppeurs qui ont fait le choix de PHP, pour les prsenter plus en dtail avant de passer une prsentation gnrale avec laide de lObservatoire franais de PHP.

Gros plan : Tuxfamily et DaCode


Tuxfamily, hbergeur indpendant
Lanc par Julien Ducros, Tuxfamily est un hbergeur de projets libres qui utilise PHP au sein de sa plateforme. Age de trois ans, la structure de Tuxfamily est dsormais solide : un systme LVS (Linux Virtual Server) orchestr par deux Load Balancer (N.D.A : rpartiteur de charge). Toute la plateforme est rplique et les donnes utilisateurs sont contenues sur un filer central de 360 Go en raid 5. Les responsables de Tuxfamily connaissent PHP depuis bien longtemps, lpoque mme o lon parlait encore de PHP/FI.

45

Chapitre 1

Introduction

1. Introduction

Pourquoi ont-ils choisi PHP ? Principalement pour sa rapidit de mise en uvre. Mais ce nest pas tout : "Le langage PHP a aussi t pour nous un choix politique", explique Pierre Machard. Il poursuit : "PHP est un logiciel libre de grande qualit. Sa flexibilit et sa polyvalence ont motiv ce choix. Par exemple, nous pouvons actuellement lutiliser indiffremment avec une base de donnes MySQL ou Postgres". Pour lui, mme sil noffre pas la puissance des CGI, PHP est beaucoup plus simple mettre en uvre et exploiter. Selon Pierre Machard, la syntaxe de PHP, proche du C, participe aussi de son succs. Enfin, il est, daprs lui, idal pour pauler Apache. PHP nest pas pour autant au-dessus de tout soupon. Comme toute technologie dite "dynamique", PHP expose les sites des attaques par cross site scripting (exploitation dune faille de scurit sur un serveur web en entrant des commandes directement dans ladresse dune page). Pour Tuxfamily, il est ncessaire de sassurer davoir la dernire version stable installe. Les alertes de scurit publies sont plutt le signe dune bonne sant de PHP. En tout cas, "une rustine est rapidement disponible sur lInternet", nous explique Pierre Machard, "ce qui nest pas le cas dASP, logiciel propritaire". Pour un site fort trafic comme Tuxfamily, PHP dispose dun moteur bien conu qui "naccapare pas outrance les ressources des machines, mme sil possde quelques carences", concde Pierre Machard. Seul petit bmol adress PHP par lquipe de Tuxfamily : la licence de la dernire version. Les version 3.x taient libres, alors que la licence applique partir de PHP 4.x est plus restrictive (voir notre partie sur les licences).

daCode, moteur de nouvelles


Crateur et webmestre du site dinformations sur Linux et les logiciels libres http://linuxfr.org, Fabien Penso a bien voulu nous expliquer pourquoi il avait choisi PHP pour dvelopper daCode, le moteur de son site. Il a rencontr PHP par hasard. Cherchant un langage de script simple pour faire des sites web, il a tout naturellement test PHP. Voulant rendre daCode utilisable par nimporte qui, il a choisi PHP pour dvelopper son logiciel, car cest le langage disponible sur les plateformes grand public comme Free ou Multimania. Cela allait dans le sens de sa dmarche. Lide tant galement davoir le plus de contributions possibles pour daCode, limportante communaut de dveloppeurs PHP a jou en faveur du langage libre. Il fut un temps question de Perl/ mod_perl mais cette solution posait trop de problmes de fuite de mmoire.

Leurs sites Tuxfamily, hbergement libre pour gens libres :


http://www.tuxfamily.org

Contact : Pierre Machard <pmachard@tuxfamily.org> Linuxfr, site dinformation sur Linux et les logiciels libres :
http://linuxfr.org

daCode, gestionnaire de contenus open source (GPL) :


http://www.dacode.org

Contact : Fabien Penso <penso@linuxfr.org>

46

Pourquoi ont-ils choisi PHP ?

PHP lassaut du Net


On ne dnombre plus les grands comptes qui se tournent vers PHP. Que ce soit par la petite porte, souffl un directeur informatique par un dveloppeur, ou dans un plus large panel doffres faites par une webagency, PHP nest plus un langage neuf ou exotique. Les dcideurs en informatique lui font de plus en plus confiance. Le second trimestre 2002 a vu natre deux structures parallles visant recenser toutes les utilisations professionnelles ou industrielles de PHP. LAssociation franaise des utilisateurs de PHP (AFUP), ne en avril 2002, et lObservatoire franais de PHP (OFPHP), n en juin 2002, prsentent des interviews, des tudes et des listes de sites utilisant PHP. Le surf sur ces sites montre quel point PHP a pntr les hautes sphres du web. Sur le site de lAFUP, on apprend que le quart des entreprises du CAC 40 utilisent PHP pour leur site web. Parmi elles, Cap Gemini, PSA Peugeot Citron, Schneider Electric SA, etc. On le voit, pour les grands comptes, le langage de script libre fait trs largement jeu gal avec ASP, JAVA ou ColdFusion. Du ct de lOFPHP, la liste des sites utilisant PHP de par le monde, prsente dans la section Rfrences, est impressionnante : http://sourceforge.net (30 millions de pages visionnes par mois), http://www.phpbuilder.com (9 millions de pages par mois) ou encore http://www.insight.com (plus de 2 milliards $US. de chiffre daffaire en 2000). Pour la France, citons simplement http://www .boursorama.com (14 378 807 visites en juillet 2001 avec une pointe 9 783 039 pages vues pour la seule journe du 17 septembre 2001, jour de la rouverture des marchs Wall Street). LOFPHP prsente galement des interviews dacteurs de linternet qui ont choisi de faire confiance au PHP.

1. Introduction

Lutilisation de PHP dans les entreprises AFUP : le quart des entreprises du CAC 40 utilisent PHP
http://www.afup.org/article.php3?id_article=105

OFPHP :
http://www.ofphp.com/index.php?page=references

ZDNet : les logiciels libres tiennent la charge


http://techupdate.zdnet.fr/story/0,,t381-s2111391,00.html

47

Chapitre 2

Prise en main
2.1 2.2 2.3 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Le chier de conguration php.ini . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 Les diteurs et dbogueurs PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

Installation

our crer un site en PHP, il ny a pas besoin de beaucoup de choses. Un diteur de texte et un serveur web suffisent.

Si vous utilisez les services dun hbergeur Internet, vous pouvez ventuellement vous contenter de dposer vos scripts dans lespace qui vous est rserv et voir le rsultat obtenu. Mais il est bien plus pratique dinstaller son propre serveur web sur sa machine, afin de tester ses scripts avant daller les dposer chez un hbergeur. Autrement dit, quels que soient les cas, vous serez amen installer un serveur web supportant PHP. Dailleurs, vu la simplicit de lopration, pourquoi sen priver ? Si vous tes votre propre hbergeur, le chapitre Configuration vous permettra de personnaliser les options autorises. Dans le cas contraire, il est conseill de consulter ce chapitre qui vous permettra (via un appel phpinfo()) de mieux connatre ce que permet votre hbergeur et ce quil interdit. Enfin, ce chapitre vous prsente quelques diteurs particulirement adapts PHP.

2. Prise en main

2.1.

Installation

PHP est disponible pour diffrents serveurs et systmes dexploitation. Dans ce chapitre, nous nous efforcerons de dcrire au mieux linstallation de PHP sur les serveurs Apache, IIS, iPlanet, etc.

Avec Apache
PHP pour Apache est notamment disponible sous les environnements Linux/UNIX, Windows et Mac OS X.

Apache 2 Apache 2 est considr par ses dveloppeurs comme la version officielle du serveur web. Malheureusement, Apache2 nest pas encore officiellement support par les dveloppeurs de PHP. Dans certains cas, la version 5 de PHP peut fonctionner avec Apache 2. Dans tous les cas, consultez la documentation officielle pour connatre lvolution de la compatibilit : www.php.net/manual/fr/install.apache2.php. Nous prsenterons donc essentiellement linstallation avec la premire version dapache tout en indiquant les diffrences mineures pour une installation avec Apache2.

Sous Linux/Unix
Nous pouvons considrer quil existe trois grandes mthodes dinstallation de PHP dans un environnement Linux/UNIX. Cela peut ainsi se faire :
j j j

En utilisant les scripts dinstallation fournis avec les distributions (Linux notamment) ; En utilisant des kits dinstallation disponibles sur Internet ; En faisant une installation "manuelle".

51

Chapitre 2

Prise en main

Utiliser les scripts dinstallation de votre distribution est le moyen le plus sr et le plus rapide pour dbuter avec PHP, mais passer par une installation "manuelle" vous permet de personnaliser au mieux votre serveur.

Installation via la distribution Linux (ou UNIX)


2. Prise en main
Lors de linstallation du systme dexploitation, de nombreuses distributions offrent leurs utilisateurs la possibilit dinstaller un serveur Apache avec PHP et, bien souvent, MySQL, voire galement dautres bibliothques. Il suffit alors gnralement de cocher une case ou deux. Certaines distributions proposent mme des versions dites "optimises". Nous ne pouvons malheureusement pas toutes les dtailler ici. Vous tes donc convi consulter la documentation fournie avec votre systme dexploitation. Il est galement possible dinstaller cet ensemble Apache/PHP (et ventuellement MySQL) a posteriori, grce aux systmes des "packages" (parfois appels paquetages) portant gnralement lextension .rpm.

Installation via un kit


Si votre distribution ne propose pas de quoi installer simplement PHP dans votre environnement, ou bien si elle ne propose pas de version rcente des serveurs Apache et de PHP, vous pouvez utiliser un kit dinstallation. Il existe, par exemple, Apache Toolbox, que vous trouverez ladresse http://www.apachetoolbox .com (mais malheureusement en anglais). ApacheToolbox est un projet qui permet en effet dinstaller et de mettre jour trs facilement Apache, PHP (version 3 ou 4, au choix), MySQL, ZendOptimizer, OpenLDAP, ainsi que prs de cinquante modules pour Apache. Bien que les auteurs ne laient jamais essay, sachez quil existe LinuxEasyInstaller, disponible ladresse http://www.phpmylinux.net/index.php3?rub=lei, qui installe Apache/PHP, MySQL et phpMyAdmin (scripts permettant ladministration des bases de donnes via un navigateur).

Installation manuelle
Linstallation manuelle est certainement la meilleure faon davoir exactement ce que lon veut : Apache et PHP avec la base de donnes de son choix (PostgreSQL ou Oracle, par exemple) et pas ncessairement MySQL, ainsi quavec les bibliothques que lon souhaite (au choix parmi celles prsentes tout au long de ce livre) et pas seulement avec celles supportes par les kits dinstallation (que ce soient ou non ceux des distributions). Cest galement le plus sr moyen davoir la toute dernire version (chacun des lments tant librement tlchargeable sur Internet). Bref, mme si ce nest pas la faon la plus simple dinstaller PHP, elle reste celle que nous prconisons. Les autres mthodes prsentes prcdemment sont toutefois fort pratiques pour dbuter en PHP.

Pr-requis
Il va de soi que, pour installer Apache manuellement, vous devez avoir une connaissance des bases de Linux (la notion de droit utilisateur) et des commandes lmentaires que sont cp, cd ou ls par exemple. Nous ne reviendrons pas sur lutilisation du systme Linux, et encore moins sur son installation. En revanche, vous trouverez dexcellentes documentations sur Internet ou

52

Installation

dans des livres. Ce message davertissement na pas pour objectif de vous dcourager ou de vous effrayer devant cet excellent systme dexploitation quest Linux. Nous vous invitons simplement prendre connaissance des bases avant de vous lancer plus avant dans linstallation dApache et de PHP.

Installation
La notice dinstallation suivante fonctionne avec la plupart des distributions Linux (RedHat, Mandrake, SuSE, etc.). Il peut nanmoins y avoir des diffrences darborescence, les diffrentes distributions nayant pas toujours la mme logique. Pour cela, reportez-vous au manuel de rfrence de votre systme dexploitation, qui doit vous fournir une description dtaille de sa structure. Il vous suffit alors de modifier les chemins donns dans les lignes de commande. Les grandes procdures, elles, restent inchanges. Linstallation se ralise en deux temps : 1. 2. Dans un premier temps, vous devez installer les bibliothques que vous souhaitez utiliser. Vous devez compiler PHP en tenant compte des bibliothques prcdemment installes, puis compiler Apache en intgrant PHP.

2. Prise en main

Suite de linstallation Une fois connect et authentifi sur un systme Linux, et pour que la suite de linstallation se droule correctement, vous devez passer en mode super utilisateur (root). Pour cela, dans un shell, tapez simplement la commande "su " suivie du mot de passe root quand le systme vous le demande.
Installation des bibliothques Si vous ne savez pas encore quelles bibliothques vous allez utiliser, vous pouvez vous contenter dune installation de base (sans bibliothque particulire). Les procdures dinstallation des bibliothques sont dcrites dans le chapitre traitant de la bibliothque, mais, gnralement, le principe est le suivant : il suffit de tlcharger la dernire version de la bibliothque sur Internet (ou dutiliser celle disponible sur le CD-ROM), de copier larchive (par exemple sous /usr/local/src), et de taper les commandes suivantes :
# # # # # tar zxvf librairie-version.tar.gz cd librairie-version ./configure make make install

Si vous rencontrez un problme, pensez consulter le fichier INSTALL (bien souvent en anglais) qui doit tre fourni avec larchive dinstallation. Vous y trouverez la documentation complte pour linstallation de la librairie, qui ncessite peut-tre des paramtres spciaux. Soyez galement attentif au message derreur qui pourrait tre donn par le compilateur. Il constitue gnralement un excellent moyen de savoir o se situe le problme (dpendances, version de compilateur trop ancienne, etc). Le fichier README (galement en anglais, moins

53

Chapitre 2

Prise en main

que vous trouviez un LISEZMOI) peut galement contenir des informations utiles comme, par exemple, des incompatibilits temporaires. Compilation de PHP et Apache Vous devez, dans un premier temps, tlcharger les dernires versions dApache et de PHP (ou utiliser celles fournies sur le CD-ROM).

2. Prise en main

Les sites officiels Apache :


http://www.apache.org

PHP :
http://www.php.net

Autant que possible, tlchargez les sources au format .tar.gz qui seront utilises dans la suite de notre explication. Cela vous permettra davoir des binaires optimiss pour votre systme. Allez dans le dossier contenant les archives que vous avez tlcharges. Vous pouvez dores et dj passer en mode administrateur (root), puisque cela est gnralement ncessaire pour lopration dinstallation. Dcompressez alors les deux archives (nous supposerons ici que les archives sont dcompresses dans le mme rpertoire).
# tar zxvf apache_1.3.31.tar.gz

Dans le cas dapache 2, la commande devient tar zxvf httpd2.0.50.tar.gz.


# tar zxvf php-5.0.1.tar.gz

Pour compiler PHP en tant que module APXS, vous devrez dabord compiler Apache en vous assurant quil autorise le chargement des modules dynamiques.
# # # # cd httpd_X ./configure --prefix=/usr/local/apache --enable-module=so make make install

Apache est dsormais install sous /usr/local/apache. Reste compiler le module APXS PHP.
# cd .. # cd php-5.0.1 # rm config.cache

La suppression du fichier config.cache est inutile lors de la premire compilation (ce fichier nexistant pas), mais, par la suite, elle est quasiment indispensable si vous souhaitez tre sr de recompiler PHP avec les nouvelles options prcises. Vous pouvez alors passer la configuration (prparation la compilation de PHP).
# ./configure --with-apxs=/usr/local/apache/bin/apxs <autres options>

54

Installation

Dans le cas dapache 2, la commande devient ./configure withapxs2=/usr/local/


apache/bin/apxs <autres options>

Il existe de nombreuses options de configuration consultables en tapant ./configure help. Pour chaque bibliothque prsente dans ce livre, loption de configuration est indique (vous devrez sans doute en cumuler plusieurs). Ainsi, par exemple, la compilation de PHP avec mysql et gd donnera :
# ./configure --with-apxs=/usr/local/apache/bin/apxs --with-mysql=/usr/local/ mysql --with-gd=/usr/local --with-jpeg-dir=/usr/local --with-png-dir=/usr/ local --with-zlib-dir=/usr/local

2. Prise en main

Il est noter quil nest pas obligatoire de prciser les chemins des bibliothques, PHP sassurant de retrouver la bibliothque concerne Mais il est toutefois conseill de le faire afin de sassurer quil ny ait pas de malentendu (en particulier sur la version installer). Vous pouvez ensuite passer la compilation :
# make

Compilation sous Solaris Sous Solaris, vous devrez vous assurer de compiler PHP avec les outils GNU. En dautres termes, vous devrez installer le "package" binutils (disponible sur le site http://www.sunfreeware.com) et vrifier que le make GNU est bien le premier trouv dans le PATH.

# make install

a y est, PHP est compil et install (un fichier libphp5.so a t ajout dans le rpertoire libexec dApache). Reste configurer PHP et Apache. Outre ce qui est dcrit dans le paragraphe suivant, vous devrez consulter le fichier /usr/local/apache/conf/httpd.conf et vrifier quil contient bien la ligne suivante (de prfrence juste aprs les lignes correspondant la mme directive). Au besoin, ajoutez la :
LoadModule php5_module libexec/libphp5.so

Compilation de PHP intgr Apache Il est galement possible de compiler PHP au sein dApache (sans utiliser de module). Pour cela, la procdure devient :
# # # # # # # # # cd apache_1.3.31 ./configure cd .. cd php-5.0.1 rm config.cache ./configure --with-apache=../apache_1.3.31 <autres options> make make install cd ../apache_1.3.31

55

Chapitre 2

Prise en main

# ./configure --prefix=/usr/local/apache --activate-module=src/modules/php5/libphp5.a # make # make install

Dans ce cas, vous ne devrez pas ajouter ou devrez commenter la ligne : 2. Prise en main
LoadModule php5_module libexec/libphp5.so

Reste copier le fichier de configuration par dfaut de PHP dans le rpertoire o il doit se trouver :
# cd ../php-5.0.1 # cp php.ini-dist /usr/local/lib/php.ini

Les principales options de php.ini seront dcrites dans le prochain chapitre.

Ensuite, ditez le fichier /usr/local/apache/conf/httpd.conf laide de Vi ou Emacs (selon votre appartenance), et ajoutez la ligne suivante afin que les fichiers portant les extensions indiques soient interprts par PHP :
AddType application/x-httpd-php .php .php5 .php4 .phtml AddType application/x-httpd-php-source .phps

Pour voir la vie en rose (ou bleu, ou jaune, ou rouge...) Si vous donnez une extension .phps vos scripts, alors ceux-ci ne seront pas interprts, mais le code source sera affich et coloris, ce qui peut parfois permettre de voir comment PHP lanalyse (et ainsi dtecter des parse error).
Il est aussi prfrable de modifier linstruction suivante :
DirectoryIndex index.html

en :
DirectoryIndex index.html index.php index.php5 index.php4

Cette instruction permet de forcer la page index que le navigateur doit afficher si lURL demande est incomplte. Avec la ligne prcdente, le serveur ira chercher dans le rpertoire prcis le fichier index.html et, sil ne le trouve pas, index.php, etc. Ainsi, appeler la page http://localhost/ renvoie la page se trouvant lURL http://localhost/index.html, si celle-ci existe. Pensez galement, si ce nest dj fait, dcommenter ou ajouter une ligne
ServerName <nom de votre machine>

Vous pouvez par exemple indiquer :


SeverName localhost

56

Installation

prsent, lancez le serveur Apache :


/usr/local/apache/bin/httpd start

Pour larrter, vous naurez qu taper la commande :


/usr/local/apache/bin/httpd stop

Si vous n Vous pouvez maintenant crer votre premire page web. ditez la page /usr/local/apache/ htdocs/index.php et insrez-y ces quelques lignes :
<?php phpinfo(); ?>

2. Prise en main

Vous navez plus qu appeler la page depuis votre navigateur en entrant ladresse http://localhost/index.php.
Figure 2.1 :

Voil votre page interprte en PHP

Sous Windows
Tout comme pour Linux, linstallation sous Windows pourra se faire de deux faons diffrentes : en cliquant ou en compilant. Il existe dsormais de nombreuses solutions "tout en un" qui vous permettent dinstaller Apache et PHP sur un systme Windows sans avoir faire de fastidieuses manipulations. De plus, ce type dinstallation ne ncessite quun minimum de temps et de connaissances techniques. Si ces programmes ont pour eux la simplicit et la rapidit, ils ont aussi les dfauts vidents de leurs avantages : installation non transparente et pas toujours personnalisable souhait. Il faut parfois galement aller ajouter "manuellement" des bibliothques.

57

Chapitre 2

Prise en main

Installer PHP5 pour Apache 2 Si vous souhaitez installer PHP5 et Apache2, vous devrez tlcharger larchive zippe de PHP5. Linstalleur automatique ne vous fournira pas tous les fichiers requis pour que PHP5 fonctionne avec Apache2. 2. Prise en main

Installation automatique
EasyPHP
EasyPHP est un programme bien pratique, qui permet dinstaller Apache, PHP, MySQL et PhpMyAdmin en quelques clics de souris. Il y a environ une nouvelle mouture chaque anne. Pour dbuter linstallation, lancez lexcutable EasyPHP1-7_setup.exe prsent sur le CD-ROM. Cela installera Apache 1.3.27, PHP 4.3.3, MySQL 4.0.15 et Phpmyadmin 2.5.3. Vous pouvez galement vous rendre sur le site dEasyPHP pour vrifier si une version plus rcente est disponible (www.easyphp.org). Si cest le cas, il est vivement conseill dutiliser le produit le plus rcent.
Figure 2.2 :

Dbut de linstallation dEasyPHP

Quoi quil en soit, linstallation nest en rien hors du commun, et se droule sans difficult particulire. Une fois lopration mene terme, le programme dinstallation vous propose de vous rendre sur la page daccueil dEasyPHP.
Figure 2.3 : Fin de linstallation dEasyPHP

58

Installation

Ne changez rien, puis cliquez sur Terminer (enfin... Finish si comme dans votre environnement vous avez un texte mi-anglais mi-franais) Et voil, cest fini. Un navigateur souvre alors pour vous prsenter la page daccueil dEasyPHP. Si le logiciel ne se lance pas automatiquement, dans le menu Dmarrer, cliquez sur Tous les programmes, puis sur EasyPHP 1.7 et, enfin, sur EasyPHP. Le programme va alors dmarrer.

2. Prise en main

Figure 2.4 : Page daccueil dEasyPHP

La page daccueil dEasyPHP prsente plusieurs choses fort utiles : une introduction EasyPHP en local et des liens vers le support en ligne. Vous pouvez galement accder cette page en cliquant droit sur le "E" qui a t ajout la barre des tches (dj certainement bien assez charge votre got).

Figure 2.5 : lment de la barre des tches

Ce E vous permettra daccder aux principales fonctions relatives ladministration dun serveur web. Dans le menu contextuel qui souvre alors, il suffit de choisir Web local, mais, pour le moment, cliquez plutt sur Administration. Cette option vous permet daccder une configuration centralise de certains des programmes que vous venez dinstaller.

59

Chapitre 2

Prise en main

2. Prise en main

Figure 2.6 : La page dadministration dEasyPHP

Il vous est alors possible (par exemple) de vrifier puis de changer le mot de passe daccs MySQL depuis le compte "root". Dans la section Environnement EasyPHP, cliquez sur le bouton Paramtres. La page se rafrachit pour vous donner les informations relatives aux paramtres de connexion par dfaut attribus votre serveur MySQL. Vous devez lire quelque chose comme ceci :
Paramtres par dfaut de la base de donnes : serveur : "localhost" username : "root" mot de passe : ""

Pour le serveur "localhost", lutilisateur "root" (celui qui a tous les droits) na pas de mot de passe ; il peut se connecter sans mme avoir sidentifier. Il peut donc tre important de corriger cela (si plusieurs personnes ont accs votre machine). Toujours sur la mme page, cliquez sur PhpMyAdmin dans la section Administrez vos bases de donnes. Vous devez voir safficher la page daccueil de PhpMyAdmin dans un nouveau navigateur. Pour plus dinformations, vous pouvez vous reporter la partie des annexes traitant de PhpMyAdmin.

60

Installation

2. Prise en main

Figure 2.7 : PhpMyAdmin

Dans la partie gauche de la page, vous devez trouver, sous la mention Accueil, un menu droulant des diffrentes bases de donnes prsentes sur le systme. La partie qui nous intresse se trouve sur la partie droite de la page. On peut voir deux colonnes : une premire qui propose des liens en rapport avec MySQL, et une seconde qui concerne PhpMyAdmin. Dans la colonne MySQL, cliquez sur le lien Utilisateurs et privilges. La nouvelle page qui saffiche prsente alors un tableau rcapitulatif des utilisateurs ayant un accs au serveur, un rsum de leurs privilges, ainsi que diverses options concernant les utilisateurs. Sur la ligne de lutilisateur "root", cliquez sur le lien Modifier. La page se recharge. Certains des champs ont t pr-remplis. Vrifiez que le champ "Utilisateur" contienne bien "root", puis donnez par deux fois le mot de passe que vous souhaitez voir utilis pour cet utilisateur. Cliquez enfin sur Excuter. Voil. Noubliez pas de noter le mot de passe de lutilisateur "root". Noubliez pas de lancer EasyPHP lorsque vous voulez utiliser Apache ou MySQL. Autre intrt dEasyPHP : il peut servir de base de dpart. Rien ne vous empche, sans avoir tout rinstaller, de mettre jour certains des programmes mis disposition par EasyPHP. Cela se fera, certes, au prix de quelques manipulations. PHP lui-mme pourra, par exemple, tre mis jour facilement grce PHPInstaller.

WAMP5 : pour installer PHP5, MySQL4 et Apache2 WAMP5 est un systme similaire EasyPHP qui permet dinstaller PHP5 et MySQL 4.0.18 automatiquement. Apache2, lui, est disponible sous forme dadd-on. Vous pouvez trouver WAMP5 cette adresse : www.wampserver.com. Attention toutefois : si vous avez dj install Apache2 ou PHP5, il faudra les dsinstaller sans quoi il risque dy avoir un conflit avec les versions installes par WAMP5.

PHPInstaller : mettre PHP jour facilement


PHPInstaller est un programme du groupe PHP (http://www.php.net), qui vous permet dinstaller PHP sur votre systme. Il est pratique plus dun titre. Si vous disposez dj dun serveur web sur votre machine, il lui est possible de configurer lui-mme ce serveur. Malheureusement, le programme de configuration automatique nexiste pas encore pour tous les serveurs web, et il faudra donc mettre la main la pte dans certains cas (Apache, tout particulirement). PHPInstaller est donc plutt a rserver pour une premire installation avec un serveur IIS ou dans

61

Chapitre 2

Prise en main

les autres cas, pour une mise jour. Ceci constitue un moyen simple et rapide de suivre au plus prs lvolution de PHP. Pour commencer, lancez lexcutable php-5.0.1-installer.exe prsent sur le CD-ROM.
Figure 2.8 : Page daccueil de PHPInstaller

2. Prise en main

Une fois passe la page daccueil et celle concernant la licence, PHPInstaller va vous proposer deux types dinstallation.
Figure 2.9 :

Choix du type dinstallation

Nous allons dcrire linstallation avance, linstallation standard ntant pas assez complte pour garantir un minimum de personnalisation. Une fois le processus dmarr, rpondez aux questions que vous pose lAssistant. Choisissez un rpertoire dinstallation, puis acceptez la sauvegarde des fichiers dj prsents sur le systme, comme vous le propose PHPInstaller.

62

Installation

Figure 2.10 : Rpertoire dinstallation

2. Prise en main

Les options qui arrivent maintenant sont propres au PHP. Vous devez donner un rpertoire temporaire qui servira pour les fichiers en attente de publication ("files upload") ainsi quun rpertoire de stockage pour les fichiers de sessions. Ensuite, lorsque la fonction mail() sera utilise, vous devrez spcifier ladresse qui sera utilise pour le champ "de" ("from").
Figure 2.11 : Configuration du mail

Vous pouvez ensuite choisir le niveau de rapport derreur. Votre choix sera guid par lutilisation que vous comptez faire du serveur sur lequel vous tes en train dinstaller PHP. Sil a pour vocation de devenir un serveur de test, vous choisirez laffichage maximal, cela afin de cerner au mieux les erreurs et dysfonctionnements. En revanche, si vous installez PHP sur une machine qui hbergera un site professionnel destin au grand public, choisissez le plus bas niveau daffichage. Les visiteurs ne sont pas concerns par ces questions de programmation, et il nest pas ncessaire de faciliter la tche dventuels pirates qui sauraient alors directement o aller fouiller... Ensuite, choisissez le serveur HTTP sur lequel vous tes en train dinstaller PHP : Microsoft PWS, IIS 3 ou 4, Apache ou Xitami.

63

Chapitre 2

Prise en main

Figure 2.12 :

Slection du serveur Web

2. Prise en main

Si le serveur que vous utilisez ne se situe pas dans cette liste, vous devrez alors passer par la case "configuration la main post-installation" (vous pouvez dailleurs utiliser les diffrentes mthodes prsentes dans ce livre). Enfin, choisissez les extensions qui devront tre interprtes comme tant de PHP. Cette dernire tape passe, PHPInstaller passe linstallation des composants de PHP sur votre machine. Si vous disposiez dj de PHP sur votre machine, le programme vous demandera si vous souhaitez ou non conserver votre ancien php.ini. Cela peut savrer trs intressant si vous aviez personnalis votre fichier php.ini.
Figure 2.13 : Voil, cest fini !

Et voil, cest fait.

Mise jour de PHP pour une installation dEasyPHP Dans le cas dune mise niveau de PHP pour un systme sur lequel avait t install EasyPHP, il faudra jongler un peu avec le fichier php.ini. EasyPHP installe PHP dans un rpertoire qui lui est propre. Si vous dsirez conserver la configuration dEasyPHP, ce qui est recommand, vous devrez diter le fichier php.ini situ la racine de votre dossier Windows pour lui donner les bons chemins pointant vers les diffrents composants de PHP (php.exe, dossier des extensions, etc.).

Installation personnalise
Vous pouvez choisir dinstaller les diffrents lments de la configuration un par un, grce des solutions plus ou moins automatises. Voici comment procder.

64

Installation

Installer Apache
Il existe des programmes qui vous permettent dinstaller facilement la dernire version dApache sur votre machine. Tlchargez lun de ces programmes, de prfrence depuis lun des miroirs du site Apache (http://mir2.ovh.net/ftp.apache.org/dist/httpd/binaries/win32/). Vous pouvez choisir entre un installateur automatique en .exe ou en .msi (Microsoft Installer). Si vous optez pour la version en .msi, assurez-vous que vous disposez bien de linstallateur Windows. Pour vrifier, dans le menu Dmarrer, puis dans Excuter, tapez la commande msiexec. Il vous faut au minimum la version 1.10.1029.1. Si vous ne disposez pas de la version approprie, tlchargez le programme depuis lune de ces adresses, en fonction de votre plateforme :
j j

2. Prise en main

Windows NT 4.0 : www.microsoft.com/downloads/release.asp?ReleaseID=17344 Windows 95 et 98 : www.microsoft.com/downloads/release.asp?ReleaseID=17343

Une fois que vous avez tlcharg le programme dinstallation dApache, lancez-le.
Figure 2.14 : Fentre daccueil

Acceptez la licence du programme, puis cliquez sur OK jusqu ce que vous arriviez sur la page qui vous pose quelques questions relatives la configuration du serveur.
Figure 2.15 :

Paramtrage minimal

65

Chapitre 2

Prise en main

Remplissez les champs Network Domain (nom du domaine pour lequel le serveur est install), Server Name (nom du serveur web qui va tre install), et donnez ladresse e-mail de ladministrateur. Choisissez ensuite si Apache doit tre install comme un service utilisable pour tous les utilisateurs, ou sil doit tre lanc manuellement par un utilisateur donn.
Figure 2.16 : Choix du type dinstallation

2. Prise en main

vous de faire votre choix selon les besoins du serveur que vous mettez en place. Donnez ensuite le chemin dinstallation pour que le processus puisse arriver terme.
Figure 2.17 : Fin de linstallation

Par la suite, vous pourrez rutiliser cet installateur pour rparer votre serveur web Apache si vous lavez mis mal avec de trop nombreux tests. Il vous suffit de relancer linstallateur pour quil vous propose soit de supprimer Apache, soit de le rparer.

Ruse de sioux Si vous installez Apache pour faire des tests sur votre machine personnelle, voici comment renseigner les champs de linstallateur Apache ltape Server Information.
j j

Network Domain : localdomain ; Server Name : localhost.localdomain ;

66

Installation

Administrators Email Address : votre adresse e-mail.

Si vous utilisez Windows XP avec le Service Pack 2, vous aurez certainement droit une alerte de scurit la fin de linstallation dApache.
Figure 2.18 : Alerte de Windows XP lors du dmarrage dApache

2. Prise en main

Cliquez sur le bouton Dbloquer pour permettre lexcution du serveur web. Une fois Apache install, il va se lancer automatiquement. Vous pourrez trouver une petite plume orne dune flche vers la droite dans la barre des tches Windows qui permet daccder la console de gestion de votre serveur Web. La console de gestion vous permet de connatre le statut du serveur, de larrter, de le relancer ou bien daccder la console de gestion des services Windows.
Figure 2.19 : Cliquez sur la petite flche verte sur fond blanc pour accder la console de gestion Apache

Figure 2.20 : La console de gestion du serveur Apache (ici ctait un test avec Apache2)

Vous pouvez lancer un navigateur et le faire pointer sur ladresse http://localhost pour vrifier si la page de test Apache saffiche bien. Une fois toutes ces tapes effectues, vous pouvez passer linstallation de PHP.

67

Chapitre 2

Prise en main

Installer PHP
Tlchargez larchive zippe disponible sur le site du groupe PHP (PHP Zip package dans la partie Windows Binairies de la section Download du site). Une fois que vous avez tlcharg le fichier compress, dcompactez-le sur votre disque dur dans un dossier spcialement cr cet effet. Sans vouloir vous influencer, c:\php serait une bonne ide (vitez tout particulirement les noms de dossiers avec des espaces). Dans ce dossier, reprez le fichier php.ini-dist, renommez-le en php.ini, et copiez-le dans votre rpertoire Windows (c:\Windows ou c:\WINNT). Une fois le fichier copi, ditez-le avec votre logiciel prfr. Recherchez cette ligne :
; extension_dir =

2. Prise en main

et renseignez le champ avec lemplacement o se trouvent les extensions PHP. Par exemple :
extension_dir = c:\PHP\ext\

si vous avez install PHP dans un dossier PHP la racine de votre disque dur. Noubliez pas, pour cette ligne et pour toutes les autres, de les dcommenter lorsque vous aurez rentr les paramtres ncessaires. Pour cela, il vous suffit de supprimer le ";" en dbut de ligne. Attention, ne dcommentez que la ligne contenant des paramtres ; laissez les lignes dexplication en commentaire. Recherchez ensuite la ligne
doc_root =

et renseignez le champ avec lemplacement de la racine de votre serveur web. Il sagit en fait de donner le chemin daccs du dossier c:\Program Files\Apache Group\Apache\htdocs\.
doc_root = "C:\Program Files\Apache Group\Apache\htdocs"

Une fois que vous en avez termin avec php.ini, copiez le fichier php5ts.dll qui se trouve la racine de votre rpertoire PHP dans le dossier System du rpertoire Windows (c:\windows\system pour Windows 9x/Me ou c:\winnt\system32 pour Windows NT/2000/XP).

Conguration
Vous allez devoir diter le fichier httpd.conf qui configure le serveur web Apache. Normalement, un lien a t prvu pour cela dans le groupe de programmes Apache cr aprs linstallation du serveur web (Configure Apache server puis Edit the Apache httpd.conf configuration file). Si vous ne trouvez pas ce lien, le fichier httpd.conf se trouve dans le dossier conf du rpertoire Apache. Avant de vous lancer dans la configuration, assurez-vous que votre serveur web Apache est bien arrt. Si vous lavez lanc depuis le lien prsent dans le menu Dmarrer, fermez simplement la console. Dans ce fichier, recherchez la ligne :
#LoadModule unique_id_module modules/mod_unique_id.so

Et ajoutez cette ligne juste aprs :


LoadModule php5_module c:/php/php5apache.dll

68

Installation

Attention, ne dcommentez pas la ligne dj prsente dans le fichier de configuration ; elle a juste t utilise pour permettre une localisation plus aise. Noubliez pas de donner votre propre chemin vers le fichier php5apache.dll. Si vous utilisez Apache 2 alors le nom du fichier devient php5apache2.dll. Recherchez ensuite la ligne:
#AddModule mod_setenvif.c

2. Prise en main

A sa suite, ajoutez cette ligne:


#AddModule mod_php4.c

Enfin, recherchez la ligne :


#AddType application/x-tar .tgz

la suite de laquelle vous ajoutez cette ligne :


AddType application/x-httpd-php .php .php5 .php4

Sauvegardez le fichier httpd.conf et relancez votre serveur web laide de la console Apache. Vous pouvez tester la bonne prise en compte de PHP en affichant un fichier test en PHP.

Racine Par dfaut, la racine de votre serveur web se trouve dans le dossier htdocs du rpertoire Apache. Cest donc l que vous devrez copier vos fichiers .php, .html, etc.

Complment dinstallation
Ca y est vous avez install PHP 5 pour Windows. Vous disposez de la majorit des bibliothques. Sachez toutefois, que le PHP Group propose galement un autre ensemble dextensions (pour la plupart peu utilises ou rendues obsoltes) dans un paquetage appel PECL. Celui-ci est disponible sur le site officiel ladresse http://www.php.net/downloads.php mais galement sur le CDROM fourni. Pour en profiter, il vous suffit de dzipper son contenu (ou seulement les dll qui vous intressent) dans le rpertoire contenant les extensions PHP dont le chemin est prcis dans le fichier php.ini sous le paramtre extension_dir. et de les activer en les supprimant les commentaires dans ce mme fichier.

Sous Mac OS X
Nous pouvons considrer quil existe deux grandes mthodes pour installer PHP dans un environnement Mac OS X. Cela peut ainsi se faire :
j j

Rien quen activant PHP au niveau du serveur prinstall (si vous disposez de la version serveur de Mac Os X) ; En faisant une installation "manuelle" (notamment si vous disposez de la version cliente de Mac Os X ou pour les mises jours).

69

Chapitre 2

Prise en main

Installation par un package


Des packages dinstallation prpars pour Mac sont disponibles pour Apache2 et PHP5. Comme pour PHP4, le site web Entropy.ch met disposition des internautes un package dinstallation de PHP5. Il est bien tenu jour et suit les remarques des utilisateurs. Vous pouvez le tlcharger cette adresse : http://www.entropy.ch/phpbb2/viewtopic.php?t=1446.

2. Prise en main

Linstallation dApache2 pourra se faire directement grce au package prpar par la Apache Software Foundation : http://www.apple.com/downloads/macosx/unix_open_source/apache.html. Vous naurez plus qu lancer une rapide compilation pour ensuite profiter dApache2.

Activation de PHP sur Mac Os X


Avec OS X, les Mac souvrent beaucoup plus facilement au web, que ce soit dans les versions serveur ou client. Mme si les Mac ont toujours fait des serveurs web trs scuriss, du fait, entre autres, de labsence de ligne de commande, la mise sur pied dun serveur web sur une machine de la firme de Cuppertino ntait pas, contrairement aux habitudes de la maison, un modle de simplicit. Le dernier systme dexploitation dApple, Mac OS X, repose sur Darwin, un noyau Unix libre. Avec larrive dune base Unix, les Mac gagnent en simplicit en matire de web. Alors que les utilisateurs de MacOs navaient leur disposition que quelques serveurs web quils devaient installer eux-mmes, Mac OS X dispose en natif dun serveur Apache qui nattend quun claquement de doigts pour tre oprationnel. De mme, PHP ne demande qu tre activ. On ne peut toutefois pas se limiter ses installations par dfaut. La volont lgitime davoir une installation plus personnalise (nouveaux modules, optimisation, etc.) passera par une installation ex nihilo dApache et de PHP, depuis des sources quil faudra compiler. Les mises jour dApache ou du langage PHP passeront par le suivi des annonces faites par Apple. Ainsi, nous verrons, dans un premier temps, lactivation des services et modules dj prsents linstallation et, dans un second temps, la compilation et linstallation des programmes depuis un code source.

Activer Apache
Serveur web le plus puissant ou le plus rpandu qui soit, peu importe : quand Apple fait quelque chose, il le fait de manire simple et accessible. Les amoureux de la ligne de commande vont en prendre pour leur grade Lancer Apache sur Mac OS X est encore plus simple que de terminer Adibou dcouvre les animaux en mode facile. Une fois Mac OS X lanc, allez dans le menu Pomme, puis dans Prfrences Systme, et slectionnez Partage. Dans la bote de dialogue qui souvre alors, vous trouverez de nombreuses options relatives la configuration de votre serveur web Apache. En effet, ce quApple appelle Partage web repose, en fait, sur le travail du serveur web (voir fig. 2.21). Sous le titre Partage web, cliquez simplement sur le bouton Dmarrer. Votre mot de passe vous sera alors demand ; rentrez-le, puis patientez quelques instants, le temps que le serveur se lance. Voil, le tour est jou. Si vous obtenez un message derreur, il se peut que vous ne soyez pas un utilisateur faisant partie du groupe "admin".

70

Installation

2. Prise en main

Figure 2.21 : La bote de dialogue Partage web sous Mac OS X

Le groupe "admin" Par dfaut, le premier utilisateur cr fait partie de ce groupe. Il faut faire partie de ce groupe pour accomplir certaines actions (lancer le partage web par exemple). Pour lancer ou arrter le serveur Apache, il faudra tre soit le premier utilisateur cr, soit un utilisateur qui aura t plac dans le groupe "admin".
Pour vrifier que tout fonctionne bien, vous pouvez lancer votre navigateur web prfr et vous rendre ladresse http://localhost/. Vous devriez y trouver une page daccueil par dfaut. Vous pouvez galement effectuer cette vrification avec votre nom dutilisateur, en vous rendant sur votre espace web personnel qui aura t cr automatiquement par le serveur. Si vous tes lutilisateur toto, votre espace personnel sera alors accessible ladresse http://localhost/toto/. Cela nest pas trs utile pour le moment, mais cela pourra se rvler intressant quand il sagira de faire des tests de scripts. Vous pourrez utiliser votre espace personnel plutt que le site web de premier niveau (un site en http://localhost/~toto plutt que http://localhost/). Les utilisateurs trouveront leur site dans leur rpertoire personnel, dans le dossier Sites. Pour publier des documents la racine du site, il faudra placer ces lments dans le dossier "/Library/Webserver/Documents/".

Activer PHP
Le serveur Apache install sur Mac OS X comporte dj le module PHP. Toutefois, celui-ci nest pas activ par dfaut. Il faut donc faire quelques acrobaties accompagnes dun redmarrage du serveur web pour que toutes les modifications soient prises en compte.

Faire fausse root En fouillant sur le web, ou en puisant dans ses connaissances dunixien, on peut tre tent dactiver le module PHP en passant par lutilisateur root. Or, ce compte nexiste pas sur Mac OS X. Il est bien sr possible de le crer. Toutefois, il est fortement recommand de ne pas crer ce compte. Dune part, on respecte ainsi la philosophie dApple vis--vis de son systme dexploitation et, dautre part, lon garantit une meilleure scurit au systme root ayant droit de vie et de mort sur le systme).

71

Chapitre 2

Prise en main

Pour mener bien certaines oprations, vous devrez utiliser la commande sudo (su pour "super-user" et do de "to do"). Cette commande vous permet davoir accs des actions normalement rserves lutilisateur root. Lorsque vous ferez appel cette commande pour la premire fois, le systme vous demandera votre mot de passe. Ensuite, vous pourrez lutiliser directement. Lactivation de PHP consiste principalement en une modification du fichier httpd.conf, fichier de configuration du serveur web Apache. Avant de faire des modifications sur ce fichier, il est fortement recommand den faire une copie, afin de garder une porte de sortie en cas de mauvaise manipulation. Rendre ce fichier de configuration inutilisable revient purement et simplement mettre en berne son site web, Apache ne pouvant alors plus dmarrer. Pour faire cette copie, lancez un terminal (depuis le Finder, dans le dossier Applications, puis le dossier Utilitaires, choisissez Terminal). Une fois le terminal lanc, saisissez cette ligne de commande :
sudo cp /etc/httpd/httpd.conf /etc/httpd/httpd.conf.copie

2. Prise en main

Le systme vous demande votre mot de passe ; donnez-le lui. Si jamais il vous arrivait malheur lors de ldition du fichier de configuration, vous nauriez alors qu craser le fichier de configuration par la sauvegarde que vous aviez faite. Pour cela, utilisez cette commande :
sudo cp /etc/httpd/httpd.conf.copie /etc/httpd/httpd.conf

Une fois cette opration effectue, nous pouvons travailler sans danger sur le fichier httpd.conf (ou tout au moins sans remords). Nous allons devoir rechercher les rfrences PHP dans ce fichier, pour nous assurer quelles sont bien prises en compte par le serveur lors de son dmarrage. Nous utiliserons lditeur de texte Pico pour travailler sur le fichier. Si cest la premire fois que vous utilisez cet diteur en mode texte, il peut tre utile den consulter laide. Cela vous vitera des heures derrance, coinc dans un fichier texte qui nen demandait pas tant. Puis, une fois Pico lanc, tapez [Ctrl}]+ [G] pour accder laide intgre. La plupart des commandes sobtiennent par le biais de la touche [Ctrl] suivie dune lettre. Vous pouvez dailleurs voir les fonctions les plus utiles en bas de la fentre de terminal. Une fois que vous avez compris les bases de lutilisation de Pico, vous pouvez lancer ldition du fichier http.conf :
sudo pico /etc/httpd/httpd.conf

Noubliez pas que vous devez donner votre mot de passe. Dans ce fichier, recherchons les rfrences PHP ([Ctrl}]+[}W], PHP, [Entre]). La premire rponse doit tre celle-ci :
#LoadModule php5_module libexec/httpd/libphp5.so

Le # devant la ligne signifie quelle est commente, et que le serveur ne prend pas en compte cette ligne de configuration lors de son dmarrage. Supprimez le # et refaites une recherche. Vous ne devriez pas avoir ressaisir "php", Pico gardant en mmoire la dernire occurrence de recherche. Votre nouvelle recherche doit vous amener cette ligne :
#AddModule mod_php4.c

De mme, supprimez le #. Dsormais, Apache chargera le module PHP lors de son chargement.

72

Installation

Continuons la recherche. Loccurrence suivante doit se trouver dans ce paragraphe :


# AddType allows you to tweak mime.types without actually editing it, or to # make certain files to be certain types. # # For example, the PHP 3.x module (not part of the Apache distribution - see # http://www.php.net) will typically use: # #AddType application/x-httpd-php3 .php3 #AddType application/x-httpd-php3-source .phps # # And for PHP 4.x, use: # #AddType application/x-httpd-php .php #AddType application/x-httpd-php-source .phps

2. Prise en main

Ce paragraphe stipule que les fichiers dlivrs par le serveur qui ont pour extension .php3, .php ou .phps doivent tre traits avec le module PHP. Supprimez aussi les # devant ces lignes, sinon le chargement du module PHP ne servirait pas grand-chose. Attention, ne dcommentez pas toutes les lignes, mais seulement les lignes dinstructions, comme ceci :
# # # # # # AddType allows you to tweak mime.types without actually editing it, or to make certain files to be certain types. For example, the PHP 3.x module (not part of the Apache distribution - see http://www.php.net) will typically use: AddType application/x-httpd-php3 .php3 AddType application/x-httpd-php3-source .phps # # And for PHP 4.x, use: # AddType application/x-httpd-php .php AddType application/x-httpd-php-source .phps

Recherchez maintenant loccurrence <IfModule mod_dir.c>. Vous devez arriver sur un paragraphe comme celui-ci :
<IfModule mod_dir.c> DirectoryIndex index.html </IfModule>

Ajoutez "index.php" la ligne du milieu, en laissant un espace aprs "index.html". Cela indique au serveur Apache quil doit, lorsquon lui donne une adresse du type http://toto.com/titi/, rechercher un fichier index.html dans le dossier /titi, mais galement un fichier index.php. Voil, toutes les modifications ncessaires ont t effectues. Vous pouvez sauvegarder le fichier et quitter Pico. Il vous faut maintenant redmarrer le serveur Apache, afin quil prenne en compte les modifications que vous avez effectues dans le fichier de configuration. Faites-le depuis linterface graphique (Partage web, en arrtant puis dmarrant le serveur), ou encore depuis votre terminal en tapant cette commande :
sudo apachectl restart

73

Chapitre 2

Prise en main

Pour vrifier que vos modifications ont bien t intgres, tapez cette commande dans votre shell :
tail /var/log/httpd/error_log

Cela aura pour effet dafficher les traces des messages derreur dApache. Au dbut du fichier, vous devez pouvoir trouver cette ligne :
[notice] Apache/1.3.23 (Darwin) PHP/4.1.2 configured -- resuming normal operations

2. Prise en main

Une fois que tout est intgr et fonctionnel, profitez de loccasion pour faire une copie de sauvegarde de votre fichier httpd.conf. Cela vous vitera, lors dune rinstallation, de devoir rpter toutes ces manipulations. Toujours dans votre shell, tapez cette commande :
sudo cp /etc/httpd/httpd.conf /etc/httpd/httpd.conf.copie

Une version serveur de pointe Sur la version serveur de Mac OS X, le serveur de bases de donnes MySQL fait galement partie de linstallation par dfaut. Dans la version client, il faut installer soi-mme le serveur.

Installation manuelle
Apple fournit des sources prtes tre compiles qui vous permettront de rester jour sans avoir rinstaller tout votre systme. Compiler une nouvelle version dApache ou du langage PHP peut tre obligatoire pour des raisons de scurit. Ayez en tte que vous devrez alors certainement revoir des options de configuration (tout particulirement pour httpd.conf) pour vos logiciels nouvellement installs. Faites galement le tour des modules que vous avez installs et des modules qui seront disponibles et compatibles aprs la mise jour. Certains portages peuvent prendre quelque temps. vitez donc de faire une mise jour trop rapide, qui vous priverait de modules dont vous avez besoin pour votre site.

Compiler Apache
Avant daller plus loin, assurez-vous que vous disposez bien des outils de dveloppement Apple sur votre machine. Si vous navez pas le CD qui contient ces logiciels, vous pouvez vous inscrire gratuitement au Developper Network dApple. Cet enregistrement vous donnera accs ces logiciels, que vous naurez plus qu tlcharger et installer. Nous vous recommandons dailleurs de faire des mises jour de ces logiciels. En effet, les versions les plus rcentes dApache ou de PHP pourraient ne pas se compiler avec des outils trop anciens. Une fois cette installation effectue, lancez un terminal (depuis le Finder, dans le dossier Applications, puis le dossier Utilitaires, choisissez Terminal). Saisissez alors les lignes de commande suivantes :
mkdir install_apache cd /install_apache

Vous crez et entrez dans un rpertoire qui vous servira pour cette compilation.
wget http://www.apache.org/dist/httpd/httpd_XX.tar.gz

Vous tlchargez la dernire version du serveur web Apache directement depuis le site dApple.

74

Installation

gnutar xzf httpd_XX.tar.gz

Vous dcompressez le fichier contenant les sources.


cd httpd_XX

Vous entrez dans le rpertoire qui contient les sources.


./configure --enable-module=most --enable-shared=max

2. Prise en main

Vous crez le fichier de configuration qui servira lors de la compilation.


make

Vous compilez les sources.


sudo make install

Vous installez les excutables sur votre systme. Noubliez pas que cest votre mot de passe quil faut donner au systme pour quil puisse excuter la commande sudo. Dans httpd_XX.tar.gz, les XX sont remplacer par le numro de la version dApache concerne. Noubliez pas darrter puis de relancer votre serveur Apache, comme nous lavons vu plus haut, afin que ce soit cette nouvelle version qui soit en service.

Compiler PHP
Dans un terminal, rentrez les commandes suivantes :
mkdir install_php cd install_php

Vous crez et entrez dans un rpertoire qui vous servira pour cette compilation.
wget http://www.php.net/distributions/php-XX.tar.gz

Vous tlchargez la dernire version du langage PHP directement sur le site de PHP.
gnutar -xzf php-XX.tar.gz

Vous dcompressez le fichier contenant les sources.


cd php-XX.tar.gz

Vous entrez dans le rpertoire qui contient les sources.


./configure --with-apxs=/usr/sbin/apxs --disable-pear

Sans PEAR cest mieux ? Si, comme nous, vous rencontrez des problmes lis la bibliothque PEAR, nhsitez pas utiliser loption --disable-pear. Vous pouvez toutefois essayer sans, histoire de voir si vous tes plus chanceux que nous

75

Chapitre 2

Prise en main

Vous crez le fichier de configuration qui servira lors de la compilation.


make

Vous compilez les sources.


sudo make install

2. Prise en main

Vous installez les excutables sur votre systme.


sudo cp php.ini-dist /usr/local/lib/php.ini

Vous copiez le fichier de configuration de PHP dans un rpertoire o Apache saura le trouver. Noubliez pas que cest votre mot de passe quil faut donner au systme pour quil puisse excuter la commande sudo. Dans php-XX.tar.gz, les XX sont remplacer par le numro de la version du langage PHP concerne. Assurez-vous enfin que votre fichier httpd.conf est bien configur pour permettre Apache dutiliser et dinterprter correctement PHP.

Quelques liens En franais Un tutoriel en franais trs complet et trs bien fait pour installer Apache2 et PHP5 :
www.phpmac.com/articles.php?view189

De nombreuses informations pour les dveloppeurs sous Mac Os X (page PHP) :


http://projectomega.online.fr/contents/fr/php/index.php

En anglais Installer Apache2 et PHP5 sous Mac OS X :


http://laughingmeme.org/archives/001787.html

PHP sur Mac Os X, chez Apple (conseils pour la compilation, modules compatibles, etc.) :
http://developer.apple.com/internet/Mac_OS_X/php.html

Apache et PHP sous Mac Os X par lun des crateurs de Darwin :


http://www.stepwise.com/Articles/Workbench/2001-10-11.01.html

Apache et PHP sous Mac Os X, par Marc Liyanage :


http://www.entropy.ch/software/macosx/php/

Avec IIS
Installer IIS
Linstallation du serveur web IIS est plutt simple. Insrez le CD-ROM dinstallation de Windows NT, 2000 ou XP Pro dans le lecteur de votre machine. Allez dans le menu Dmarrer puis dans Paramtres et Panneau de configuration. Lancez Ajout/Suppression de programmes. Cliquez sur longlet Ajouter/Supprimer des composants Windows, puis cochez la case Services

76

Installation

Internet (IIS), validez par OK. Vous pouvez tester la bonne installation dIIS en ouvrant un navigateur cette adresse : http://localhost/.

Installer PHP
Vous devrez donc utiliser larchive zippe disponible sur le site du groupe PHP (PHP Zip package dans la section Windows Binairies de la section Download du site), ou celle fournie sur le CD-ROM. Une fois que vous avez tlcharg le fichier compress, dcompactez-le sur votre disque dur, dans un dossier spcialement cr cet effet. Sans vouloir vous influencer, c:\php serait une bonne ide (vitez tout particulirement les noms de dossiers avec des espaces). Dans ce dossier, reprez le fichier php.ini-dist, renommez-le en php.ini , et copiez-le dans votre rpertoire Windows (c:\Windows ou c:\WINNT). Une fois le fichier copi, ditez-le avec votre logiciel prfr. Recherchez cette ligne :
; extension_dir=

2. Prise en main

et renseignez le champ avec lemplacement o se trouvent les extensions PHP. Par exemple :
extension_dir=c:\PHP\extensions\

si vous avez install PHP dans un dossier PHP la racine de votre disque dur. Noubliez pas, pour cette ligne et pour toutes les autres, de les dcommenter lorsque vous aurez rentr les paramtres ncessaires. Pour cela, il vous suffit de supprimer le ";" en dbut de ligne. Attention, ne dcommentez que la ligne contenant des paramtres ; laissez les lignes dexplication en commentaire. Recherchez maintenant la ligne :
;browscap=extra/browscap.ini

et donnez ladresse de votre fichier browscap.ini. Sous Windows 9x ou Me, vous le trouverez l : c:\windows\system\inetsrv\browscap.ini et, sous Windows NT, 2000 ou XP Server, il est situ au bout de ce chemin : c:\winnt\system32\inetsrv\browscap.ini. (Cette opration est plus que facultative). Si vous voulez installer dautres extensions, il vous suffit de disposer des DLL requises par celles-ci, et de dcommenter les lignes les concernant dans le fichier de configuration. Une procdure complte est prsente dans le fichier install.txt fourni avec larchive PHP. Cette procdure est galement dcrite pour chaque bibliothque prsente dans ce livre. Une fois que vous en avez fini avec le fichier php.ini, et quil est bien plac la racine de votre dossier Windows, passez la configuration du serveur lui-mme. Il vous faut travailler dans la console dadministration du serveur IIS. Pour cela, allez dans le Panneau de configuration, puis dans Outils dadministration. L, double-cliquez sur Gestionnaire des services Internet. Dans la fentre qui souvre, faites un clic droit sur le serveur web que vous voulez configurer, et choisissez Proprits. (Attention, droulez bien larborescence pour arriver au site web. Ne travaillez pas sur la machine locale.)

77

Chapitre 2

Prise en main

Figure 2.22 : Configuration de PHP pour IIS

2. Prise en main

Cliquez sur longlet Rpertoire de base, puis sur le bouton Configuration. Dans la nouvelle fentre, cliquez sur Ajouter. Dans la nouvelle fentre (Ajout/modification de mappage dextension de fichier), cliquez sur Parcourir, et donnez le chemin vers php4isapi.dll (normalement dans le dossier sapi de votre rpertoire PHP). Dans le champ extension, donnez .php. Vrifiez que la case Moteur de script est bien coche, puis cliquez sur OK pour revenir la console dadministration. Depuis cette mme console, arrtez et relancer votre serveur. Vous pouvez dsormais tester la bonne gestion de PHP. Vous devrez recommencer lopration pour toutes les extensions que le serveur doit interprter comme de PHP (.php3, .phtml, etc.).

Avec iPlanet
Sous Linux
Installer iPlanet
iPlanet sinstalle vite et bien. En plus dtre gratuit, il dispose dune interface web de configuration trs puissante, qui pourra aider les plus novices et qui, pour tous, facilite nombre de tches. Dans bien des situations, cela vite davoir passer par les fichiers de configuration. Nous prsentons ici une installation pour GNU/Linux sur une distribution RedHat. Pour une installation sur un autre systme de type UNIX, reportez-vous aux liens prsents en fin de partie. Pour installer iPlanet, moins que vous ne disposiez de votre propre copie, tlchargez-en une version sur le site de Sun (wwws.sun.com/software/download/download/5126.html). Le serveur est distribu sans contrepartie ; il vous suffit de laisser quelques informations Sun. Pendant que le tlchargement suit son cours, vous allez pouvoir faire quelques petites manipulations prparatoires. La version de iPlanet distribue par Sun pour Linux a t prpare pour une RedHat 6.0. Les autres distributions (hors Mandrake) auront certainement quelques difficults sadapter. Les versions postrieures la 6.0 posent dailleurs un problme assez gnant, puisquelles interrompent carrment le script dinstallation du serveur. En fait, iPlanet demande

78

Installation

la librairie ncurses dans sa quatrime version, alors quaujourdhui, cest la version 5.2 qui est fournie avec les systmes RedHat. Il est possible de tricher en faisant un lien symbolique de la version installe vers une prtendue version 4 ; version qui donnera alors entire satisfaction au script dinstallation. Pour cela, en tant logu en tant que root, rentrez la commande suivante :
ln -s /usr/lib/libncurses.so.5.2 /usr/lib/libncurses.so.4

Pour vrifier quelle est la version de ncurses installe sur votre systme, tapez la commande :

2. Prise en main

locate ncurses

Notez alors le chemin qui saffiche, et utilisez-le dans la commande donne plus haut. Cette manuvre ne met absolument pas en pril le systme dexploitation, pas plus quelle ne compromet le bon fonctionnement du serveur. La librairie concerne nest en effet utilise que lors de la cration de linterface dadministration. Lors de nos tests, cette procdure a parfaitement fonctionn, nentranant aucun dysfonctionnement du serveur, du systme Linux, ni de linterface graphique elle-mme. Une fois le lien cr et le tlchargement termin, vous pouvez passer linstallation du serveur. Avant de vous lancer dans la procdure dinstallation, assurez-vous que vous disposez bien de tous les outils logiciels ncessaires : compilateur, gestionnaire de fichiers compresss, etc. Les utilisateurs de Sun trouveront tout le ncessaire sur le site http://www.sunfreeware.com. Rendez-vous dans le dossier contenant larchive iPlanet et dcompactez-la. Entrez dans le dossier iws qui vient alors dtre cr. En tant quutilisateur root (commande su pour passer en root), lancez le script dinstallation (./setup). Renseignez ensuite tous les champs demands et rpondez aux questions qui restent assez classiques (dossier racine du site, cration dun utilisateur et dun groupe pour le serveur, etc.). Vous pouvez dailleurs choisir entre une configuration express ou une configuration avance. vous de voir ce qui convient le mieux linstallation que vous tes en train deffectuer. Si vous ne destinez pas le serveur une mise en exploitation, autant aller au plus vite. Retenez bien lidentifiant (login) et le mot de passe qui vous sont demands pour laccs linterface de gestion. Une fois iPlanet install, passons la compilation de PHP.

Compiler PHP
Tout dabord, tlchargez la dernire version de PHP sur le site officiel (http://www.php.net), ou bien utilisez celle fournie sur le CD-ROM. Passez en utilisateur root, et vrifiez que les paramtres suivants sont bien situs dans votre PATH (commande echo $PATH). Si elle ny sont pas, ajoutez-les :
:/usr/local/bin:/usr/sbin:/usr/bin:/usr/ccs/bin

Dcompactez larchive :
# tar xzvf php-XX.tar.gz

Rentrez dans le rpertoire cr lors du dcompactage, puis rentrez cette commande :


# ./configure --with-nsapi=/opt/netscape/suitespot/ --enable-libgcc

Le chemin suivant le paramtre withnsapi varie selon votre installation. vous de donner le bon chemin. Sous Linux, ce doit tre quelque chose comme : /usr/iplanet/servers/.

79

Chapitre 2

Prise en main

Si le serveur de base de donnes MySQL est install sur votre machine, vous pouvez galement donner ce paramtre comme option de configuration withmysql=/usr/lib/mysql. Une fois la configuration effectue, rentrez alors la commande :
# make

puis, finalement :

2. Prise en main

# make install

PHP est maintenant install sur votre systme. Vous pouvez passer la configuration du serveur web.

Conguration diPlanet
La configuration du serveur iPlanet se rsume ldition de quelques fichiers de configuration ponctue dun redmarrage dudit serveur. Rendez-vous dans le rpertoire contenant les fichiers de configuration de votre serveur (quelque chose comme /usr/iplanet/servers/ https-localhost.localdomain/config/). Faites attention, ne vous trompez pas entre le dossier https-loalhost.localdomain et le dossier https-admserv. Le premier est le bon ; cest celui qui contient les informations et documents relatifs votre serveur web public. Le second ne concerne que le serveur utilis par linterface web de configuration, Sun ayant offert linterface web son propre serveur (ce qui est plutt une bonne ide quand on sait ce que peut engendrer une mauvaise manipulation des fichiers de configuration). Nayez dailleurs pas peur lors de vos exercices de configuration : il existe dj sur votre machine un rpertoire de sauvegarde qui contient une copie des fichiers de configuration du serveur web. Situ au mme niveau que le dossier config, le dossier config-bk pourra vous sortir de lornire en cas de ppin. Il vous suffira de copier tout simplement son contenu dans le rpertoire config. Commencez dabord par diter le fichier mime.types pour y ajouter la ligne suivante :
type=magnus-internal/x-httpd-php exts=php,php3,php4,php5,phtml

Sauvegardez mime.types, puis passez magnus.conf. Ajoutez les lignes suivantes la fin de la section des inits, en dbut de fichier :
Init fn="load-modules" funcs="php5_init,php5_close,php5_execute,php5_auth_trans" shlib="/php5/nsapiPHP5.dll" Init fn="php5_init" errorString="Linitialisation du PHP a chou !" LateInit="yes"

Le chemin utilis pour shlib varie en fonction du systme dexploitation. Pour Linux, ce sera quelque chose comme /opt/netscape/suitespot/bin/libphp5.so ou /usr/iplanet/servers/bin/libphp5 .so. Donnez simplement le chemin qui pointe vers la librairie PHP 5, prcdemment installe lors de la compilation. Une fois magnus.conf complt, sauvegardez-le, puis ouvrez obj.conf. En suivant le modle et laspect gnral du fichier, ajoutez-y le bloc de texte suivant (un nouvel objet) :
</Object> <Object name="x-httpd-php"> ObjectType fn="force-type" type="magnus-internal/x-httpd-php" Service fn=php5_execute

80

Installation

</Object>

Ensuite, dans lobjet default, vous devrez ajouter la ligne suivante :


Service fn="php5_execute" type="magnus-internal/x-httpd-php"

et ce avant chaque ligne AddLog et aprs chaque ligne ObjectType. Voici un exemple, pris pour une configuration sous Linux :
<Object name=default> NameTrans fn="NSServletNameTrans" name="servlet" NameTrans fn="pfx2dir" from="/servlet" dir="/usr/iplanet/servers/docs/servlet" name="ServletByExt" NameTrans fn=pfx2dir from=/mc-icons dir="/usr/iplanet/servers/ns-icons" name="es-internal" NameTrans fn="pfx2dir" from="/manual" dir="/usr/iplanet/servers/manual/https" name="es-internal" NameTrans fn=document-root root="$docroot" PathCheck fn=unix-uri-clean PathCheck fn="check-acl" acl="default" PathCheck fn=find-pathinfo PathCheck fn=find-index index-names="index.html,home.html" ObjectType fn=type-by-extension Service fn="php5_execute" type="magnus-internal/x-httpd-php" ObjectType fn=force-type type=text/plain Service fn="php5_execute" type="magnus-internal/x-httpd-php" Service type="magnus-internal/jsp" fn="NSServletService" Service method=(GET|HEAD) type=magnus-internal/imagemap fn=imagemap Service method=(GET|HEAD) type=magnus-internal/directory fn=index-common Service method=(GET|HEAD|POST) type=*~magnus-internal/* fn=send-file Service fn="php4_execute" type="magnus-internal/x-htt AddLog fn=flex-log name="access" </Object>

2. Prise en main

Une fois le fichier obj.conf correctement renseign, sauvegardez-le et relancez le serveur web afin quil prenne en compte les dernires modifications (commande ./restart). Vous pouvez alors tester la bonne prise en compte de PHP avec une simple page place la racine de votre serveur web.

Sous Windows
Linstallation et la configuration du serveur web iPlanet sous Windows ne prsentent pas de difficult particulire. Bien que nombreuses, les tapes ncessaires ne sont en rien insurmontables.

Installation du serveur web iPlanet


Tout dabord, tlchargez directement la version Windows du serveur sur le site de Sun (wwws .sun.com/software/download/download/0104.html). Lancez le programme dinstallation. La procdure vous est propose en trois dclinaisons : express, typique ou personnalise. Si cest la premire fois que vous installez iPlanet sur votre machine, choisissez loption typique, qui est largement

81

Chapitre 2

Prise en main

2. Prise en main

suffisante, et qui vous permettra mme de modifier certains paramtres assez pratiques. Premier point important, vous allez devoir choisir un dossier pour linstallation du serveur web. Conservez le chemin propos par le programme dinstallation (vitez le dossier Program Files qui serait pineux utiliser dans des fichiers de configuration). Donnez ensuite un nom dutilisateur et un mot de passe, qui seront utiliss pour linterface dadministration web. Conservez prcieusement ces informations, sans quoi vous seriez un peu gn pour grer votre serveur. Le port dadministration (par dfaut 8888) ainsi que le port web (80) nont pas tre modifis, moins que vous nayez une ide bien spcifique. tape suivante, spcifiez et notez bien le dossier racine du site. Les dernires tapes de prparation de linstallation concernent lutilisation ventuelle dun annuaire LDAP ou de Java. Lorsque vous aurez rpondu toutes ces questions, linstallation proprement dite pourra dbuter. Une fois iPlanet correctement mis en place, vous pouvez tester son bon fonctionnement en rentrant ladresse http://localhost/ dans un navigateur web de votre choix.

Installer PHP
Tlchargez la dernire version de PHP pour Windows zippe sur le site officiel du groupe PHP (http://www.php.net), ou bien utilisez la version disponible sur le CD-ROM. Dcompactez cette archive dans un dossier c:\php, ou dans tout autre dossier simple, facile reprendre pour les ditions de fichiers de configuration venir. Copiez le fichier php4ts.dll ainsi dcompact dans votre dossier Windows (c:\WINNT). Toujours dans le dossier qui a servi pour le dcompactage, trouvez le fichier php.ini-dist, et renommez-le en php.ini. Le changement de nom effectu, ditez ce mme fichier, soit avec votre diteur de texte prfr, soit avec la ligne de commande suivante dans une fentre MSDos :
edit php.ini

Dans ce fichier, recherchez la ligne :


extension_dir = ./

et renseignez-la avec lemplacement sur votre systme du dossier contenant les extensions PHP. Si vous avez dcompact PHP dans un rpertoire c:\php, vous devez remplir la ligne ainsi :
extension_dir= c:\php\extensions\

Sauvegardez le fichier, puis copiez-le la racine de votre rpertoire WINNT :


copy php.ini c:\WINNT\

Il vous faut maintenant crer une association de fichiers pour PHP. Dans une fentre MSDos, rentrez les deux lignes de commande suivantes, en validant par la touche [Entre] chaque fin de ligne :
assoc .php=PHPScript ftype PHPScript=c:\php\php.exe %1 %*

noter que ladresse donne dans la seconde ligne est modifier selon vos propres paramtres. Vous pouvez passer maintenant la configuration du serveur web iPlanet pour quil prenne en compte PHP.

82

Installation

Congurer PHP
Tout dabord, stoppez votre serveur (depuis linterface web de configuration, dans la rubrique on/off). Commencez dabord par diter le fichier mime.types pour y ajouter la ligne suivante :
type=magnus-internal/x-httpd-php exts=php,php3,php4,phtml

2. Prise en main

Sauvegardez mime.types, puis passez obj.conf. Ajoutez les lignes suivantes la fin de la section des inits, en dbut de fichier :
Init fn="load-modules" funcs="php5_init,php5_close,php4_execute,php5_auth_trans" shlib="c:/php/sapi/php5nsapi.dll" Init fn="php5_init" errorString="Linitialisation du PHP a chou !" LateInit="yes"

Le chemin utilis pour shlib varie en fonction de votre installation. Avec lexemple cit plus haut, il faudrait donner ce chemin : c:/php/sapi/php4nsapi.dll. En suivant le modle et laspect gnral du fichier, ajoutez-y le bloc de texte suivant (un nouvel objet) :
</Object> <Object name="x-httpd-php"> ObjectType fn="force-type" type="magnus-internal/x-httpd-php" Service fn=php5_execute </Object>

Ensuite, dans lobjet default, vous devrez ajouter la ligne suivante :


Service fn="php5_execute" type="magnus-internal/x-httpd-php"

et ce avant chaque ligne AddLog et aprs chaque ligne ObjectType (pour un exemple de fichier de configuration, voir la partie Configuration sous Unix). Une fois ces fichiers dits et sauvegards, vous pouvez relancer le serveur web et tester votre nouvelle configuration.

Autres
Installation sous les autres systmes dexploitation Installation sous HP-UX :
www.php.net/manual/fr/install.hpux.php

Installation sous Solaris :


www.php.net/manual/fr/install.solaris.php

Installation sous Unix-OpenBSD :


www.php.net/manual/fr/install.openbsd.php

Tutoriel dinstallation pour PHP sous Windows NT :


http://benoit.noss.free.fr/php/install-php4.html

83

Chapitre 2

Prise en main

2.2.

Le chier de conguration php.ini

PHP se configure en deux fois. Dans un premier temps, lors de sa compilation, pour assurer le support de certaines bases de donnes, dun serveur web sous la forme dun module pour activer certaines fonctions, etc. ; et, dans un second temps, aprs son installation, par ldition et le renseignement du fichier php.ini.

2. Prise en main

Le fichier php.ini contrle bon nombre des comportements de PHP. Pour que PHP puisse lire et comprendre ce fichier, il doit imprativement avoir pour nom php.ini. Au dmarrage, PHP cherche ce fichier dans son rpertoire de travail, dans le chemin dsign par la variable denvironnement PHPRC puis, enfin, dans le chemin dfini lors de la compilation. Sous Windows, le chemin correspond au rpertoire Windows ; sous Linux, par dfaut, il sagit du rpertoire /usr/local/lib. Si PHP a t compil en module, le fichier php.ini ne sera lu quune seule fois, lors du lancement du serveur web. Si PHP fonctionne en CGI, php.ini sera lu chaque utilisation de PHP. Si vous utilisez des constantes dans vos valeurs et que ces constantes appartiennent une extension charge dynamiquement (extension PHP ou Zend), vous ne pouvez utiliser ces constantes quaprs la ligne de configuration qui charge cette extension. Les valeurs utilises dans le fichier php.ini-dist correspondent aux valeurs par dfaut de PHP. Cela veut dire que, si vous nutilisez pas de php.ini ou que vous effacez les lignes qui suivent, les valeurs et paramtres utiliss par PHP seront identiques ceux prsents dans php.ini-dist. Pour crer un fichier php.ini, utilisez le fichier php.ini-dist prsent dans votre rpertoire PHP. Ce fichier contient un squelette de configuration, quil vous appartiendra dadapter votre systme selon vos besoins. Notez quil existe galement un fichier php.ini-recommended, que vous trouverez, lui aussi, la racine de votre dossier PHP. Ce fichier est une recommandation de configuration pense pour vous par les dveloppeurs de PHP. Comme le prcise len-tte du fichier, cette configuration peut rendre PHP incompatible avec certaines applications. Elle rend galement le dveloppement plus difficile et plus rigoureux. Une bonne solution consiste se baser sur ce fichier, en passant en revue toutes les variables pour vrifier si elles conviennent votre environnement de travail. Vous ne modifierez ainsi que le strict ncessaire, tout en conservant une configuration plus sre et plus performante que celle offerte par dfaut par la simple mise en place du php.ini-dist. Dans cette partie, nous allons passer en revue toutes les options prsentes dans le fichier php.ini-dist ; fichier qui, une fois renseign, deviendra votre propre php.ini. La syntaxe du fichier php.ini est simple. Toute ligne commenant par un point-virgule ou toute chane de caractres contenue entre crochets ne sera pas interprte par PHP. Les directives utilisent une syntaxe simple :
directive = valeur

Attention, les noms des directives sont sensibles la casse : respectez donc scrupuleusement lutilisation des majuscules ou minuscules (EMMA est diffrent de Emma). La valeur peut consister en une chane de caractres, un nombre, une constante PHP (ex. : E_ALL ou M_PI), une des constantes INI (On, Off, True, False, Yes, No et None), une expression (ex. : E_ALL & ~E_NOTICE), ou, enfin, une chane de caractres entre guillemets ("emma").

84

Le fichier de configuration php.ini

Dans le fichier php.ini, les expressions sont limites aux oprateurs binaires et aux parenthses :
| & ~ ! binaire binaire binaire booleen OR AND NOT NOT

Les oprateurs boolens peuvent tre activs en utilisant les valeurs 1, On, True ou Yes. Pour les dsactiver, utilisez les valeurs 0, Off, False ou No. Une chane vide peut tre indique soit en ncrivant rien aprs le =, soit en utilisant le mot-cl none. Attention, dans lexpression toto = "none", la chane de caractres ne sera pas vide, mais contiendra le mot none ; une chane vide serait toto = none.

2. Prise en main

Options PHP de base


Balises
short_open_tag = On

permet dutiliser le tag court douverture de script PHP < ? (plutt que < ?php ou <script>).
asp_tags = Off

permet dutiliser les tags ASP <% %>.

Serveur
engine = On

autorise le moteur de langage de script PHP sous Apache.


zend.ze1_compatibility_mode = Off

active le module de compatibilit avec le Zend Engine 1 (utilis dans PHP4.x).


expose_php = On

permet dindiquer que PHP est install sur le serveur, et que, par consquent, on peut lutiliser. Cela ne constitue pas proprement parler un problme de scurit, mais cela signale tout de mme aux utilisateurs que PHP est install sur le serveur.
y2k_compliance = Off

Compatibilit an 2000. Il est dconseill dactiver cette option, car elle pourrait poser des problmes avec des navigateurs non compatibles an 2000.

85

Chapitre 2

Prise en main

Limites des ressources


max_execution_time = 30

Indiquez le temps maximum dexcution des scripts, en secondes (ici : 30 secondes).


memory_limit = 8M

2. Prise en main

Indiquez la quantit maximale de ressource mmoire utilisable par les scripts (ici : 8 Mb).

Scurit
Mode scuris
safe_mode = Off

Activation ou dsactivation du mode scuris.


safe_mode_gid = Off

louverture des fichiers, le mode scuris utilise, par dfaut, des vrifications comparatives des UID. Pour passer des comparaisons sur le GID, activez cette commande.
safe_mode_include_dir =

Si safe_mode est activ, les vrifications des UID/GID sont ignores lorsquun fichier contient des inclusions de fichiers provenant de ce rpertoire ou de ses sous-rpertoires. Le chemin concern doit tre prsent dans le include_path, ou alors cest le chemin complet qui doit tre donn pour linclusion.
safe_mode_exec_dir =

Si le mode scuris est activ, seuls les excutables qui se situent dans le rpertoire renseign ici seront autoriss lexcution via la famille des fonctions excutables (comme exec()).
open_basedir =

Indiquez le chemin du rpertoire sur lequel vous souhaitez limiter les oprations sur les fichiers. Ceci sera valable pour ce rpertoire et ses sous-rpertoires.
safe_mode_allowed_env_vars = PHP_

La configuration de certaines variables denvironnement peut prsenter des failles de scurit. Cette directive comprend une liste de prfixes spars par des virgules. En mode scuris, lutilisateur peut uniquement modifier les variables denvironnement dont le nom commence par les prfixes indiqus ici. Par dfaut, les utilisateurs ne pourront configurer que les variables denvironnement commenant par PHP_ (ex. : PHP_FOO=BAR). Si cette directive est vide, lutilisateur pourra modifier toutes les variables denvironnement !

86

Le fichier de configuration php.ini

Autres
safe_mode_protected_env_vars = LD_LIBRARY_PATH

Indiquez, en les sparant par une virgule, les variables denvironnement que lutilisateur final ne pourra pas modifier en utilisant putenv(). Ces variables seront protges, mme si la directive safe_mode_allowed_env_vars est configure pour que lon puisse les changer.

2. Prise en main

disable_functions =

Indiquez ici, spares par des virgules, les fonctions que vous souhaitez interdire pour des raisons de scurit. Lactivation ou non du mode scuris na aucune influence sur cette directive.
enable_dl = On

Activation ou non de la fonction dl() qui permet de charger des DLL la vole. Cette fonction ne marche pas correctement sur des serveurs multi-tches (multithread) comme, par exemple, IIS ou Zeus, et est automatiquement dsactive sur ces derniers.
cgi.force_redirect = 1
cgi.force_redirect est ncessaire pour apporter de la scurit si lon fait tourner PHP en

tant que CGI sous la plupart des serveurs web. Si vous laissez cette directive vide, PHP linterprtera comme active par dfaut. Il est tout fait dconseill de dsactiver cette directive (hormis sous IIS, pour lequel il vaut mieux lactiver).
cgi.redirect_status_env =

Si cgi.force_redirect est activ, et que vous ne vous trouvez pas sous un serveur Apache ou Netscape (iPlanet), vous devrez dterminer un nom de variable denvironnement que PHP interrogera afin de savoir sil peut ou non continuer lexcution. Ayez une ide prcise de ce que vous souhaitez faire avant de dterminer tout cela, la configuration de cette variable pouvant provoquer des problmes de scurit !
cgi.fix_pathinfo=0

Si cgi.fix_pathinfo est activ , PHP CGI corrigera son chemin pour se conformer aux spcifications. Si vous nactivez pas ce paramtre (en le laissant 0), PHP se comportera comme dans les versions antrieures. Il est conseill dutiliser SCRIPT FILENAME plutt que PATH TRANSLATION.
enable_dl = On

Gestion des erreurs et rcupration des messages derreur


error_reporting est un champ de bits. Vous pouvez dterminer quel type et quel niveau de rapport derreur vous souhaitez rcuprer.

E_ALL

87

Chapitre 2

Prise en main

Toutes les erreurs et avertissements.


E_ERROR

Erreurs fatales du programme.


E_WARNING

2. Prise en main

Avertissements du programme (qui ne sont pas des erreurs fatales).


E_PARSE

Erreurs danalyse lexicale la compilation.


E_NOTICE

Indications du programme. Ce sont des avertissements qui rsultent gnralement dun bug dans votre code, mais il se peut que ce soit intentionnel. Cest le cas, par exemple, si lon utilise une variable non initialise en considrant quelle sera automatiquement initialise par une chane vide.
E_STRICT

Permet PHP de vous indiquer des modifications dans votre code qui assureraient une meilleure inter-oprabilit et une meilleure compatibilit ascendante.
E_CORE_ERROR

Erreurs fatales survenant lors du dmarrage initial de PHP.


E_CORE_WARNING

Avertissements (qui ne sont pas des erreurs fatales) survenant lors du dmarrage initial de PHP.
E_COMPILE_ERROR

Erreur fatale la compilation.


E_COMPILE_WARNING

Avertissement derreur la compilation (qui ne sont pas des erreurs fatales).


E_USER_ERROR

Message derreur provoqu par lutilisateur.


E_USER_WARNING

Message davertissement provoqu par lutilisateur.


E_USER_NOTICE

Message dindication provoqu par lutilisateur. Exemples :


error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

88

Le fichier de configuration php.ini

Montrer toutes les erreurs, sauf les messages dindication et les messages de qualit de code.
error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR

Ne montrer que les erreurs.


display_errors = On

Active laffichage des erreurs. Pour un site de production, il est conseill de dsactiver cette fonction et dutiliser, sa place, error logging. Si vous gardez display_errors active, vous risquez de rvler des informations de scurit aux utilisateurs finals comme, par exemple, des chemins daccs de votre serveur web, le schma de votre base de donnes, ou dautres informations encore.
display_startup_errors = Off

2. Prise en main

Mme si display_errors est activ, les erreurs qui se produisent lors du dmarrage de PHP ne sont pas affiches. Il est fortement conseill de ne pas activer cette fonction, sauf pour du dbogage.
log_errors = Off

Permet de stocker les erreurs dans un fichier de logs. Sil sagit dun site de production, il est fortement conseill dutiliser cette directive au lieu de error_display.
track_errors = Off

Archive le dernier message derreur ou davertissement dans $php_errormsg.


html_errors = Off

Interdit linclusion de tags HTML dans les messages derreur. Nutilisez pas cette fonction sur des serveurs de production.
error_prepend_string = "<font color=ff0000>"

Chane intgrer avant un message derreur.


error_append_string = "</font>"

Chane intgrer aprs un message derreur.


error_log = filename

Placer les traces derreur dans un fichier particulier. Remplacez filename par le nom du fichier que vous voulez utiliser.
error_log = syslog

Placer les traces derreur dans syslog (Event Log sur Windows NT, non valide sous Windows 95).
define_syslog_variables = Off

Cette directive active ou dsactive la dfinition de diverses variables syslog comme, par exemple, les variables $LOG_PID, $LOG_CRON, etc. Il est conseill de dsactiver cette directive

89

Chapitre 2

Prise en main

dans un souci de performance. Vous pourrez dfinir ces variables dans le programme en faisant appel la fonction define_syslog_variables().
warn_plus_overloading = Off

Prvenir si loprateur + est utilis dans les chanes.

2. Prise en main

Gestion des chiers


Include
include_path =

Indique quels rpertoires doivent tre explors lorsquun fichier est inclus. Sous UNIX, il devra tre donn de cette faon : include_path = ".:/php/includes" et, sous Windows, de la faon suivante : include_path = "c:\php\includes". Vous pouvez en spcifier plusieurs, en les sparant par un deux points (:) sous Linux, et par un point-vigule (;) sous Windows, comme ceci : include_path = "c:\php\includes;c:\php\emma \includes".

Ouverture distante de chiers


allow_url_fopen = On

Active ou dsactive lautorisation de traitement des URL (comme http:// ou ftp://) en tant que fichiers.
from="john@doe.com"

Dfinit le mot de passe anonyme du FTP. Ici, une adresse e-mail sera demande.

Publication de chiers
file_uploads = On

Autorise (ou non) lupload de fichiers HTTP.


upload_tmp_dir =

Indiquez, si besoin, le rpertoire temporaire o vous souhaitez archiver les fichiers HTTP publis (uploads). Si vous ne remplissez pas ce champ, ils seront placs dans le rpertoire temporaire par dfaut du systme.
upload_max_filesize = 2M

Taille maximale autorise des fichiers en upload.

90

Le fichier de configuration php.ini

Gestion des donnes


Depuis PHP 4.0.3, track_vars est toujours activ.
arg_separator.output = "&amp;"

Le sparateur des arguments utilis dans les URL gnres par PHP est, par dfaut, &.
arg_separator.input = ";&"

2. Prise en main

Liste des caractres que doit dtecter PHP pour sparer les arguments dans les URL (par dfaut les caractres & et ;). Chaque caractre est considr, dans cette directive, comme un sparateur.
variables_order = "EGPCS"

Cette directive dcrit lordre dans lequel PHP enregistre les variables passes par les mthodes GET, POST ou Cookie, les variables denvironnement et les variables incluses (respectivement G, P, C, E et S). Cet enregistrement prend en compte les valeurs de gauche droite, les nouvelles valeurs prenant le pas sur les plus anciennes.
register_globals = Off

Cette directive vous permet de choisir si vous enregistrez les variables EGPCS comme des variables globales ou pas. Par mesure de scurit, il est prfrable de laisser ce paramtre Off.
register_long_arrays = On

Cette directive vous permet de continuer utiliser la mthode HTTP_GET_VAR . Si vous nutilisez pas cette mthode (en prfrant la mthode $_GET["Varaible"]), il est prfrable de ne pas activer la directive pour optimiser les performances.
register_argc_argv = On

Cette directive dfinit si PHP dclare les variables argv et argc (qui pourraient contenir les informations GET). Si vous nutilisez pas ces variables, vous pouvez dsactiver cette directive pour amliorer les performances.
post_max_size = 8M

Taille maximale des donnes POST que PHP acceptera.

Les magic quotes


Les magic quotes sont des directives qui vous permettent dchapper les caractres qui pourraient provoquer des erreurs dans votre code. Par exemple, une apostrophe, un slash, etc. dans une variable issue dun formulaire qui pourraient tre interprts comme une fin de chane ou autre caractre interprt par PHP :
<form action="recupere.php"> <input type="hidden" name="exemple" value="Laventure cest laventure !"> <input type="submit"> </form>

91

Chapitre 2

Prise en main

Puis, laide de ce script :


<?php echo $_GET["exemple"]; ?>

2. Prise en main

vous rcuprez les donnes contenues dans recupere.php. Si les magic quotes sont actives, vous obtenez ceci : L\aventure c\est l\aventure ! Sans les magic quotes, nous avons ceci :
<?php echo $_GET["exemple"]; ?>

Laventure cest laventure !


magic_quotes_gpc = On

Active les magic quotes pour les donnes entrantes GET, POST et Cookie.
magic_quotes_runtime = Off

Dsactive les magic quotes pour les donnes gnres par le programme (ex. : donnes SQL, donnes provenant des fonctions exec(), etc.).
magic_quotes_sybase = Off

Si cette directive est active, des apostrophes seront utilises en lieu et place des "backslashes" pour les magic quotes (style Sybase, cest--dire au lieu de \).

Sessions
session.save_handler = files

Il sert redfinir la manire dont seront gres les sessions. Par dfaut, les sessions sont enregistres dans des fichiers. Cest grce ces fichiers que PHP retrouvera les donnes dune session. Si vous souhaitez une gestion personnalise des sessions indiquez alors "user" (voir chapitre sur les sessions).
session.save_path = /tmp

Rpertoire par dfaut o stocker les sessions. Il vaut mieux viter que ce rpertoire soit lisible par tous, auquel cas la scurit du site pourrait tre compromise. Quelquun pourrait usurper lidentificateur dun autre. Par dfaut, il vaut /tmp. Il faut donc imprativement modifier ce paramtre pour pouvoir faire fonctionner les cookies sous Windows.
session.use_cookies = 1

Permet dindiquer si le gestionnaire de sessions doit utiliser un cookie chez le client pour mmoriser lidentifiant de session. Par dfaut lutilisation de cookies est active (valeur 1).

92

Le fichier de configuration php.ini

session.name = PHPSESSID

Nom de lidentifiant de la session. Il ne contient que des caractres alphanumriques.


session.auto_start = 0

Indique si une session doit automatiquement tre lance lors de la premire requte. Cette option est dsactive par dfaut (valeur 0).

2. Prise en main

session.cookie_lifetime = 0

Permet de dfinir la dure de vie du cookie de session (en secondes). La valeur 0 (par dfaut) signifie que le cookie doit tre effac la fermeture du navigateur.
session.cookie_path = /

Permet de dfinir le chemin utiliser par les cookies. Par dfaut, il est mis /.
session.cookie_domain =

Permet de dfinir le domaine sur lequel est restreint le cookie.


session.serialize_handler = php

Permet de dfinir le gestionnaire de la srialisation/dsrialisation. Les formats PHP et WDDX sont supports, WDDX ntant disponible que si PHP a t compil avec WDDX.
session.gc_probability = 1

Permet de dfinir la probabilit dexcution de gc (garbage collector) chaque requte. gc est le dispositif permettant de supprimer les sessions qui ne sont plus valides. Gnralement, les sessions sont enregistres sous forme de fichiers, et gc se charge de supprimer les fichiers prims. Par dfaut, gc est requis chaque appel (la valeur vaut 1).
session.gc_maxlifetime = 1440

Aprs ce laps de temps (en secondes), une donne sera considre comme prime et pouvant tre supprime par gc.
session.referer_check =

Permet de ne valider une session que si lutilisateur provient dun site en particulier (typiquement le vtre). Il suffit de renseigner tout ou partie du nom de domaine. Si cette chane de caractres est contenue dans le HTTP_REFERER fourni par le navigateur, ou si cette valeur retourne est vide, alors la session est valide. Par dfaut, cette chane de caractres est vide.
session.entropy_file =

Permet de dfinir le chemin vers un fichier externe qui sera utilis pour gnrer (de faon pseudo-alatoire) un identifiant de session. Dans le monde UNIX, il est possible de dfinir /dev/random ou encore /dev/urandom.
session.entropy_length = 0

Permet de dterminer le nombre doctets lus dans le fichier dclar par session .entropy_file. Par dfaut, celui-ci tant dsactiv, il vaut 0.

93

Chapitre 2

Prise en main

session.cache_limiter = nocache

Permet de dfinir len-tte de contrle du cache qui doit tre envoy avec chaque script gnr partir de variables de sessions. Il peut tre dfini comme none, nocache, private, private_no_exprire ou public.
session.cache_expire = 180

2. Prise en main

Permet de dfinir len-tte dfinissant la dure de validit (en minutes) dune page gnre partir de variables de sessions. Cette option na aucune influence si le contrle du cache a t mis nocache.
session.use_trans_sid = 1

Permet dindiquer si lidentifiant de session doit tre transmis de manire transparente de page en page (URL rewriting). (Pour les versions PHP<=4.1.1, cette option est utilisable uniquement si PHP a t compil avec loption --enable-trans-sid). Par dfaut, cette option est active.
session.hash_function = 0

Dfinit le format de hash. 0 pour MD5 (128 bits) ou 1 pour SHA-1 (160 bits)..
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"

Permet de dfinir quelles URL seront rcrites afin de transmettre lidentifiant de session, si loption session.use_trans_sid est active. Par dfaut, ce sont les tags a=href, area=href, frame=src, input=src, form=fakeentry.

Gnration du document
Cache et compression
output_buffering = Off

La mise en tampon (ou mmoire cache) vous permet de nenvoyer le document gnr quune fois le script termin. Cela permet notamment denvoyer des en-ttes (instructions de manipulation des sessions et des cookies y compris), mme aprs avoir commenc gnrer la page. Mais, en contrepartie, cela ralentit la couche de sortie de PHP. Si vous voulez limiter le tampon une certaine taille, vous pouvez spcifier une taille en octets la place du On (ex. : output_buffering=4096).
output_handler =

Cette option permet dappliquer une fonction (typiquement de compression) sur le document gnr avant de lenvoyer au client. Par exemple, si vous configurez output_handler vers ob_gzhanler, la sortie sera compresse pour les navigateurs qui supportent Gzip. Si vous entrez un nom de fonction pour output_handler, cela activera automatiquement la mise en cache des sorties.
zlib.output_compression = Off

94

Le fichier de configuration php.ini

Cette directive permet la compression des sorties laide de la bibliothque Zlib. Les valeurs que vous pouvez indiquer pour cette commande peuvent tre On, Off ou une taille spcifique de tampon utiliser pour la compression (la taille par dfaut est 4 Kb). Attention : output_handler doit tre vide si cette directive est active.
implicit_flush = Off

Implicit flush demande PHP de vider les tampons de sortie ds quun lment du document est gnr. Ceci est quivalent lappel de la fonction flush() aprs chaque commande echo() ou print() et aprs chaque bloc HTML. Si vous activez cette fonction, vous rduirez vos performances. Cette option est conseille dans des objectifs de dbogage.

2. Prise en main

lments par dfaut


auto_prepend_file =

Pour ajouter automatiquement un fichier avant un document PHP.


auto_append_file =

Pour ajouter automatiquement un fichier aprs un document PHP.


default_mimetype = "text/html" default_charset = "iso-8859-1"

Spcifie le type du document et lencodage. Sachant que depuis PHP 4.0b4, PHP envoie par dfaut un en-tte prcisant lencodage. Si vous ne voulez pas le prciser, vous devrez, ici, mettre une chane vide. Par dfaut, sil nest pas prcis ici, le type du document est text/html.

Gestion de laffichage
Nombres dcimaux
precision = 12

Indiquez le nombre de dcimales aprs la virgule que vous souhaitez afficher.

Source
Couleurs pour la coloration syntaxique de votre code. Indiquez les codes couleurs qui vous conviennent :
highlight.string = #CC0000

pour une chane de caractres ;


highlight.comment = #FF9900

pour un commentaire ;
highlight.keyword = #006600

95

Chapitre 2

Prise en main

pour un mot-cl ;
highlight.bg = #FFFFFF

pour le fond ;
highlight.default = #0000CC

2. Prise en main

par dfaut ;
highlight.html = #000000

pour le html.

Extensions dynamiques
extension_dir = ./

Indiquez le chemin du rpertoire dans lequel se trouvent les extensions (modules) chargeables. Si vous souhaitez quune extension soit charge automatiquement, utilisez la syntaxe suivante :
extension=modulename.extension

Par exemple, pour Windows :


extension=php_gd.dll

ou, sous UNIX :


extension=php_gd.so

Notez que vous ne devez indiquer que le nom du module, et non pas les informations concernant le chemin du rpertoire (ce dernier doit obligatoirement tre celui spcifi par extension_dir).

Conguration des extensions


BcMath
bcmath.scale = 0

Prcision avec laquelle BcMath doit travailler (nombre de chiffres aprs la virgule souhaits).

Bases de donnes
sql.safe_mode = Off

Active ou non le mode scuris pour les bases de donnes. Il existe de nombreux autres paramtres pour les bases de donnes. Ceux-ci seront voqus dans les chapitres correspondants.

96

Les diteurs et dbogueurs PHP

Sockets
sockets.use_system_read = On

Utilise la fonction systme read() au lieu de la fonction programme php_read().

Divers
Browscap
browscap = extra/browscap.ini

2. Prise en main

Chemin vers le fichier browscap.ini contenant les informations qui permettent de dduire les caractristiques des navigateurs daprs leur HTTP_USER_AGENT.

2.3.

Les diteurs et dbogueurs PHP

Dans le monde de la programmation, les diteurs de texte font office de religions. On en utilise un comme on choisit une glise. Comme les religions, les diteurs connaissent leurs guerres. Lune des plus clbres oppose les partisans de Vi aux zlateurs dEmacs. Tout a t dit : "Emacs rend beau", "Vi fait repousser les cheveux", etc. En cherchant bien, on peut mme trouver sur le Web un mmo sur les diffrents diteurs de texte, rdig pour une universit canadienne, commenant par cette citation : "Papa, pourquoi nous cachons-nous de la police ? - Ils utilisent Emacs, fils, et nous utilisons Vi." Les adeptes dun diteur en particulier ressentent, gnralement, le besoin de prouver que le leur est le meilleur, le plus beau, le plus complet. Cela entrane immanquablement de folles discussions fort peu constructives, mais folkloriques, voire divertissantes. Mais le dbutant en qute de conseils ne sy retrouve pas pour autant. On peut tout de mme regrouper les diteurs en diffrentes grandes familles, pour ensuite comparer leurs avantages et inconvnients respectifs. Il nest pas opportun de comparer Emacs Dreamweaver MX. En revanche, mettre face face PHPEdit et Komodo prsente un intrt. Sur le CD-ROM, vous trouverez un tableau comparatif des diffrents diteurs ainsi que quelques fiches descriptives. Les gots et attentes de chacun interviennent beaucoup dans le choix dun diteur. Le contexte de dveloppement de PHP joue galement. Si cest pour un projet isol, le programmeur pourra choisir librement ; si, en revanche, il doit travailler en troite collaboration avec un graphiste, un logiciel comme Dreamweaver MX sera plus appropri. Pour mettre sur pied une architecture complexe imbriquant de multiples pages en PHP, une solution comme Zend Studio ou Maguma rendra de bien meilleurs services. Les outils les plus puissants ne doivent pas faire oublier quun site peut tre dvelopp avec un simple bloc-note (bien moins gourmand en mmoire et CPU). Ce nest pas lditeur qui fait le dveloppeur. Les assistants les plus pousss et conviviaux ne remplaceront pas une bonne connaissance du langage.

97

Chapitre 2

Prise en main

Nous avons class les diteurs en diffrentes catgories. Nous savons que ces catgories seront coup sr critiques par les partisans de lun ou lautre des logiciels prsents, mais cest un mal ncessaire
j

2. Prise en main

Lartillerie lourde, ce sont ces diteurs qui intgrent PHP toute une solution de dveloppement web. Rsolument tourns vers PHP, il leur faut une plateforme assez muscle pour fonctionner, et ils nont pas t penss pour le dveloppeur solitaire, coinc entre pizza et CVS. Ils permettent souvent un travail collaboratif pouss, qui place lditeur au centre dune architecture incluant un serveur web et un serveur de bases de donnes. Leur prix souvent lev les met hors de la porte des programmeurs isols. Les spcialistes, ce sont des diteurs PHP purement PHP. Ils ont t dvelopps pour ce langage de script en particulier. tant donn quils sont assez nombreux, nous ne prsentons ici que ceux que nous avons jugs pertinents en fonction de critres jugs primordiaux par plusieurs dveloppeurs. Nous traitons enfin, dans une partie spare, Dreamweaver et GoLive, deux logiciels de cration de sites web qui grent dsormais PHP, mais qui restent tout de mme en de de ce quoffrent les diteurs spcialiss.

Nos plus vifs remerciements vont Stphane Pineau, auteur dun comparatif dditeurs PHP, qui nous a permis de reproduire ici en grande partie son travail (par ailleurs disponible ladresse http://steph.pineau.free.fr/php/index.php?LNK=EDIT/). Nous vous conseillons dailleurs daller consulter cette page rgulirement pour vous tenir jour des dernires mises jour dditeurs. Vous pourrez galement y effecuter des recherches multicritres pour choisir lditeur qui vous convient le plus.

Lartillerie lourde
Zend Studio

Figure 2.23 : Zend Studio

98

Les diteurs et dbogueurs PHP

Tableau 2.1 : Zend Studio


Zend Studio diteur Langues Plateformes Langages supports Prix URL version 3.5.1 Zend Technologies Ltd. Anglais, allemand, franais, hollandais, espagnol, italien, coren. Windows, Linux, MacOSX. PHP, HTML. 249 $US.
www.zend.com

2. Prise en main

Principales fonctionnalits et commentaire Lditeur offre toutes les fonctions de base ncessaires : compltion du code PHP et HTML, compltion galement pour les variables, liste des fonctions disponibles dans un fichier, visualisation des fichiers en includes, coloration syntaxique, dition du mme fichier depuis diffrentes fentres, dition de fichiers depuis un serveur FTP, etc. Le dbogage est possible en local, et galement en direct sur des serveurs distants. Cela permet ainsi de contrler lexcution de PHP sur les serveurs de production. Le dbogueur intgr est particulirement performant. La suite Zend inclut galement un centre dadministration pour configurer et administrer les serveurs, ainsi quune application daide complte et fonctionnelle. On remarque aussi la prsence du Zend Optimizer, logiciel optimisant le code PHP et permettant lexcution de code camoufl (obfusqu). Il supporte la version 5 de PHP. Au rang des dernires nouveauts, on trouve les templates de code, personnalisation des schmas de coloration, dbogage actif ou passif, transmission scurise des fichiers (publication par SFTP et FTP sur SSH). Certainement lune des solutions les plus abouties et les plus compltes pour la cration dapplications en PHP.

Maguma Studio

Figure 2.24 : Maguma Studio

99

Chapitre 2

Prise en main

Tableau 2.2 : Maguma Studio


Maguma Studio diteur Langue OS Langage support Prix URL version 1.3.2 Maguma. Anglais. Windows. PHP. 69 5 pour lditeur. Existe une version gratuite limite.
www.maguma.com

2. Prise en main

Principales fonctionnalits et commentaire La plateforme Maguma intgre, en plus dun diteur puissant, toute une architecture de travail en commun, allant du client au serveur en passant par une interface dadministration gnrale. Lditeur offre la numrotation des lignes, la coloration syntaxique, une dition multi-fichiers, une aide PHP intgre, une aide MySQL intgre, une aide HTML intgre, un gestionnaire de fichiers, un gestionnaire FTP, un visualiseur HTML interne, une visualisation/excution depuis lditeur, un dbogueur interne ou externe, un explorateur de code PHP, linsertion assiste de code HTML, linsertion assiste de code CSS, linsertion assiste de code PHP, lauto-compltion PHP, la gestion des abrviations (code template), le commentaire des fonctions/classes, la recherche des paires []{}() et le RegExp en mode recherche.

NuSphere PHPEd

Figure 2.25 : NuSphere PHPEd

100

Les diteurs et dbogueurs PHP

Tableau 2.3 : NuSphere PHPEd


NuSphere PHPEd diteur Langue Plateformes Langages supports Prix URL version 3.3 NuSphere. Anglais. Windows, Linux, Solaris PHP, HTML. 299 $US.
www.nusphere.com/products/phpadv.htm

2. Prise en main

Principales fonctionnalits et commentaire Ajout de code depuis des modles, dbogueur de code, interfaage avec des serveurs de bases de donnes (support en natif de PostgreSQL), gestion de projets, connexion en FTP, FTPS, WebDAV/HTTPS, gestion du travail en quipe, dbogage de sessions, optimisation du code, etc. PhpED offre une compltion automatique du code qui supporte la programmation oriente objet. Le "PHP Profiler" intgr vous aide dans votre dveloppement et permet de constater sa progression et loptimisation de son code. Des fonctionnalits originales pour une solution vraiment complte.

Les spcialistes
Tous les diteurs prsents ici ont un dbogueur intgr, lexception de Jext qui compense ce manque par une kyrielle de fonctionnalits et dadd-on.

Komodo

Figure 2.26 : Komodo

101

Chapitre 2

Prise en main

Tableau 2.4 : Komodo


Komodo diteur Langue Plateformes Langages supports Prix version 3 ActiveState. Anglais. Windows et Linux. C, C++, Diff, Eiffel, HTML, Java, Javascript, Latex, Lisp, PHP, Pascal, Perl, Python, tcl, vb, XML, XLT, etc. La version 1.1 est gratuite dans le cadre dune utilisation en milieu enseignant, ou vise ducative. La version 1.2 est tlchargeable en valuation pour 21 jours, puis payante. De 29,5 $US 296 $US selon les types de licences.
www.activestate.com/Products/Komodo/

2. Prise en main

URL

Principales fonctionnalits et commentaire Numrotation des lignes, coloration syntaxique, multi-fichiers, aide PHP intgre, aide MySQL intgre, aide HTML intgre, gestionnaire de projets, gestionnaire de fichiers, gestionnaire de favoris, gestionnaire FTP, liste de "reste faire" (todo), rechargement automatique des derniers fichiers, visualiseur HTML interne, visualisation/excution depuis lditeur, dbogueur interne ou externe, macros, explorateur de code PHP, explorateur de code HTML, insertion assiste de code HTML, insertion assiste de code CSS, insertion assiste de code JavaScript, insertion assiste de code PHP, insertion code template, auto-compltion PHP, gestion des abrviations (code template), commentaire des fonctions/classes, recherche des paires []{}(), indentation / dsindentation de blocs, commentaire de blocs, partage de la fentre ddition, RegExp en mode recherche, archivage des fichiers/projets, slecteur de couleurs. Dvelopp autour du navigateur Mozilla auquel il sintgre et de lditeur Scintilla. Un petit module permet de tester ses expressions rgulires avec visualisation du rsultat en temps rel. Possibilit de cacher le code des classes, fonctions et blocs (outlining). "Debug" pour Perl, Python, PHP et XSLT. Affichage des paramtres requis lors de lutilisation dune fonction. Rechargement des derniers fichiers, gestionnaire FTP. La version comporte son lot damliorations et dajouts de fonctionnalits (dont le support de PHP5). La liste des nouveauts est consultable cette adresse : http://aspn.activestate.com/ASPN/docs/Komodo/3.0/relnotes.html#New_Features.

102

Les diteurs et dbogueurs PHP

PhpCoder

2. Prise en main

Figure 2.27 : PhpCoder

Tableau 2.5 : PhpCoder


PhpCoder diteur Langue Plateforme Langage support Prix URL version R2 Prerealese 3 phpIDE.de. Anglais. Windows. PHP. Gratuit.
www.phpide.de

Principales fonctionnalits et commentaire Numrotation des lignes, coloration syntaxique, multi-fichiers, aide PHP intgre, aide MySQL intgre, gestionnaire de projets, visualiseur HTML interne, visualisation/excution depuis lditeur, dbogueur interne ou externe, insertion assiste de code HTML, lauto-compltion PHP. Un clone de PHPEd quasi conforme, mais qui ncessite encore quelques amliorations.

103

Chapitre 2

Prise en main

PHPEdit

2. Prise en main

Figure 2.28 : PHPEdit

Tableau 2.6 : PHPEdit


PHPEdit diteurs Langue Plateforme Langage support Prix URL Version 1.0.3.68 Waterproof SARL Anglais, franais, allemand, espagnol. Windows et Linux. PHP. Gratuit pour une utilisation personnelle, version professionnelle 75 5 HT (Open Source).
www.phpedit.com

Principales fonctionnalits et commentaire Rest longtemps la version 0.6, PHPEdit a tenu ses promesses et combl ses lacunes de jeunesse. Il est disponible en franais avec une documentation complte et de trs nombreuses fonctionnalits. Les dernires versions ont apport un gnrateur daide, des raccourcis personnalisables, plus de 100 commandes scriptables, le mappage de clavier personnel, un gestionnaire de todo. Lditeur offre galement : numrotation des lignes, coloration syntaxique, multi-fichiers, aide PHP intgre, aide MySQL intgre, aide HTML intgre, gestionnaire de fichiers, visualisation/excution depuis lditeur,

104

Les diteurs et dbogueurs PHP

PHPEdit

Version 1.0.3.68

dbogueur interne ou externe, explorateur de code PHP, insertion assiste de code PHP, gestion des abrviations (code template), commentaire des fonctions/classes, indentation/dsindentation de blocs, commentaire de blocs, RegExp en mode recherche Lexplorateur de code est excellent ; il spare bien les fonctions et classes de chaque fichier, et hirarchise correctement les mthodes des classes. Apprciable galement : la fonction dautocomment des classes et fonctions. Le systme dinsertion assiste de code PHP, similaire celui du VBA, est agrable (plus que celui de PHPEd), et laffichage des paramtres requis dune fonction native par simple placement du curseur entre parenthses est vraiment pratique. On apprcie galement la possibilit dimprimer avec les numros de lignes et la mise en valeur des mots-cls. Un petit gestionnaire de copier/coller fonctionnant en drag and drop est intressant. Sil tait possible de lintgrer en tant que panneau latral plutt que de le laisser en fentre libre, ce serait encore plus pratique. Dommage quaucun choix de langue ne soit propos, dautant quil sagit dune production franaise. Labsence de toute documentation est vraiment pnible, car nombre de petits gadgets assez droutants de prime abord mriteraient une aide un peu plus substantielle.

2. Prise en main

SciTE

Figure 2.29 : SciTE

105

Chapitre 2

Prise en main

Tableau 2.7 : SciTe


SciTE diteur Langues Plateformes Langages supports Prix URL version 1.61 Neil Hodgson. Anglais, Franais, Allemand. Windows et Linux. C, C++, C#, Eiffel, Java, Js, Latex, Lisp, Pascal, Perl, Php, Python, Sql, Vbscript, XML, etc. Gratuit (Open Source).
www.scintilla.org

2. Prise en main

Principales fonctionnalits et commentaire Numrotation des lignes, coloration syntaxique, multi-fichiers, gestionnaire de projets, rechargement automatique des derniers fichiers, visualisation/excution depuis lditeur, dbogueur interne ou externe, macros, insertion assiste de code PHP, auto-compltion PHP, gestion des abrviations (code template), recherche des paires []{}(), commentaire de blocs, RegExp en mode recherche. Lditeur offre galement la recherche dans des fichiers non ouverts. Peut se placer en mode rduit dans la barre des tches. Il ne pse que 500 Ko avec sa DLL. On peut zoomer et dzoomer du code en cours ddition. Permet de masquer laffichage (outlining) logique des blocs dun texte (HTML) ou dun script. On peut donc masquer le corps des fonctions (dun bloc If/end, par exemple) dun simple clic (ou par [Ctrl]+[*]). On peut ainsi obtenir le squelette dun script en naffichant plus que le nom des classes, les fonctions et les commentaires. Il est galement possible deffectuer une inversion rapide des lignes (ligne courante avant la suivante). Lditeur se configure via des fichiers, ce qui est un peu lourd. La configuration par dfaut est plutt restreinte ; nombre de possibilits ne sont pas visibles de prime abord. Les fichiers pour le franais ne sont pas inclus dans larchive, mais on peut les rcuprer sur : www.scintilla.org/locale.fr.properties. Le chargement en mmoire est quasi instantan sur un PIII 533 MHz, ce qui est loin dtre le cas de bien des diteurs. On ne trouve pas de macros ni de gestion de projets en natif, mais ce manque est compens par un add-on FilerX. Il nexiste pas dexplorateur de code. Trop de fonctions intressantes sont dsactives par dfaut. Lisez bien la documentation pour connatre toutes les possibilits de paramtrage. Cest vraiment lditeur ne pas manquer pour sa lgret et sa puissance, dautant que les sources fournies (projet Scintilla) permettent de greffer ses propres fonctions. Cest dailleurs lditeur qui est intgr dans Komodo. Voici quelques "trucs" pour activer des fonctions intressantes. Pour activer loutlining, il faut dcommenter la ligne fold.html=1 dans le fichier html.properties, et la ligne fold=1 dans le fichier sciteglobal.properties. Dans ce dernier, vous pouvez galement mettre la valeur 0 la ligne fold.symbol. Pour afficher les numros de lignes, il faut dcommenter la ligne line.number dans le fichier sciteglobal.properties, et lui mettre une valeur de 30. Pour pouvoir ouvrir plusieurs fichiers, il faut dcommenter la ligne buffers dans le fichier sciteglobal.properties, et lui mettre la valeur de 10 par exemple.

106

Les diteurs et dbogueurs PHP

Jext

2. Prise en main

Figure 2.30 : Jext

Tableau 2.8 : Jext


Jext diteur. Langues. Plateformes Langages supports Prix URL version 5 Romain Guy. Franais, anglais. Java (multi-plateforme). Ncessite JRE 1.301 ou JDK 1.2. PHP, ASM, ASP, C, C#, C++, Eiffel, HTML, XML, Java, Perl, Python, Sql, Shell scripts, etc. Gratuit (OpenSource).
www.jext.org

Principales fonctionnalits et commentaire Numrotation des lignes, coloration syntaxique, multi-fichiers, gestionnaire de projets (add-on), gestionnaire de fichiers, gestionnaire de favoris, gestionnaire FTP (add-on), rechargement automatique des derniers fichiers, explorateur de code PHP, insertion assiste de code HTML, insertion assiste de code PHP, auto-compltion PHP, gestion des abrviations (code template), recherche des paires []{}(), indentation/dsindentation de blocs, commentaire de blocs, RegExp en mode recherche.

107

Chapitre 2

Prise en main

Jext

version 5

Avec ses add-on, cet diteur est particulirement intressant. Il offre ainsi un systme de bureau, cest--dire une liste de fichiers ouverts faisant partie, par exemple, dun mme programme. Il est possible de crer plusieurs bureaux, et donc de disposer dun gestionnaire de projets basique mais efficace. Un add-on "Wapppaaa" permet douvrir en une opration lensemble des fichiers contenus dans un rpertoire et ses sous-rpertoires. Ladd-on Xinsert permet de grer ses code template de manire hirarchique, et cela pour chaque langage voulu. Il autorise linclusion automatique du texte slectionn dans le template choisi. Ladd-on FindAll permet, en double-cliquant sur un mot, et en appuyant sur [Ctrl] + [F3], dobtenir toutes ses occurences dans une liste slectionnable ; cest trs utile pour trouver les occurrences dune variable ou dune fonction. Les recherches sont, de plus, mmorises. Ladd-on ProjectMaster remplacera utilement le gestionnaire de projets CodeMaster fourni par dfaut, car il sintgre directement dans le panneau latral. Bien que plutt ax Java, il peut tre utilis en PHP. Jext dispose dun langage de script intgr, Dawn. On apprciera galement le systme One Clic : il suffit de slectionner une commande de ce menu, par exemple Ajouter un commentaire simple, puis de cliquer sur chaque ligne que lon veut commenter, et cest tout. La commande slectionne sapplique chaque ligne clique tant que loption One Click nest pas arrte. Ladd-on Code2Html transforme le fichier en cours (ou la slection) en fichier HTML, tout en conservant la coloration syntaxique. Idal pour publier le code source dun langage quelconque de manire attrayante. De nombreux autres add-on sont disponibles : console systme, skins, impression avec numros de lignes, tri de lignes... En bref : cest un excellent diteur. Il nest pas inutile de lire la documentation (en franais ou en anglais) pour tirer parti de toutes ses possibilits.

2. Prise en main

Le choix des auteurs titre purement indicatif, les auteurs de cette Bible utilisent, par ordre de pagaille : Vi, Emacs, Nedit, Wordpad, le bloc-notes ou encore UltraEdit pour programmer en PHP. Vous le voyez, aucun diteur spcialis... Comme quoi, ce nest (dcidment !) vraiment pas lditeur qui fait le dveloppeur.

Dreamweaver et GoLive
Au dpart, ce sont des outils de cration de sites web destins aux graphistes et webmestres Aujourdhui, et tout particulirement dans les dernires versions, les deux diteurs supportent particulirement bien PHP. On peut, par exemple, facilement crer des pages contenant des objets en PHP en puisant dans des bibliothques prtes lemploi. Les deux diteurs ont intgr le travail avec des bases de donnes (GoLive est vendu avec Apache, PHP, JSP et MySQL). Sans aller jusquau serveur de dbogage de Zend, installer directement sur les machines de production, Dreamweaver et GoLive ont dpass le simple stade du "wysiwyg" (what you see is what you get ou, vous voyez ce que vous avez). Les deux logiciels disposent dune composante de travail collaboratif. Il est mme possible de travailler avec Webdav, ou mme davoir une gestion centralise du code source. Lintrt des logiciels de cration de sites web dans le cadre dun dveloppement en PHP reste limit. Si une page contient uniquement un dveloppement original en PHP, il sera inutile daller lditer dans Dreamweaver. De mme, quel intrt peut-il y avoir dvelopper toute une application en PHP dans un logiciel comme GoLive, largement plus performant dans le Webdesign ?

108

Les diteurs et dbogueurs PHP

Dans une optique PHP, Dreamweaver et GoLive restent de trs bons outils dintgration finale et dhabillage des dveloppements en PHP. Un meilleur support de PHP reste un point positif. Cela signifie, par exemple, quun graphiste aura plus de souplesse pour travailler une page contenant du code PHP.

Quelques site dditeurs Document traitant des diteurs, rdig pour luniversit McGill au Canada :
www.cs.mcgill.ca/~navindra/editors/

2. Prise en main

Vi :
http://vim.sourceforge.net/

Emacs :
www.gnu.org/software/emacs/emacs.html

UltraEdit :
www.ultraedit.com/

Pages personnelles de Stphane Pineau Dictionnaire francophone des acronymes informatiques :


www.teaser.fr/~spineau/acrodict/index.htm

Script PHP 3 gratuits (forum, gestionnaires BDD, etc.) :


http://steph.pineau.free.fr/php/index.php3

109

Chapitre 3

Le langage PHP
3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 Intgrer le code PHP au HTML Les commentaires . . . . . . . . Les constantes . . . . . . . . . . Les variables . . . . . . . . . . . Les oprateurs . . . . . . . . . . Les structures de contrle . . . Les fonctions . . . . . . . . . . . Les tableaux . . . . . . . . . . . . Les inclusions de chiers . . . Les classes, les objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 116 117 118 140 148 158 174 206 216

Intgrer le code PHP au HTML

3.1.

Intgrer le code PHP au HTML

Comme cela a dj t dit dans lintroduction, le langage PHP est un langage de script qui sinsre dans des pages HTML, et les parties crites en langage PHP sont dclares au moyen de balises reconnues par le serveur. Le code PHP scrit donc avec un diteur de texte et lutilisation des diteurs "wysiwyg" (what you see is what you get) sarrte lorsque lcriture du langage PHP commence.

Vous pouvez vous reporter la section "Les diteurs" pour choisir le vtre. 3. Le langage PHP

Le principe de fonctionnement de PHP est assez simple : le serveur va effectuer un travail dinterprtation avant de retourner le rsultat (gnralement une page HTML) au client (classiquement un navigateur Internet). Lavantage par rapport lHTML est alors considrable, puisquil est ainsi possible de concevoir des sites dits dynamiques. Cest--dire que, dune fois sur lautre, une page peut changer de contenu sans quaucune intervention humaine ne soit ncessaire. Prenons le cas dun forum : il est souhaitable que, ds quune personne soumet une question, celle-ci soit disponible sur le site. Cest un cas typique dutilisation dun site Internet dynamique. Le langage PHP permettra alors de crer une page HTML partir de ce message (et des autres messages disponibles dans la base de donnes). Il faut toujours garder lesprit que cest un langage de script qui est excut ct du serveur ; il ne dpend donc ni du navigateur ni du systme dexploitation du visiteur. Lavantage est indniable puisque ce langage permet, partir dinformations de nature diffrente, (base de donnes, heure actuelle, configuration du client, etc.) denvoyer des pages dont on peut tre sr quelles seront comprhensibles par le navigateur du client ( condition de programmer proprement).

Les balises
Les parties correspondant au code PHP sont dclares au moyen de balises. Il existe plusieurs types de balises en fonction de vos prfrences, habitudes, et de la configuration de PHP sur le serveur ou tournera vos scripts. Il existe quatre diffrents types de balises regroups dans le tableau ci-aprs :

Tableau 3.1 : Les diffrentes balises


Balise <?php ?> <script language="php"> </script> Remarque Ce type de balise est le plus courant. Il est accept par dfaut par linterprteur. Ce type de balise est galement accept par dfaut par linterprteur.

113

Chapitre 3

Le langage PHP

Balise <? ?> <% %>

Remarque Ces balises courtes sont appeles short tags. Elles ne sont pas acceptes par dfaut, cela fait partie de la configuration de PHP. Ces balises sont l pour obtenir les mmes balises que pour lASP. Elles ne sont pas acceptes par dfaut, cela fait partie de la configuration de PHP.

3. Le langage PHP

Vous pouvez vous reporter au chapitre "Prise en main" afin de voir comment configurer PHP pour utiliser les balises qui vous serviront.
Pour ceux qui veulent en crire le moins possible, il existe aussi deux autres types de balises qui ont pour effet de simplifier la syntaxe lorsque vous souhaitez simplement afficher du texte avec la commande echo. Ainsi <? echo "toto" ?> peut tre avantageusement remplac par <?= "toto" ?> et <% echo "toto" %> par <%= "toto" %>.

Ne vous loignez pas des balises... standard Si vous crivez vos premiers scripts, utilisez le premier type de balises (<?php ?>). En effet, celui-ci est compris de lensemble des serveurs, car il ne dpend pas de leur configuration. Le troisime est le type pour fainants, mais peut se retourner contre vous car, si vous ne pouvez pas accder la configuration du serveur aprs en avoir chang, il vous faudra modifier toutes les balises ! De mme, il ne faut pas oublier que, si vous voulez distribuer votre script, il vous faut un script qui fonctionne sur nimporte quel serveur muni de PHP.

Mon premier script


Le premier script PHP est un grand classique ; il ne fait quafficher une phrase.
<html> <head> <title>Mon premier script</title> </head> <body> <?php echo "Mon premier script qui naffiche que du texte en attendant mieux..."; ?> </body> </html>

114

Intgrer le code PHP au HTML

Ici, lintrieur dun script HTML classique, on a insr des balises PHP dans lesquelles on a plac une seule instruction, echo, qui affiche simplement la chane de caractres qui suit. Le sparateur dinstructions est classiquement le point-virgule ; il peut tre omis aprs la dernire instruction dun bloc PHP (ici, en loccurrence, il aurait pu tre omis). Ce fichier, qui sera stock sur le serveur, va tre interprt puis envoy au client (le navigateur Internet du visiteur) quand celui-ci y fera appel.

3. Le langage PHP

Figure 3.1 : Ce que verra le visiteur

Comme nous pouvons le constater en rclamant le code source du document reu, le rsultat de linterprtation ne laisse plus apparatre de code PHP.

Figure 3.2 : Le code source reu par le client

Les balises PHP peuvent tre places nimporte o dans le script ; le script suivant donnera le mme rsultat :
<html> <head> <title>Mon premier script</title> </head> <body> <?php echo "Mon premier script" ?> qui naffiche <?php echo "que du texte en attendant mieux..."; ?> </body> </html>

Dans le cas prsent, lutilit nest pas flagrante, mais nous verrons des cas dapplications lorsque nous tudierons les boucles de contrle.

115

Chapitre 3

Le langage PHP

3. Le langage PHP

Client-serveur Il faut bien comprendre la logique client/serveur : dun ct le serveur est charg dinterprter le code PHP et denvoyer au client (le navigateur Internet du visiteur) le rsultat de linterprtation. De lautre, le client se contente dafficher la page correspondant au code source envoy. Il nest donc pas question de demander PHP dagir sur le client. Vous ne trouverez, par exemple, aucune fonction permettant de suivre le dplacement de la souris, et toute modification du contenu de la page passe ncessairement par une nouvelle interrogation du serveur (i.e. affichage dune nouvelle page ou, ventuellement, raffichage de la page avec de nouveaux paramtres). En contrepartie, le client na pas interprter PHP, ce qui implique que la machine na pas besoin doutils spcifiques, ni de beaucoup de ressources : cest le serveur qui fait tout le travail !

3.2.

Les commentaires

Pour commenter ses scripts et permettre ainsi de les rendre plus clairs, il existe trois faons de faire :

Tableau 3.2 : Les diffrentes faons dinsrer des commentaires


Notation # commentaire // commentaire /* commentaire */ Remarque Le texte entre le signe # et la fin de la ligne sera en commentaire. Cette faon de noter est celle des scripts shell. Le texte entre // et la fin de la ligne sera en commentaire. Tout le texte entre /* et */ sera en commentaire.

Listing 3.1 : Exemple de script avec commentaires


<?php echo "Ligne suivi dun commentaire"; # commentaire faon shell echo "Ligne suivi dun commentaire";// commentaire faon C /* commentaire sur plusieurs lignes */ echo "Ligne entre 2 blocs de commentaires"; /* commentaire * sur * plusieurs

116

Les constantes

* lignes * plus lisibles */ /* cette partie est commente // ce type de commentaire bien quinutile ici est valable # celui ci aussi peut tre imbriqu */ ?>

Un petit commentaire ? Les commentaires sont importants pour sy retrouver ; ils le sont plus encore quand vous relisez un script qui date de plusieurs mois. Mais cela na rien de nouveau et est valable pour nimporte quel langage Privilgiez lutilisation des // et /* */ et vitez #.

3. Le langage PHP

Ne pas imbriquer les commentaires /* */ Vous ne pouvez pas placer */ lintrieur dun commentaire entre /* et */. Par exemple, le script suivant provoquera une erreur :
<?php /* je mets des remarques parce que je le veux bien /* jaime tellement les remarques que je les imbrique */ */ ?>

Au moment de linterprtation, les commentaires sont supprims ; ils ne sont donc pas envoys au client, et, ainsi, ne ralentissent en rien lenvoi de la page. Encore une bonne raison pour user et abuser des commentaires

3.3.

Les constantes

PHP permet de dfinir des constantes, autrement dit des chanes de caractres reprsentant une valeur fige (chane de caractres, nombre ou boolen). Les constantes se dclarent par linstruction define(). Ainsi,
define("LANGAGE", "PHP"); define("VERSION", 4);

cre deux constantes, LANGAGE et VERSION, qui peuvent tre utilises trs naturellement ;
echo LANGAGE." ".VERSION;

117

Chapitre 3

Le langage PHP

retournera ainsi PHP 4 Outre les constantes que vous pourrez dfinir, PHP propose ses propres constantes dont :
j j j
PHP_VERSION qui contient le numro de version de PHP (ex. : "4.3.2"). PHP_OS qui contient le nom du systme dexploitation sous lequel PHP tourne ("Linux", "WINNT", "WIN32", "HP-UX", "AIX", etc.). __FILE__ qui contient le chemin complet du script actuellement lu (sil sagit dun script inclus, cest donc bien le chemin complet du script qui est retourn et non celui du script appel). __LINE__ qui contient le numro de la ligne actuellement excute.

3. Le langage PHP

Existent aussi les constantes TRUE (vrai) et FALSE (faux) et les constantes de niveau derreur que nous prsenterons plus loin.

Les constantes sont accessibles depuis nimporte quel endroit du code, y compris lintrieur des fonctions. Voir ce sujet la section concernant "les fonctions" et la porte des variables.

3.4.

Les variables

Dnition et syntaxe
Les variables sont destines stocker les donnes qui seront utilises et pourront tre modifies lors de lexcution du programme. Le langage PHP, tout comme le langage Perl, utilise une forme particulire de syntaxe pour dfinir une variable. Les variables sont reprsentes avec un caractre $ prfixant lidentification de cette variable. Par exemple, pour dclarer une nouvelle variable de nom "maVariable", il suffit de lappeler $maVariable lintrieur du code source. Contrairement au langage comme le C, PHP nexige pas la dclaration pralable des identificateurs avant leur utilisation. Les variables sont donc dites non types, cest--dire quune variable peut prendre une valeur de chane de caractres et, ensuite, tre utilise pour contenir un entier. Le type est dfini laffectation de cette variable. Cest en partie cette grande souplesse dutilisation qui fait de PHP un langage simple et rapide daccs. Dans lexemple ci-dessous, vous pouvez constater la simplicit dutilisation des variables :
<?php $maVariable = "0"; // $maVariable est une chane de caractres $maVariable = $maVariable + 1; echo $maVariable; // Renvoie "1" et est maintenant un entier

118

Les variables

$maVariable = 1; // $maVariable est present un entier $maVariable = $maVariable / 2; // $maVariable est maintenant du type double $maVariable = 1 + "2 Vive le PHP !"; echo $maVariable; // $maVariable est du type entier et renvoie 3 ?>

Le nom de la variable peut tre dfini par tous les caractres alphanumriques ainsi que par le caractre _ , mais il ne peut pas commencer par un chiffre.
$maVariable, $_maVariable, $maVariable1 sont des variables correctes. En revanche, $1maVariable provoquera une erreur de syntaxe.

3. Le langage PHP

Faites chauffer la colle (attention la casse) Les variables dfinies dans un programme PHP sont sensibles la casse. Faites donc attention, dans vos programmes, ne pas initialiser $maVariable et appeler $MAVARIABLE lutilisation. Ces deux variables sont distinctes.

Les variables dynamiques


Les variables dynamiques (aussi appeles variables "variables") sont des variables dont le nom dpend dautres variables. Les noms de ces variables sont donc construits dynamiquement pendant lexcution du code PHP. Lexemple ci-dessous est bien plus parlant quun long discours :
<?php $var = "Je dveloppe en PHP."; $dyn = "var"; echo $$dyn; // Affiche "Je dveloppe en PHP."; ?>

Ainsi, en crivant simplement $$dyn on rcupre la valeur de la variable dont le nom est contenu dans $dyn, cest--dire $var. Le recours aux variables dynamiques nest gnralement pas ncessaire, car elles peuvent, bien souvent, tre avantageusement remplaces par lutilisation de tableaux, mais qui sait... il est possible que cela vous dpanne un jour ! Il est souvent prfrable, et parfois indispensable, de mettre le nom des variables entre accolades. Cela vous permettra, par exemple, de crer un nom de variable avec une partie variable et une partie fixe, comme cest le cas dans lexemple suivant :
<?php $prefixe= "PHP"; $suffixe= " cest sympa";

119

Chapitre 3

Le langage PHP

$dyn echo $dyn echo ?>

= "pre"; ${$dyn}fixe; = "suff"; ${$dyn}fixe;

// Affichera PHP // Affichera cest sympa

Le rsultat aurait t videmment tout autre si nous avions utilis $dynfixe. Le problme est identique lorsquil sagit de slectionner un lment dun tableau ; $$dyn[0] est ambigu, contrairement ${$dyn[0]} et ${$dyn}[0].

3. Le langage PHP

Les types
Comme nous avons pu le constater, les variables PHP nont pas un type prdfini. Pourtant, un dveloppeur peut tre amen manipuler les types pour le besoin dune application et les problmes de conversion peuvent non pas causer des erreurs, mais retourner des rsultats surprenants et gnants. Pour viter cela, le langage PHP possde un jeu de fonctions qui lui permet de fixer et de rcuprer le type dune variable donne. On peut classer les diffrents types possibles en trois catgories : les types scalaires, les types composs et les types spciaux.

Tableau 3.3 : Dfinitions des quatre types scalaires


Type int (ou integer) Description Le type int est utilis pour contenir des entiers (nombres sans virgule). Les valeurs peuvent aller de 2147483648 2147483647. Le type double sert dfinir des nombres dcimaux, cest--dire comportant une virgule flottante. Le type string dfinit une chane de caractres. Le type boolen dfinit une variable prenant des valeurs de type binaire : TRUE (Vrai) ou FALSE (Faux). Exemple $maVariable = 2; $maVariable = 4; $maVariable = 2002; $maVariable = 1.0; $maVariable = 0.1 $maVariable = 3.1415972; $maVariable = "Vive le php !"; $maVariable = "1"; $maVariable = TRUE; $maVariable = FALSE;

double (ou real ou float)

string

boolean (ou bool)

Notation dans les diffrentes bases Le type entier peut prendre des valeurs exprimes en dcimales (en base 10), hexadcimales (en base 16) et octales (en base 8). Pour indiquer le changement de base, le programmeur placera un 0 devant laffectation.
<?php $dec = 16; // Affectation classique en base 10

120

Les variables

$hex = 0x10; $oct = 020; ?>

// Le 0x indique laffectation en hexadcimal // Le simple 0 devant indique laffectation en Octal

$dec, $hex et $oct possdent la mme valeur mais exprime dans une base diffrente. Il est noter quil nest pas possible dexprimer un nombre directement dans sa forme binaire.

Tableau 3.4 : Les deux types composs


Type array Description Dsigne un type tableau (ensemble de valeurs). Voir la sectionTableaux. Dsigne un type objet (variable possdant ses propres proprits, attributs et mthodes). Voir la section Classes. Exemple $monTableau = array (2, "Super, du PHP !", "cl"=>"valeur"); $monTableau[2] = "Top"; class MaClasse { } $monObjet = new MaClasse()

3. Le langage PHP

object

Tableau 3.5 : Les deux types spciaux supports


Type resource NULL Description Reprsente une rfrence (ex. : identifiant de connexion une base de donnes ou toute autre source). La variable de type NULL reprsente une variable ne possdant pas de valeur.

Rencontre avec le 9e type Dans les descriptions des fonctions, nous utiliserons galement, en lieu et place de certains types, dautres termes qui ne correspondent pas vritablement des types. Ainsi :
j j j j
mixed dsignera les paramtres (ou valeurs retour) pouvant tre de diffrents types. function dsignera des noms de fonctions (en fait, des types string mais avec une signification particulire). numeric dsignera des paramtres (ou valeurs retour) de type int ou double. void dsignera les fonctions sans paramtre ou sans valeur retour.

121

Chapitre 3

Le langage PHP

Bien que le type des variables soit dfini leur initialisation, il est quand mme possible de forcer une variable dans un type donn. Pour cela, nous utilisons la fonction setType().

setType()
Affecte un type une variable. Syntaxe $variable boolean setType(mixed $variable, string $type) Variable dont on veut fixer le type. Chane de caractres prcisant le type que lon veut affecter la variable. Ce peut tre au choix : integer pour un type entier. double pour un type rel. string pour une chane de caractres. array pour un tableau. TRUE en cas de succs ou FALSE (ex. : nom de type invalide).

3. Le langage PHP

$type

retour

Pour rcuprer le type vous utiliserez la fonction gettype().

getType()
Retourne le type de la variable. Syntaxe $variable retour string getType(mixed $variable) Variable dont on veut dterminer le type. Les diffrentes valeurs retournes possibles sont : integer pour un type entier. double pour un type rel. string pour une chane de caractres. array pour un tableau. object pour un objet. resource pour une ressource (un pointeur sur ...). user function pour une fonction cre par lutilisateur. unknown type pour un type indtermin.

Le code ci-dessous est un bon exemple de cette utilisation :


<?php setType($toto, "integer"); // La variable est du type entier echo getType ($toto); // Renvoie "integer"

122

Les variables

$i = 2+2; echo getType ($i); // Renvoie "integer" $i = "Jaime le chiffre ".$i; // Concatenation dune chane avec un entier echo getType ($i); // Renvoie "string" ?>

Le transtypage
Pour remdier aux problmes que vous pouvez rencontrer dans vos manipulations de conversion, le dveloppeur a la possibilit dutiliser le transtypage (ou type casting). Sous ce terme un peu barbare, se cache la possibilit de crer une nouvelle variable contenant la valeur dune autre avec un type diffrent mais compatible. Ainsi, le transtypage permet un programmeur de modifier le type de ses variables pendant lexcution de son programme, que ce soit pour faire un test dgalit ou des oprations entre deux variables de type diffrent. Le transtypage sutilise, comme pour le langage C, en crivant le type entre parenthses devant le nom de la variable, comme indiqu dans lexemple ci-dessous :
<?php $monEntier = 10; // $monEntier est un "integer" $maChaine = (string)$monEntier; // $maChaine est une chaine de caractres ?>

3. Le langage PHP

Les diffrentes conversions possibles sont donc :


j j j j j j
(array) pour convertir en type tableau. (boolean) ou (bool) pour convertir en type boolen. (double), (float) ou (real) pour convertir en type rel (dcimal). (int) ou (integer) pour convertir en type entier. (object) pour convertir en type objet. (string) pour convertir en type chane de caractres.

Dans lexemple suivant, nous montrons comment, depuis la conversion en tableau ou en objet, un programmeur peut rcuprer les donnes :
<?php $maVariable = "Super, encore du PHP !"; $tableau = (array)$maVariable; echo $tableau[0]; // renvoie "Super, encore du PHP !" $objet = (object)$maVariable; echo $objet->scalar;

123

Chapitre 3

Le langage PHP

// renvoie "Super, encore du PHP !" ?>

Notez que la conversion dune variable de type scalaire (int, double ou string) dans le type objet crera un attribut nomm scalar et contenant la valeur de la variable.

Les rfrences
PHP permet de crer une rfrence une variable existante. De la mme manire quavec le langage C, vous pouvez accder directement une zone mmoire contenant une variable. La rfrence une variable permet de crer une nouvelle variable qui utilise la mme zone mmoire que la variable dorigine. Pour cela, vous devez lindiquer laide du caractre & devant le nom de la variable, comme le montre lexemple suivant :
<?php $var1 = "Bonjour"; $var2 = &$var1; // $var1 et $var2 sont deux mmes noms pour une mme variable $var2 = "Au revoir"; echo $var1; // Affiche Au revoir ?>

3. Le langage PHP

Tester une variable


Dans vos manipulations des donnes, vous pouvez tre amen tester lexistence ou le type des variables que vous utilisez. Pour cela, on utilise un jeu de fonctions trs utile.

isSet()
Dtermine si une variable existe (a t initialise). Syntaxe $variable retour boolean isSet(mixed $variable) Variable que lon veut tester. TRUE si la variable existe bien et FALSE sinon.

unset()
Dtruit les variables.

124

Les variables

Syntaxe $variable1, ...


<?php echo isSet($toto); $toto = ""; echo isSet($toto); unset ($toto); echo isSet($toto); ?>

void unset(mixed $variable1 [, mixed $variable2 [, ...]]) Les variables dtruire.


// Renvoie FALSE (ce qui naffiche rien) // Renvoie TRUE (ce qui affiche 1)

// Renvoie FALSE (ce qui naffiche rien)

De la mme manire, la fonction empty() dtermine si une variable possde une valeur non nulle ou non.

3. Le langage PHP

empty()
Dtermine si une variable possde une valeur non nulle ou non. Syntaxe $variable retour boolean empty(mixed $variable) Variable que lon veut tester. TRUE si la variable nexiste pas, est une chane vide () ou vaut 0, NULL, FALSE sinon.

<?php echo <html><body>; // affectation des variables $var1 = 0; $var2 = 1; $var3 =""; $var4 ="Bonjour !"; // empty($var1) renvoie TRUE if (empty($var1)) echo $var1 est "vide"<br>; else echo $var1 = .$var1.<br>; // empty($var2) renvoie FALSE if (empty($var2)) echo $var2 est "vide"<br>; else echo $var2 = .$var2.<br>; // empty($var3) renvoie TRUE if (empty($var3)) echo $var3 est "vide"<br>; else echo $var3 = .$var3.<br>; // empty($var4) renvoie FALSE if (empty($var4)) echo $var4 est "vide"<br>; else echo $var4 = .$var4.<br>; echo </body></html>; ?>

125

Chapitre 3

Le langage PHP

Figure 3.3 : Le rsultat dans un navigateur

Pour dtruire une variable, utilisez la fonction unset().

3. Le langage PHP

is_bool(), is_int(), is_double(), is_numeric(), is_scalar(), is_object(), is_resource(), is_NULL().

Afin de tester le type des variables, PHP possde une srie de fonctions trs commodes : is_string(), is_array(),

Toutes ces fonctions sutilisent de la mme manire. Elles renvoient TRUE si le type de la variable passe en paramtre est exactement le type recherch, et FALSE dans le cas contraire.

is_bool()
Dtermine si une variable est de type boolen. Syntaxe $variable retour boolean is_bool(mixed $variable) Variable dont on veut dterminer si elle est de type boolen. TRUE si la variable est de type boolen, FALSE sinon.

<?php $var = 1; echo is_bool($var); // Ne renvoie rien, le rsultat du test est faux $var = TRUE; echo is_bool($var); // Renvoie 1, le rsultat du test est vrai ?>

is_int()
Dtermine si une variable est de type entier. Syntaxe $variable retour boolean is_int(mixed $variable) Variable dont on veut dterminer si elle est de type entier. TRUE si la variable est de type entier, FALSE sinon.

126

Les variables

is_int() est en fait un alias de is_long() dont is_integer() est un autre alias.

<?php $var = "15"; echo is_int($var); // Ne renvoie rien, le rsultat du test est faux $var = 15; echo is_int($var); // Renvoie 1, le rsultat du test est vrai ?>

3. Le langage PHP

is_double()
Dtermine si une variable est de type rel (dcimal). Syntaxe $variable retour boolean is_double(mixed $variable) Variable dont on veut dterminer si elle est de type rel. TRUE si la variable est de type rel, FALSE sinon.

is_float() et is_real() sont des alias de la fonction is_double().

<?php $var = 15; echo is_double($var); // Ne renvoie rien, le rsultat du test est faux $var = 15.0; echo is_double($var); // Renvoie 1, le rsultat du test est vrai ?>

is_numeric()
Dtermine si une variable est un nombre ou une chane de caractres reprsentant un nombre. Syntaxe $variable retour boolean is_numeric(mixed $variable) Variable dont on veut dterminer si elle est de type nombre ou chane de caractres reprsentant un nombre. TRUE si la variable est de type nombre ou chane de caractres reprsentant un nombre, FALSE sinon.

<?php $var1 = "quinze"; echo is_numeric($var1);

127

Chapitre 3

Le langage PHP

// Ne renvoie rien, le rsultat du test est faux $var2 = 15; echo is_numeric($var2); // Renvoie 1, le rsultat du test est vrai $var3 = "15"; echo is_numeric($var3); // Renvoie 1, le rsultat du test est vrai $var4 = 15.0; echo is_numeric($var4); // Renvoie 1, le rsultat du test est vrai ?>

3. Le langage PHP

is_string()
Dtermine si une variable est de type chane de caractres. Syntaxe $variable retour boolean is_string( mixed $variable) Variable dont on veut dterminer si elle est de type chane de caractres. TRUE si la variable est de type chane de caractres, FALSE sinon.

<?php $var = "15"; echo is_string($var); // Renvoie 1, le rsultat du test est vrai $var = 15; echo is_string($var); // Ne renvoie rien, le rsultat du test est faux ?>

is_array()
Dtermine si une variable est de type tableau. Syntaxe $variable retour boolean is_array(mixed $variable) Variable dont on veut dterminer si elle est de type tableau. TRUE si la variable est de type tableau, FALSE sinon.

<?php $var1 = 15; echo is_array($var1); // Ne renvoie rien, le rsultat du test est faux

128

Les variables

$var2 = array(15); echo is_array($var2); // Renvoie 1, le rsultat du test est vrai ?>

is_object()
Dtermine si une variable est de type objet.

3. Le langage PHP

Syntaxe $variable retour


<?php class Bible { var $x; }

boolean is_object(mixed $variable) Variable dont on veut dterminer si elle est de type objet. TRUE si la variable est de type objet, FALSE sinon.

$var = new Bible(); $var->x = "Je suis un attribut"; echo is_object($var); // Renvoie 1, le rsultat du test est vrai echo is_object($var->x); // Ne renvoie rien, le rsultat du test est faux ?>

is_scalar()
Dtermine si une variable est de type scalaire. Syntaxe $variable retour
<?php $var1[0] = 3.14; $var2 = 3.14; $var3 = "pi"; echo is_scalar($var1); // Ne renvoie rien, le rsultat du test est faux

boolean is_scalar(mixed $variable) Variable dont on veut dterminer si elle est de type scalaire. TRUE si la variable est de type scalaire, FALSE sinon.

129

Chapitre 3

Le langage PHP

echo is_scalar($var1[0]); // Renvoie 1, le rsultat du test est vrai echo is_scalar ($var2); // Renvoie 1, le rsultat du test est vrai echo is_scalar ($var3); // Renvoie 1, le rsultat du test est vrai ?>

3. Le langage PHP

is_resource()
Dtermine si une variable est de type resource. Syntaxe $variable retour boolean is_resource(mixed $variable) Variable dont on veut dterminer si elle est de type resource. TRUE si la variable est de type resource, FALSE sinon.

is_NULL()
Indique si une variable est NULL. Syntaxe : $variable retour boolean is_NULL(mixed $variable) Variable dont on veut dterminer si elle est NULL. TRUE si la variable est NULL, FALSE sinon.

<?php $var = 0; echo is_NULL($var); // Ne renvoie rien, le rsultat du test est faux unset($var); echo is_NULL($var); // Renvoie 1, le rsultat du test est vrai ?>

Les variables externes


Nous pouvons diffrencier deux types de variables externes :
j j

Les variables denvironnement (du serveur) ; Les variables passes en paramtre lors de lappel de la page (soit via un formulaire soit via lURL).

130

Les variables

Les variables denvironnement


Les variables denvironnement sont des variables gnres automatiquement par PHP partir des donnes rcupres sur le serveur ou de len-tte des requtes du client.

Voir le chapitre "Les en-ttes" pour plus de dtails sur les en-ttes.

Ces variables constituent en fait deux tableaux de porte globale (accessibles depuis nimporte quel endroit du script) :

3. Le langage PHP

j j

$_ENV contient les "vritables" variables denvironnement du serveur, cest--dire toutes les variables dont a pu hriter le compte sous lequel tourne le serveur web (ex. : PATH). $_SERVER contient, quant lui, les variables "internes" du serveur (nom et version du serveur, adresse IP, etc.) ainsi que celles rcupres du client (adresse IP du client, type du navigateur, etc.).

Vous pouvez simplement visualiser toutes les variables denvironnement sur la page gnre par la fonction phpinfo(). Une autre possibilit pour rcuprer la liste des variables est dutiliser la fonction get_defined_vars(); elle permet de rcuprer dans un tableau la liste de toutes les variables dfinies. Le tableau retourn contient alors toutes les variables denvironnement, mais aussi toutes les variables dfinies par lutilisateur.

get_dened_vars()
Liste toutes les variables dfinies. Syntaxe retour array get_defined_vars(void) Toutes les variables dans un tableau associatif o les noms des cls sont les noms des variables et les valeurs celles des variables.

Lexemple ci-dessous permet de gnrer un tableau HTML contenant la liste des variables et leurs valeurs au moment de lexcution du code :
<html> <body> <?php $a1 = "premire variable"; $a2 = "seconde variable"; echo "<table border=1>"; $a = get_defined_vars(); while (list($key, $val) = each($a)) { echo "<tr>";

131

Chapitre 3

Le langage PHP

echo "<td>\$".$key."</td><td>".$val."</td>"; echo "</tr>"; } echo "</table>"; ?> </body> </html> Figure 3.4 : Ce code retourne un tableau contenant noms des variables et valeurs

3. Le langage PHP

Le tableau $_ENV ne prsente gnralement pas un grand intrt hormis dans quelques cas particuliers. Vous pouvez aussi rcuprer les valeurs laide de la fonction getEnv().

getEnv()
Retourne la valeur dune variable denvironnement. Syntaxe $variable Environnement retour string getEnv(string $variableEnvironnement ) Variable denvironnement dont on veut dterminer la valeur. La valeur de la variable denvironnement ou FALSE si il y a une erreur

132

Les variables

Il est trs simple de modifier les variables denvironnement en utilisant la fonction putEnv(). Les valeurs ainsi fixes par le dveloppeur ne durent que le temps de lexcution du script et, ds la fin de celui-ci, lenvironnement par dfaut est restaur. Mais, comme la modification de certaines valeurs peut entraner des problmes de scurit, ladministrateur du systme a la possibilit dempcher certaines modifications. Cest dailleurs, par dfaut, le cas de la variable LD_LIBRARY_PATH (dun systme UNIX/Linux) qui, si elle venait tre modifie, pourrait ventuellement permettre aux pirates de masquer la prsence dune bibliothque (peut-tre utilise par le serveur web) au profit dune autre plus malicieuse. Ainsi, la directive safe_mode_protected_env_vars du fichier de configuration php.ini contient une liste de variables denvironnement que le dveloppeur ne peut modifier. De la mme faon, si safe_mode (mode protg) est activ (ce qui nest pas le cas par dfaut), seules les variables commenant par les prfixes prciss dans safe_mode_allowed_env_vars pourront tre modifies.

3. Le langage PHP

Pour plus dinformations sur le fichier php.ini, reportez-vous au chapitre "Prise en main".

putEnv()
Fixe une nouvelle valeur la variable denvironnement. Syntaxe void putEnv(string $chaineAffectation) $chaineAffectation Chane de caractres de la forme "<nom de variable>=<valeur>"
<?php $ip = getEnv("REMOTE_ADDR"); // retourne ladresse IP de lutilisateur putEnv("NOUV_IP=127.0.0.1"); // Dfinit une nouvelle variable denvironnement echo getEnv("REMOTE_ADDR"); // Affiche 127.0.0.1 ?>

Le tableau $_SERVER, quant lui, va nous permettre de raliser de nombreuses oprations.

Variantes dun serveur lautre Les variables $_SERVER prsentes sont celles disponibles sous Apache. La plupart sont galement disponibles sur les serveurs IIS et iPlanet, mais vous observerez tout de mme des diffrences.

133

Chapitre 3

Le langage PHP

Dterminer ladresse IP du client


Llment $_SERVER["REMOTE_ADDR"] retourne ladresse IP du client, ce qui est particulirement utile pour ne pas compter lutilisateur plusieurs fois dans le nombre des visiteurs dun site.

3. Le langage PHP

IP mouvante La grande majorit des internautes nest pas connecte en permanence linternet (mme les utilisateurs de lADSL sont gnralement contraints de se reconnecter au moins une fois par jour). Par consquent, ladresse IP (attribue par le fournisseur daccs) varie dun jour sur lautre. Il serait donc faux de supposer que deux visites deux jours dintervalle avec la mme adresse IP corresponde au mme visiteur. Alors que si lintervalle de temps entre les deux visites est bien plus court, lhypothse est fort valable.

Dterminer do vient le client


Il est gnralement possible de savoir quel lien a suivi le visiteur pour arriver sur le script en cours dexcution. Pour cela, il suffit de lire le contenu de $_SERVER["HTTP_REFERER"] ; ceci retourne alors une URL.

Dterminer le type de navigateur du client


Llment $_SERVER["HTTP_USER_AGENT"] permet de rcuprer la chane didentification fournie par le navigateur du client. Cela est particulirement utile si vous avez crire des scripts gnrant du code Javascript un peu pointu, car, comme vous le savez peut-tre, le Javascript dpend fortement du navigateur. Il en est de mme de certaines balises HTML. La valeur ainsi rcupre ncessite toutefois une petite analyse avant de dterminer avec prcision la nature du navigateur, comme le dmontre lchantillon de valeurs possibles suivant :
j

pour Internet Explorer :


Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0) Mozilla/4.0 (compatible; MSIE 6.0; Windows 98) Mozilla/4.0 (compatible; MSIE 5.0; Mac_PowerPC)

Konqueror :
Mozilla/5.0 (compatibles; Konqueror/2.2.1; Linux)

Netscape :
Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.2) Gecko/20010726 Netscape6/6.1 Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.8) Gecko/20020204

Opera :
Mozilla/4.7 [tr] (X11; I; Linux 2.2.16 i686)

134

Les variables

Mozilla/4.0 (compatible; MSIE 5.0; Linux) Opera 6.0 [en]

Et tout cela se dcline pour ainsi dire linfini. Dautant que certains visiteurs ne sont pas des utilisateurs derrire leur navigateur, mais des aspirateurs de sites (soit pour les moteurs de recherche, soit pour un particulier). Mme si cela nest pas systmatique, la plupart prcisent leur propre identifiant et dautres offrent mme la possibilit lutilisateur de dfinir sa propre chane didentification. Voici, donc, un nouvel chantillon de valeur rencontre :
j

Les aspirateurs de sites et autres "spiders" de moteurs de recherche :


Googlebot/2.1 (+http://www.googlebot.com/bot.html) Mozilla/3.0 (Slurp/si; slurp@inktomi.com; http://www.inktomi.com/slurp.html) WebCopier v3.0

3. Le langage PHP

<html> <body> Vous avez ladresse IP : <?php echo $_SERVER["REMOTE_ADDR"]; ?> <br /> Vous avez un navigateur qui porte la signature : <?php echo $_SERVER["HTTP_USER_AGENT"]; ?> <br /> </body> </html>

Dterminer la langue du visiteur


Bien que cette fonctionnalit ne soit pas forcment bien connue, les navigateurs offrent la possibilit de dterminer ses langues prfres. Il est alors possible, lorsque lon gre un site multi-langue, de sadapter automatiquement en proposant la langue qui rpondra au mieux aux attentes du visiteur. Ce paramtre est accessible depuis le serveur via la variable $_SERVER["HTTP _ACCEPT_LANGUAGE"] qui aura une valeur du genre :
fr, en;q=0.5

Il sagit donc dune chane contenant les codes ISO des langues, spars par des virgules et par ordre de prfrence. La liste se termine par un point-virgule (et lon trouve ensuite un coefficient).

Dterminer le nom du serveur web


Il est possible de dterminer le nom du serveur en consultant le contenu de $_SERVER["SERVER_NAME"], ce qui peut vous permettre de crer un script unique ayant un comportement diffrent selon la machine sur lequel il tourne.

Dterminer la racine du serveur web


Si vous avez manipuler des noms de fichier, le chemin relatif la racine du site web ne sera peut-tre pas toujours suffisant. Si vous avez besoin du chemin complet depuis la racine du disque dur, vous pourrez faire appel $_SERVER["DOCUMENT_ROOT"] pour rcuprer le chemin depuis la racine du disque dur vers la racine du serveur web.

135

Chapitre 3

Le langage PHP

iPlanet, IIS et PWS Cette variable nest pas disponible sur les serveurs iPlanet, IIS et PWS.

Dterminer le nom du script en cours dexcution


La variable $_SERVER["PHP_SELF"] contient le chemin absolu (commence par un /) par rapport la racine du site web et le nom du script en cours dexcution. Cela est particulirement intressant lorsquil sagit dcrire des scripts qui doivent sappeler eux-mmes (ce qui est souvent le cas des scripts gnrant des formulaires) et que lon ne souhaite pas indiquer "en dur" le nom du script (pour ne pas avoir de soucis dans le cas o celui-ci serait renomm). Cela peut galement servir pour dterminer le chemin. La variable $_SERVER["SCRIPT_FILENAME"], quant elle, donne le chemin absolu par rapport la racine du disque dur.

3. Le langage PHP

Excution ! Le script en cours dexcution nest pas ncessairement le script dans lequel est crite linstruction en cours dexcution. Si un script A inclut un script B au niveau du script B, $_SERVER["PHP_SELF"] et $_SERVER["SCRIPT_FILENAME"] retourneront le chemin du script A. Pour connatre le chemin du script B, il faudra faire appel la constante __FILE__ qui donnera le chemin absolu par rapport la racine du disque dur.

iPlanet, IIS et PWS La valeur $_SERVER["SCRIPT_FILENAME"] nest pas disponible sous iPlanet, IIS et PWS ; la place, vous pouvez utiliser $_SERVER["PATH_TRANSLATED"].

Autres...
Mme si nous avons vu ici les principales variables denvironnement, il en existe de nombreuses autres.

Vous pouvez vous reporter aux annexes de ce livre pour une liste plus complte des variables denvironnement. Souvenez-vous... Avant PHP 4.1.0,

les tableaux $_SERVER, $HTTP_SERVER_VARS, $HTTP_ENV_VARS, etc.

$_ENV

sappelaient

136

Les variables

Les variables passes en paramtre du script (ou via des formulaires)


Comme vous le savez peut-tre dj (en tout cas, vous allez bientt le savoir) il est possible de passer des paramtres un script. Il existe diffrentes faons de passer ces paramtres, mais la plus simple - ou du moins la plus parlante - consiste ajouter les paramtres et leurs valeurs la suite de lURL aprs un point dinterrogation ? chaque couple <nom du parametre>=<valeur> tant spar dun autre par le caractre "et commercial" &. On parle alors de passage de paramtres par la mthode GET. Ce qui donne une URL du genre :
http://mondomaine.com/monscript.php?nom=Franois&prenom=DUPOND

3. Le langage PHP

Dans ce cas, les diffrents paramtres du script seront disponibles dans un tableau appel $_GET. Ainsi, si vous appelez le script suivant de la manire indique prcdemment,

Listing 3.2 : get_echo.php


<?php echo "Nom =".$_GET["nom"]."<br />"; echo "Prnom =". $_GET["prenom"]."<br />"; ?>

vous obtiendrez le rsultat suivant :


Nom = Franois Prnom = DUPOND

Je pense que vous commencez entrevoir des possibilits dapplications. Mais vous serez plus enthousiasm encore aprs avoir vu comment utiliser des formulaires de saisie.

Rappel sur les formulaires


Sans faire un descriptif complet des balises HTML, voici un rapide aperu des balises gnralement utilises pour crer un formulaire. Pour commencer, la dfinition dun formulaire se fait entre des balises <form> et </form>. La balise <form> possde, entre autres, deux attributs importants :
j j

Un attribut action prcisant quel page doit tre charge lorsque le formulaire sera valid. Un attribut method prcisant quel mode denvoi des donnes doit tre utilis. Ce dernier peut prendre lune des deux valeurs suivantes get (que nous venons de voir) ou post (que nous nallons pas tarder voir).

La plupart des lments dun formulaire se construisent avec la balise <input />. La balise <input> possde, entre autres, trois attributs importants :
j

Un attribut type prcisant le type de champ de saisie (voir ci-aprs).

137

Chapitre 3

Le langage PHP

j j

Un attribut name prcisant le nom du paramtre associ ce champ. Un attribut default ou checked (selon les cas) prcisant la valeur par dfaut.

Lattribut type peut prendre les valeurs :


j j j
text pour prciser un champ de saisie texte. radio pour prciser un lment dune liste de slection dans laquelle une seule des options peut-tre slectionne. checkbox pour prciser une case cocher.

3. Le langage PHP

Enfin, vous disposez galement des balises <select> (associe <option>) et <textarea>.

Application
Voici donc un petit exemple dapplication :

Listing 3.3 : form_get.html


<html> <body> <form action="get_echo.php" method="get"> Veuillez indiquer vos Noms et Prnoms<br /> Prnom: <input type="text" name="prenom" /><br /> Nom: <input type="text" name="nom" /><br /> <input type="submit" /> </form> </body> </html>

Comme vous pouvez le constater dans la barre dadresse de votre navigateur, le simple fait de valider ce formulaire appelle le script prcis dans le champ action (ici, le script get_echo.php prsent prcdemment) en ajoutant lURL la liste des paramtres et de leurs valeurs, comme cela peut se faire avec une mthode GET rdige manuellement.

Slection multiple Si vous souhaitez utiliser un lment de formulaire pouvant retourner une slection multiple (typiquement une balise <select> en mode "multiselect" ou encore une srie de cases cocher portant toutes le mme nom), vous devez alors lui affecter un nom de tableau (i.e. un nom suivi de []). La valeur rcupre dans $_GET ne sera alors pas de type string mais de type array.
Le fait dutiliser la mthode GET peut entraner des problmes dordres divers. Le problme le plus vident est li la longueur de lURL. Plus il y a de paramtres passer et plus lURL sera longue, ce qui pourrait mettre en dfaut votre serveur. Un autre problme, plus subtil (mais non des moindres) concerne la scurit. En effet, si vous utilisez une mthode GET pour passer des mots de passe (pour une section membre par exemple), ceux-ci apparatront dans lURL de la page. Outre le fait que le mot de passe devienne visible dans la barre dadresse du navigateur

138

Les variables

et dans lhistorique, le problme saggrave quand, depuis cette page, vous proposez un lien vers un autre site (site dune tierce personne). En effet, si ce site tablit des statistiques sur ses consultations, peut-tre trace-t-il linformation $_SERVER["HTTP_REFERER"] qui note do vient le visiteur. Dans ce cas, ladministrateur de ce site pourra lire lURL complte, indiquant ladresse de votre site et un mot de passe gnralement accompagn dun nom dutilisateur ! Bref, il aura en main tous les outils ncessaires pour accder des informations qui ne lui sont pas destines Pour pallier ces diffrents problmes, vous avez la possibilit dutiliser la mthode POST. Dans ce cas, les paramtres ne sont pas ajouts lURL, mais passs "discrtement" dans len-tte de la requte HTTP envoye au serveur. Dans ce cas, les deux fichiers prsents prcdemment deviennent :

3. Le langage PHP

Listing 3.4 : form_post.html


<html> <body> <form action="get_echo.php" method="post"> Veuillez indiquer vos Noms et Prnoms<br /> Prnom: <input type="text" name="prenom" /><br /> Nom: <input type="text" name="nom" /><br /> <input type="submit" /> </form> </body> </html>

Listing 3.5 : post_echo.php


<?php echo "Nom =".$_POST["nom"]."<br />"; echo "Prnom =". $_POST["prenom"]."<br />"; ?>

Vous noterez donc que le travail du dveloppeur est identique, puisquil suffit de remplacer get par post. Ainsi, le tableau contenant les donnes sappelle $_POST. En dehors de lutilisation de formulaires, la mthode GET reste la seule solution facilement implmentable pour passer des paramtres un script.

Souvenez-vous... Avant PHP 4.1.0, les tableaux $_GET, $_POST sappelaient $HTTP_GET_VARS, $HTTP_POST_VAR. Avant PHP 4.2.0, le fichier de configuration php.ini fixait par dfaut loption register_global on, ce qui avait pour effet de crer systmatiquement une variable globale portant le nom des paramtres GET, POST, etc. Ainsi, par exemple, $_GET["nom"] tait galement accessible par $nom., ce qui engendrait des problmes de scurit. Cela est particulirement vrai avec les fichiers destins tre inclus et qui sappuient sur des variables globales dclares dans le script appelant.

139

Chapitre 3

Le langage PHP

Car, dans ce cas, une variable $maVariable peut tre "pirate" en appelant le script inclus avec le paramtre ?maVariable=autreValeur.

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini.
Il existe galement dautres variables denvironnement, mais nous leur consacrerons un chapitre spcifique.

3. Le langage PHP

Il sagit des tableaux $_COOKIE et $_SESSION tudis dans le chapitre En-ttes et du tableau $_FILES tudi dans le chapitre Fichiers.

3.5.

Les oprateurs

Arithmtiques
Les oprateurs mathmatiques sont classiques ; les voici regroups dans un tableau. Ils agissent aussi bien sur des entiers que sur des rels.

Tableau 3.6 : Les oprateurs arithmtiques


Oprateur $a + $b $a $b $a * $b $a / $b $a % $b Description Somme de $a et $b. Diffrence de $a et $b. Produit de $a par $b. Quotient de $a par $b. Reste de la division de $a par $b.

Loprateur / renvoie un entier si les deux valeurs de la division sont des entiers ou des chanes de caractres reprsentant des entiers. Si une des deux valeurs est un rel, alors le rsultat sera un rel.

Reste de la division Loprateur % est particulirement utile ; il peut permettre de savoir si un nombre est divisible par un autre. Par exemple, si vous souhaitez savoir si $a est un chiffre pair, il suffit de tester le rsultat de $a%2 sil vaut 0 alors $a est un chiffre pair (divisible par 2).
<?php for ($i=1; $i<= 5; $i++) { echo "$i:"; if ($i%2 == 0) echo "impair "; else echo "pair ";

140

Les oprateurs

} ?>

Le rsultat :
1:impair 2:pair 3:impair 4:pair 5:impair

Binaires
Vous pouvez traiter les donnes binaires laide de ces fonctions primaires :

Tableau 3.7 : Les oprateurs binaires

3. Le langage PHP

Exemple $a & $b $a | $b $a ^ $b ~$a $a<<$b $a>>$b

Nom Et Ou Ou exclusif Non Dcalage gauche Dcalage droite

Description Active les bits prsents dans $a et $b/. Active les bits prsents dans $a ou $b. Active les bits prsents dans $a ou $b mais pas dans les deux. Oppose les bits. Dcale $a gauche de $b rangs (revient multiplier $b fois par 2). Dcale $a droite de $b rangs (revient diviser $b fois par 2).

Considrons $a=10 soit 1010 en binaire, que lon notera 1010b et $b=13 soit 1101b
<?php $a=10; $b=13; echo "$a & $b = ".($a&$b); echo "$a | $b = ".($a|$b); echo "$a ^ $b = ".($a ^ $b); echo "~$a = ".(~$a); echo "$a<<2 = ".($a<<2); echo "$a>>2 = ".($a>>2); ?>

Voici le rsultat obtenu :

Figure 3.5 : Rsultat

141

Chapitre 3

Le langage PHP

Vrifions :
j j j j j j

1010b AND 1101b fait 1000b soit 8 1010b OR 1101b fait 1111b soit 15 1010b XOR 1101b fait 0111b soit 7 NOT 1010b fait 10101b soit en complment a 1 1011b donc -11 1010b<<2 fait 101000 soit 40 1010b>>2 fait 10 soit 2

Les rsultats concordent bien avec nos calculs.

3. Le langage PHP

Lcriture binaire Si vous ntes pas familier de la notation et des calculs binaires, cela peut vous paratre obscur. Bien que cela ne soit pas indispensable pour lapprentissage de PHP, si vous voulez en apprendre davantage sur la notation binaire, vous pouvez vous connecter, par exemple, aux sites Internet suivants :
http://www.histoire-informatique.org/technologie/binaire.html http://www.web2.cnam.fr/evariste/evariste/10_cours/binaire/binaire.htm http://www.lille.iufm.fr/labo/pagesProjets/leparc/base2/thema.htm

Chanes de caractres
Loprateur permettant la concatnation (fusion) de deux chanes de caractres et le point .. Voici un exemple de script affichant le rsultat de la concatnation de deux chanes :
<?php $a="PHP ?"; $b=" Facile !"; echo $a.$b; ?>

Affectation
Le signe = est le symbole utilis pour affecter une valeur une variable ; la valeur la droite de ce signe est affecte la variable de gauche. Il est possible de les mettre en squence, comme dans le script qui suit :
<?php $a = ( $b = 3 ) +5; ?>

Aprs cette instruction, $a vaut 8 et $b vaut 3.

142

Les oprateurs

Il existe des raccourcis particulirement utiles : au lieu dcrire $a = $a+10, vous pouvez crire $a += 10. De mme, $a = $a10 peut scrire $a = 10. /= et *= sont aussi des oprateurs daffectation. Pour les chanes de caractres, il existe le mme type doprateur, savoir : .=, crire $a .=
"toto"; est quivalent $a = $a."toto";

Incrmentation et dcrmentation
Tableau 3.8 : Oprateurs dincrmentation et de dcrmentation
Syntaxe ++$a $a++ $a $a Nom Pr-incrmentation Post-incrmentation Pr-dcrmentation Post-dcrmentation Description Incrmente $a de un puis retourne $a. Retourne $a puis incrmente $a de un. Dcrmente $a de un puis retourne $a. Retourne $a puis dcrmente $a de un.

3. Le langage PHP

<?php echo $a = echo echo echo echo echo $a = echo echo echo echo echo $a = echo echo echo echo echo $a = echo echo echo echo ?>

"Post-incrementation<br>"; 5; $a++; // affiche 5 "<br>";// place une nouvelle ligne dans le script resultat $a; // affiche 6 "<br>"; "Pre-incrementation<br>"; 5; ++$a; // affiche 6 "<br>"; $a; // affiche 6 "<br>"; "Post-decrementation<br>"; 5; $a--; // affiche 5 "<br>"; $a; // affiche 4 "<br>"; "Pre-decrementation<br>"; 5; --$a; // affiche 4 "<br>"; $a; // affiche 4 "<br>";

143

Chapitre 3

Le langage PHP

Comparaison
Tableau 3.9 : Les oprateurs de comparaison
Syntaxe $a == $b $a === $b $a != $b Nom gal Identique Diffrent Diffrent Non identique Infrieur Suprieur Infrieur ou gal Suprieur ou gal Description Renvoie TRUE si $a est gal $b. Renvoie TRUE si $a est gal $b et que $a et $b sont du mme type. Renvoie TRUE si $a est diffrent de $b. Renvoie TRUE si $a est diffrent de $b. Renvoie TRUE si $a est diffrent de $b ou de type diffrent. Renvoie TRUE si $a est infrieur $b. Renvoie TRUE si $a est suprieur $b. Renvoie TRUE si $a est infrieur ou gal $b. Renvoi TRUE si $a est suprieur ou gal $b.

3. Le langage PHP

$a <> $b $a !== $b $a < $b $a > $b $a <= $b $a >= $b

Tous ces comparateurs vous permettront de tester les variables pour agir en fonction du rsultat obtenu.

Typage Depuis PHP4, le typage est devenu plus fort, mme si lon peut encore comparer directement des chanes de caractres avec un entier ou un rel par exemple. Mais si FALSE == 0 (ce qui peut porter confusion lorsquune fonction peut retourner 0 dans un cas nominal et FALSE en cas derreur) et bien FALSE !== 0 (puisque FALSE est un boolen et 0 un entier).
Bien entendu, il est possible de combiner les oprateurs binaires et les oprateurs de comparaison. Lexpression correspondant aux phrases "la variable a est diffrente de 3 et la variable b vaut toto ou alors la variable c est un boolen valant FALSE" scrit de diffrentes faons. En voici quelques-unes :
(($a != 3 && $b == "toto) || ($c==FALSE)) // faire un test dgalit avec TRUE nest pas trs fut (($a != 3 && $b == "toto) || (!$c==TRUE)) // la faon la plus standard de faire, reste (($a != 3 && $b == "toto) || (!$c))

144

Les oprateurs

Logique
Les oprateurs de logique vont servir faire des tests complexes, par exemple pour savoir si $a vaut 3 ET $b est faux. Dans le tableau suivant sont regroups tous les oprateurs logiques supports par PHP :

Tableau 3.10 : Les oprateurs logiques


Syntaxe $a and $b $a && $b $a or $b $a || $b $a xor $b ! $a Description VRAI si $a et $b sont vrais. VRAI si $a et $b sont vrais. VRAI si $a ou $b est vrai. VRAI si $a ou $b est vrai. VRAI si $a ou $b est vrai, mais pas les deux. VRAI si $a est faux.

3. Le langage PHP

Utiliser loprateur OR comme expression conditionnelle PHP ninterprte pas la partie droite de lexpression OR si la partie gauche est vraie. On peut ainsi sen servir astucieusement pour excuter une instruction si une expression est incorrecte.
<?php $a=4; ($a==3) OR die("\$a ne vaut pas 3"); ?>

Ce script stoppe si $a ne vaut pas 3 et affiche un message. Cela est particulirement utile lors de lappel des fonctions (par exemple de connexion une base de donnes) qui retournent FALSE en cas derreur.
<?php connexion() OR die("Impossible de se connecter"); ?>

Contrles derreur
PHP intgre quatre grands niveaux de message derreur ou dalerte. chacun correspond une constante :
j j
E_NOTICE : simple remarque (comme lorsque lon essaye daccder un index inexistant dun tableau). E_PARSE : en cas derreur danalyse la compilation (comme une erreur de syntaxe).

145

Chapitre 3

Le langage PHP

j j

E_WARNING : une alerte ne ncessitant pas larrt du script. E_ERROR : une erreur "grave" ncessitant larrt du script.

Une constante supplmentaire fait la somme de tous ces types derreur et dalerte, il sagit de E_ALL. ceux-l viennent sajouter les niveaux E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, E_USER_ERROR, E_USER_WARNING et E_USER_NOTICE dune utilisation moins courante. Lorsquune erreur est rencontre et quelle dpasse le seuil dalerte, ou plus exactement lorsque son niveau de svrit fait partie de la liste des niveaux signaler, un message est envoy au client (i.e. est affich sur la page reue par le navigateur). Les niveaux derreur signaler sont dfinis dans le fichier de configuration php.ini, mais peuvent tre modifis au niveau du script par un simple appel la fonction error_reporting().

3. Le langage PHP

error_reporting()
Fixe les niveaux derreur devant tre signals. Syntaxe $niveaux retour int error_reporting([int $niveaux]) Combinaison par OU logique ou OU exclusif des diffrentes constantes indiques prcdemment. Anciennes valeurs des niveaux derreur.

Il est toutefois possible de saffranchir des messages derreur pour une instruction donne sans avoir recours cette fonction. Pour cela, il existe un oprateur de contrle derreur, cest le caractre @ ; il peut tre mis devant nimporte quelle fonction susceptible de gnrer une erreur. Cela peut tre particulirement utile pour gnrer vos propres messages derreur. Le script suivant fixe les niveaux dalerte "tous sauf les simples remarques" (ce qui est la configuration par dfaut de PHP), puis tente daccder un fichier qui nexiste pas.
<?php error_reporting(E_ALL ^ E_NOTICE); $fichier = @file (fichier_inexistant.toto) or die ("Impossible douvrir le fichier."); ?>

La fonction file renvoie un boolen indiquant si lopration sest bien droule. Si le fichier nexiste pas, alors la fonction renvoie un message. Ici, nous avons mis @ devant le nom de la fonction ; nous naurons donc pas cet affichage, mais le texte "Impossible douvrir le fichier". Notez que cela peut aussi sappliquer des expressions, et donc un tableau, pour viter un message si llment recherch nexiste pas (ex. : @tableau["index_inexistant"];). Ceci

146

Les oprateurs

dit, le message prvu en pareil cas est de niveau NOTICE, et PHP nest, par dfaut, pas configur pour afficher ce type de message.

Connexion une base de donnes Lorsque vous vous connectez une base de donnes, il se peut que celle-ci soit momentanment indisponible. Donc, au lieu dobtenir le message derreur standard, il vaut mieux faire prcder la fonction de connexion de @ et tester le code retour pour afficher votre propre message si la connexion a chou.

3. Le langage PHP

Excution
Il existe un oprateur dexcution, cest . Ce qui se trouve entre ces apostrophes inverses sera interprt par PHP comme une commande shell. Voici un exemple de script qui liste le contenu dun rpertoire, le stocke dans une variable, et laffiche :

Listing 3.6 : version Unix/Linux


<?php $liste=ls al; echo "<pre>$liste</pre>"; ?>

Listing 3.7 : version Windows


<?php $liste=dir; echo "<pre>$liste</pre>"; ?>

Configuration du serveur Ceci ne fonctionne pas si loption safe_mode du fichier de configuration php.ini a t active (on) ou si la fonction shell_exec() est dsactive.

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini.

Priorits
Les priorits sur les calculs sont les mmes que celles que vous connaissez dj.
8 + 2 * 3 fera bien 8 + 6 = 14 (et pas 10 * 3 = 30).

147

Chapitre 3

Le langage PHP

Dans le tableau suivant, vous trouverez les oprateurs par ordre de priorit ; les premiers lments sont prioritaires sur les derniers.

Tableau 3.11 : Associativit et priorit des oprateurs par ordre dcroissant de priorit
Oprateur New [ ! ~ ++ (int) (double) (string) (array) (object) @ Associativit Aucune Droite Droite Gauche Gauche Gauche Aucune Aucune Gauche Gauche Gauche Gauche Gauche Gauche Gauche Gauche

3. Le langage PHP

* / % + . << >> < <= > >= == != === !== & ^ | && || ? : = += = *= /= .= %= &= |= ^= ~= <<= >>= ,

3.6.

Les structures de contrle

Extrmement utiles, les structures de contrle vous permettront de faire des boucles et des tests dans vos scripts PHP.

If, else, elseif


La boucle de contrle if est sans aucun doute la plus importante dans tous les langages de programmation ; cela vaut aussi en PHP. La syntaxe est classique :
if (expression) instruction;

ou, sil y a plusieurs instructions (et cela reste conseill mme sil ny a quune seule instruction) :

148

Les structures de contrle

if (expression) { instruction1; instruction2; instruction3; }


expression est une expression boolenne ; si elle est vrifie (TRUE), la ou les expressions qui suivent sont values :

<?php $a=3; if ($a>1) echo "a est suprieur un"; ?>

3. Le langage PHP

Expressions Les expressions peuvent bien entendu utiliser tous les oprateurs de comparaison et de logique. Il faut toutefois sassurer que les parenthses sont correctement places.
Maintenant, il est trs probable que vous ayez envie dexcuter certaines instructions si lexpression retourne TRUE (Vrai), et dautres si elle retourne FALSE (Faux). Dans ce cas, il faut utiliser lexpression suivante :
if (expression) { instruction1; instruction2; instruction3; } else { instruction4; instruction5; }

Voici un exemple :
<?php $a=3; if ($a>1) echo "a est suprieur un"; else echo "a est infrieur ou gal un"; ?>

Pour obtenir une valeur ou une autre selon le rsultat dun test, il est possible dutiliser les instructions ? et : selon le schma suivant :
(expression) ? (valeur1) : (valeur2)

Ce qui donne par exemple :


<?php $a=3; echo "a est ".(($a>1)?"suprieur":"infrieur ou gal")." un"; .>

149

Chapitre 3

Le langage PHP

Accolades Encore une fois, dans le cas dune seule instruction, les accolades peuvent tre omises, mais cela est dconseill (comme lindiquent les rgles de codage).
Il se peut que vous souhaitiez faire plusieurs tests conscutifs ; pour cela vous pouvez utiliser les instructions if..elseif..else
if (expression) { instruction1; instruction2; instruction3; } elseif { instruction4; instruction5; } else { instruction6; instruction7; }

3. Le langage PHP

Reprenons lexemple prcdent et amliorons-le :


<?php $a=3; if ($a>1) echo "a est suprieur un"; elseif ($a<1) echo "a est infrieur un"; else echo "a vaut 1"; ?>

Jouer lalternance Comme cela a dj t voqu, les portions de script PHP peuvent tre places comme bon vous semble dans le script (vous pouvez ainsi alterner les portions de PHP et de HTML). Ainsi, le script suivant est valide :
<?php $a=3; if ($a>1) { ?> a est suprieur un <?php } elseif ($a<1) { ?> a est infrieur un <?php else { ?> a vaut 1 <?php

150

Les structures de contrle

} ?>

Il existe encore une autre faon (mme si nous la dconseillons) de noter. Au lieu dutiliser les accolades, la notation suivante est galement valide. Dans ce cas, la fin du bloc est indique par endif.
if (expression): instruction1; instruction2; instruction3; elseif: instruction4; instruction5; else: instruction6; instruction7; endif;

3. Le langage PHP

Exemple (premire tape)


partir de cette boucle de contrle, il est dj possible de faire des scripts intressants. Ralisons ensemble un script de Quizz.

Listing 3.8 : quizz01.php


<html> <head> <title>Quizz</title> </head> <body> <?php if (isset($_POST["reponse"])) { $reponse=$ _POST["reponse"]; } else { $reponse=""; } ?> <p>Quel est le site officiel de PHP ?</p> <form type="post" action="<?php echo $_SERVER["PHP_SELF"];?>"> <input type="text" name="reponse" value="<?php echo $reponse ?>" /> <input type="submit" value="OK" /> </form> <?php if ($reponse!="") { if (strtolower($reponse) == "www.phpfacile.com") echo "Ce nest pas la bonne rponse"; elseif (strtolower($reponse) == "www.php.net") echo "Bingo !"; else echo "Et non, ce nest pas ".$reponse; } ?>

151

Chapitre 3

Le langage PHP

</body> </html>

Ici, la seule structure utilise est if elseif else. Le fichier HTML de dpart est un simple formulaire qui senvoie lui-mme la rponse saisie. Voici ce que signifie ce script : Si la variable $reponse est dfinie, alors on compare la valeur de la variable rponse transforme en minuscules avec la chane "www.phpfacile.com".. Si ces chanes sont identiques alors "Ce nest pas la bonne rponse" est affich, sinon on compare "www.php.net" .. Si ces chanes sont identiques "Bingo" est affich, sinon la phrase "Eh non, ce nest pas " suivie de la rponse entre est affiche.

3. Le langage PHP

Figure 3.6 : Quizz v0

While, do while
Pour rpter une srie dinstructions, linstruction while ou "tant que" en franais vous sera utile. Voici la syntaxe :
while (expression) instruction;

Cela signifie que tant que lexpression sera VRAIE, linstruction sera excute. Il faut donc sassurer que lexpression passe obligatoirement FAUX un moment donn, sinon le script bouclera linfini et ne se terminera que lorsque le temps maximal dexcution dun script sera atteint. Bien sr, lutilisation des accolades est galement possible (et conseille) ici.
while (expression) { instruction1; instruction2; }

La notation avec les : est galement valide (quoique dconseille). Dans ce cas, le bloc est termin par endwhile.
while (expression): instruction1; instruction2; endwhile;

152

Les structures de contrle

Voici un exemple concret de script qui affiche les entiers de 1 10.

Listing 3.9 : Exemple


<?php $i = 1; while ($i <= 10) { echo print $i++; } ?>

Dure de vie dun script Vous pouvez rgler le temps dexcution dun script dans le fichier de configuration de PHP : il suffit de donner une valeur en secondes max_execution_time au niveau du fichier de configuration php.ini ou via la fonction set_time_limit(). Ainsi, sil savre que votre boucle ne se termine pas, le script ne tournera pas indfiniment.

3. Le langage PHP

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini.
Une variante de la boucle while est la boucle dowhile. La diffrence rside dans ce que le test est fait aprs les instructions. Ainsi, la srie dinstructions est obligatoirement effectue au moins une fois avant dtre teste. Voici la syntaxe :
do { instruction1; instruction2; } while (expression);

For, foreach
Les boucles for sont trs utilises ; elles fonctionnent, comme dans dautres langages, de la faon suivante :
for (expression1; expression2; expression3) instruction
expression1 est excute avant toute itration. Elle sert donc gnralement initialiser les

variables de la boucle.
expression2 est excute chaque itration. Si elle est VRAIE, une nouvelle excution des

instructions a lieu, sinon le programme sort de la boucle.


expression3 est une instruction excute chaque itration. Elle sert gnralement incrmenter une variable.

Voici un exemple de script qui affiche les chiffres de 0 9 :


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

153

Chapitre 3

Le langage PHP

Il faut lire cette commande comme suit : aprs avoir initialis $i 0, et tant que $i est infrieur 10, afficher $i, puis lincrmenter. Linstruction break permet de sortir de la boucle. Dans ce cas, le restant des instructions nest pas excut.
for ($i=0;;$i++) { echo $i; if ($i==9) break; }

Ces lignes de code auront le mme effet que le script prcdent.

3. Le langage PHP

Il est aussi possible de se servir de la syntaxe utilisant les deux-points (:). Dans ce cas, le bloc se termine par endfor.
for (expression1;expression2;expression3): instruction1; instruction2; endfor;

Linstruction foreach. offre une autre manire de raliser une boucle, et elle est particulirement pense pour les tableaux. Voici deux syntaxes possibles :
foreach($tableau as $valeur) instruction; foreach($tableau as $cle => $valeur) instruction;

Dans la boucle, la valeur de lentre du tableau est rcuprable par $valeur ; la cl associe est rcuprable par $cle, condition dutiliser la seconde syntaxe dans cet exemple.

Pointeur de tableau Lorsque la boucle foreach est invoque, elle met le pointeur du tableau en premire position. Il est donc inutile dappliquer la fonction reset() dessus.

Exemple (deuxime tape)


Cette fois, le script propos permet de rpondre plusieurs questions sur une mme page. Il utilise une boucle foreach et une boucle for ainsi que des tests if.

Listing 3.10 : quizz02.php


<html> <head> <title>Quizz</title> </head> <body> <?php $questions = array("Quel est le site officiel de PHP ?", "Quel est le nom de la commande qui

154

Les structures de contrle

affiche une chane de caractre ?", "Quel est le nom de la commande qui met une chane de caractre en minuscule ?"); $reponses=array("www.php.net","echo","strtolower"); // initialisation des variables foreach($questions as $index => $question) { if (isset($_POST["reponse$index"])) { ${"reponse$index"} = $_POST["reponse$index"]; } else { ${"reponse$index"} = ""; } } ?> <form type="post" action="<?php echo $_SERVER["PHP_SELF"];?>"> <?php foreach($questions as $index => $question) { echo $question; echo "<input type=\"text\" name=\"reponse$index\" value=\"${"reponse$index"}\"><br>"; } ?> <input type="submit" value="OK"> </form> <?php if ($reponse0 != "") { $parfait = TRUE; for ($i=0; $i<sizeof($questions); $i++) { if (strtolower(${"reponse$i"}) == $reponses[$i]) { echo "<br />La rponse ".($i+1)." est correcte"; } else { echo "<br />La rponse ".($i+1)." est fausse"; $parfait = FALSE; } } if ($parfait) echo "<br />Bravo !"; else echo "<br />Perdu ..."; } ?> </body> </html>

3. Le langage PHP

Voici une capture dcran de ce script en cours dexcution.

155

Chapitre 3

Le langage PHP

Figure 3.7 :

Quizz v1

3. Le langage PHP

Switch
Utiliser switch revient utiliser des tests if conscutifs sur la mme variable. Voici un exemple dutilisation de switch.
switch ($chanteur) { case "Cantat": echo "Ce chanteur est celui de Noir Desir"; break; case "Harper": echo "Ce chanteur est celui de Ben Harper and the innocent criminals"; break; case "Torrini": echo "Cette chanteuse est Emiliana Torrini"; break; default: echo "Ce chanteur mest inconnu"; }

Ce script est quivalent :


if ($chanteur=="Cantat") echo "Ce chanteur est celui de Noir Desir"; elseif ($chanteur=="Harper") echo "Ce chanteur est celui de Ben Harper and the innocent criminals"; elseif ($chanteur=="Torrini") echo "Cette chanteuse est Emiliana Torrini"; else "Ce chanteur mest inconnu";
default est la condition qui sera VRAIE si aucune des autres ne lest.

Linstruction break est indispensable ici, sinon toutes les instructions qui suivent sont interprtes jusquau prochain break ou la fin du bloc switch. Cela peut tre utile dans certains cas.
switch ($i) { case 0:

156

Les structures de contrle

case 1: case 2: echo "i est positif mais infrieur 3 "; break; case 3: echo "i vaut 3"; }

Comparaison Contrairement dautres langages de programmation, la variable comparer peut tre aussi bien un nombre quune chane de caractres. 3. Le langage PHP

Break, continue
Deux instructions permettent de contrler les sorties de boucle (for, while). break est une instruction qui fait sortir de la boucle, alors que continue passe litration suivante sans excuter les instructions daprs.
<html> <head><title>Continue, Break</title></head> <body> <p> <?php for ($i=0;$i<10;$i++) { echo $i; // va afficher 0,2,4,6,8 $i++; echo $i; // va afficher 1.3.5.7.9 } echo "<br>"; for ($i = 0; $i < 10;$i++) { echo $i; $i++; if ($i>4) break; echo $i; } echo "<br>"; for ($i=0;$i<10;$i++) { echo $i; $i++; if ($i>4) continue; echo $i; } ?> </p> </body> </html>

Voici le rsultat obtenu :

157

Chapitre 3

Le langage PHP

Figure 3.8 : Rsultat

3. Le langage PHP

Pour bien comprendre, regardons la premire boucle. Elle affiche tous les chiffres de 0 9, mais affiche deux chiffres chaque itration. La deuxime boucle, semblable la premire, utilise linstruction break. la premire itration les chiffres 0 et 1 sont affichs. la seconde les chiffres 2 et 3 sont affichs. Puis 4 est affich. Enfin, aprs lincrmentation $i vaut 5 (et la condition est vrifie) et le programme sort dfinitivement de la boucle. La troisime boucle utilise linstruction continue. la premire itration les chiffres 0 et 1 sont affichs. la seconde les chiffres 2 et 3 sont affichs. Puis 4 est affich.Enfin, aprs lincrmentation $i vaut 5 (la condition est vrifie) et la seconde instruction echo nest pas excute (donc 5 nest pas affich). Mais une nouvelle itration est ralise faisant apparatre le chiffre 6, mais pas 7, puis 8, mais pas 9.

3.7.

Les fonctions

PHP possde, comme de nombreux langages, la possibilit de regrouper des portions de code sous la forme de fonctions (ou procdures). Si la dfinition de fonctions na aucun impact sur le fonctionnement dun programme, et donc sil est possible de construire son dveloppement comme une suite dinstructions mises bout bout, elle procure en revanche visibilit et rduction de la taille du code source. La maintenance nen est alors que plus simple et plus rapide. Les fonctions permettant de structurer le code, il est fortement conseill de les utiliser et de constituer des fichiers indpendants qui regrouperont les fonctions de mme type. Ces bibliothques pourront facilement tre rutilises dans dautres dveloppements et rduire ainsi le temps de mise au point (et donc le cot de production). Trois avantages dcoulent donc de lcriture du code sous forme de fonctions :
j

Le temps de dveloppement est considrablement rduit. En effet, vous navez pas retaper des squences de code identiques en divers endroits du programme. De la mme faon, les bugs ne sont pas dupliqus, do un gain de temps considrable lors de la phase de mise au point. Meilleure lisibilit du code source. Le simple fait de regrouper le code en fonctions et les fonctions dans des fichiers spars permet aux dveloppeurs de sy retrouver trs facilement. De plus, donner vos fonctions des noms significatifs est complmentaire avec lajout des commentaires, et facilite ncessairement la lisibilit et la comprhension du programme. Ceci est dautant plus important pour la prennit dun code. Ainsi, la

158

Les fonctions

maintenance et les modifications du programme sont facilites, mme pour un dveloppeur reprenant son propre code quelques temps aprs lavoir crit.
j

Le travail en quipe est amlior. Un dveloppement peut ainsi tre dcoup en plusieurs sous-parties, chaque dveloppeur ayant alors la tche de mettre au point une ou plusieurs fonctions.

Si lemploi de fonctions est un avantage certain, une tape de conception pralable reste ncessaire afin de bien dfinir les fonctions qui devront tre dveloppes et de bien cibler leurs rles respectifs. Plus important encore, ltape prliminaire permet de fixer les rgles dentre/ sortie de chacune des fonctions, ceci afin que chaque dveloppeur connaisse lavance les paramtres quil doit envoyer la fonction et ce quelle doit retourner une fois le traitement effectu. Si les fonctions sont connues ds le dbut, alors chacun pourra commencer les utiliser dans son code avant mme la mise en production desdites fonctions.

3. Le langage PHP

La syntaxe
La fonction est un sous-programme isol du reste du code et utilisable par un simple appel depuis nimporte quelle partie du programme. La syntaxe pour dclarer une fonction simple est la suivante :
<?php function premiereFonction() { echo "Jaime PHP !"; } ?>

Ce code naffiche rien tant que lon ne fait pas appel elle comme ceci :
<?php function premiereFonction() { echo "Jaime PHP !"; } premiereFonction(); // Affiche "Jaime PHP !" ?>

Le cas prcdent est un bon exemple de dclaration de fonction et dutilisation de celle-ci lintrieur du programme principal. On voit lintrt quapporte la dfinition de la fonction dans le cas o la tche de celle-ci est rptitive et devrait engendrer beaucoup de code source.

Le choix du nom dune fonction Afin de faciliter la lecture de votre code, nhsitez pas donner vos fonctions un nom vocateur. Tout comme pour les variables, la lecture de votre programme est facilite si ces lments portent des noms explicites. Si les fonctions du programme sappellent fonction1(), fonction2() et fonction3(), la maintenance nen sera que plus difficile. Ne donnez pas vos fonctions un nom trop nigmatique ou qui peut avoir plusieurs sens. vitez les noms de fonctions trop courts pour quils ne 159

Chapitre 3

Le langage PHP

soient pas utiliss plusieurs fois dans votre programme. Par exemple, pour une fonction devant compter un nombre de personnes prsentes sur une page web, ne lappelez pas simplement compteur(), mais plutt compteurPersonneEnLigne().

La porte des variables


3. Le langage PHP
Comme nous lavons dit, une fonction nest rien dautre quun bout de code isol du programme principal. Cest donc sans surprise que vous apprendrez quil est possible de dfinir des variables au sein des ses fonctions. Par contre, ce quil faut retenir cest que les variables ainsi dfinies ne sont pas accessibles du reste du programme (elles ont une porte locale), comme le dmontre lexemple suivant :
<?php function bicentenaire() { $annee = "2002"; echo "$annee ctait le bicentenaire de la naissance de Victor Hugo !"; } bicentenaire(); // Affiche "2002 ctait le bicentenaire de la naissance de Victor Hugo !" echo $anne; // naffiche rien, la variable nest pas dfinie. ?>

linverse, une variable dfinie en dehors de la fonction (dans le programme principal) nest pas accessible depuis la fonction.
<?php $annee = "2002"; $prenom = "Victor"; $nom = "Hugo"; function bicentenaire() { echo "$annee ctait le bicentenaire de la naissance de $prenom $nom !"; } bicentenaire(); /* affiche "ctait le bicentenaire de la naissance de !" Les variables $annee, $nom et $prenom ne sont pas dfinies au niveau de la fonction */ ?>

Pour utiliser des variables globales dans la fonction, il faut utiliser le mot-cl "global" lintrieur de cette fonction, comme le montre lexemple suivant :
<?php $annee = "2002";

160

Les fonctions

$prenom = "Victor"; $nom = "Hugo"; function bicentenaire() { global $annee, $prenom, $nom; echo "$annee ctait le bicentenaire de la naissance de $prenom $nom !"; $annee = "2003"; } bicentenaire("bicentenaire"); // affiche "2002 ctait le bicentenaire de la naissance de Victor Hugo!"

3. Le langage PHP

echo $annee; // affiche 2003 ?>

Comme vous le constatez, les modifications apportes ces variables globales au sein de la fonction se rpercutent en dehors de la fonction. Il existe une autre faon de faire pour utiliser les variables globales depuis une fonction. Cette mthode consiste utiliser directement le tableau prdfini $GLOBALS. Lexemple prcdent donnerait alors :
<?php $annee = "2002"; $prenom = "Victor"; $nom = "Hugo"; function bicentenaire() { echo $GLOBALS["annee"]." ctait le bicentenaire de la naissance de ". $GLOBALS["prenom"]." ".$GLOBALS["$nom"]." !"; $GLOBALS["annee"] = "2003"; } bicentenaire("bicentenaire"); // affiche "2002 ctait le bicentenaire de la naissance de Victor Hugo!" echo $annee; // affiche 2003 ?>

Variables denvironnement Les variables externes $_SERVER, $_ENV, $_GET, $_POST, $_SESSION, $_COOKIE, $_FILES, etc. sont, quant elles, accessibles depuis nimporte o. Il nest donc pas ncessaire, dans leur cas, de prciser global pour les utiliser dans une fonction.

161

Chapitre 3

Le langage PHP

La porte dune variable dpend donc de lendroit o elle est initialise. La porte dune variable ne sera pas la mme si elle est dfinie dans une fonction ou au dbut de votre programme. On peut considrer trois niveaux de dfinition.

Tableau 3.12 : Les diffrents niveaux de dfinition des variables


Niveau Local Description Les variables sont propres chaque fonction. Ds la fin de lexcution de cette fonction, la variable est dtruite et lespace mmoire qui contenait la valeur est libre. Les variables globales sont dfinies pour la totalit du temps dexcution du code de la page. Les variables statiques sont propres chaque fonction, mais elles ne sont pas dtruites la fin de lexcution de cette fonction. Si la fonction est rappele plusieurs fois, la valeur de la variable est conserve et modifie chaque fois.

3. Le langage PHP

Global Static

Il nous reste donc aborder le cas des variables statiques. Ces variables sont initialises au premier appel de la fonction et ne sont pas rinitialises les fois suivantes. Pour crer une variable statique, il faut utiliser le mot-cl static suivi du nom de la variable. Exemple dutilisation :
<? function maFonction (){ static $variable = "Emma "; $variable . =" Cest toi?"; echo $variable."<br>"; } maFonction(); maFonction(); maFonction(); ?>

Cela affichera en effet :


Emma Cest toi? Emma Cest toi? Cest toi? Emma Cest toi? Cest toi? Cest toi?

Initialisation dune variable statique Il nest pas possible dinitialiser une variable statique avec le rsultat dune fonction. On peut toutefois contourner ce problme en affectant cette variable une valeur quelle est suppose ne jamais atteindre, et appeler la fonction si jamais la variable prend cette valeur.

162

Les fonctions

<?php function maFonction() { static $date = -1; if ($date == -1) $date = time(); } ?>

Le passage des paramtres


Vous serez souvent amen rclamer des paramtres pour vos fonctions. Pour cela, il suffit de complter la ligne de dclaration de la fonction par une liste de noms de variables. Les variables ainsi dfinies ne sont accessibles qu lintrieur de la fonction ; ce sont donc des variables de visibilit locale.
<?php function bicentenaire($quoi) { echo "2002 ctait le $quoi de Victor Hugo !"; } bicentenaire("bicentenaire de la naissance "); // Affiche "2002 ctait le bicentenaire de la naissance de Victor Hugo !" echo $quoi; // naffiche rien, la variable nest pas dfinie. ?>

3. Le langage PHP

Les paramtres par dfaut


Vous pouvez donner votre fonction des paramtres par dfaut. Ainsi, si vous ne rentrez aucune valeur lors de lappel de cette fonction dans votre code, une valeur par dfaut est utilise afin dexcuter la fonction. Pour placer une valeur par dfaut, vous devez simplement spcifier cette valeur laide du signe "=" lors de la dclaration de la fonction. Comme ceci :
<?php function exemple($parDefaut="bonjour") { return $parDefaut; } ?>

Cette fonction peut donc recevoir ou non une valeur comme paramtre. Si ce nest pas le cas, alors celle-ci prend, par dfaut, la valeur "bonjour". Il y a donc deux faons dappeler cette fonction dans le programme principal.
<?php function exemple($pardefaut="bonjour") { return $pardefaut; }

163

Chapitre 3

Le langage PHP

// soit en plaant une valeur en paramtre echo exemple("bye bye"); // affiche "bye bye" // soit en laissant vide echo exemple(); // affiche "bonjour" ?>

Le fait que les fonctions ncessitent a priori un nombre fixe darguments vous posera peut-tre un jour un problme. Mais il y a deux faons dy faire face:
j j

En utilisant un tableau, si votre fonction naccepte quun seul argument mais que celui-ci est de type tableau, vous pouvez y mettre autant darguments que vous voulez. En utilisant les fonctions mises disposition par PHP (ce qui en fait sapparente utiliser un tableau cr par PHP).

3. Le langage PHP

Ainsi, alors que func_num_args() renvoie le nombre dlments passs en paramtre dune fonction, func_get_arg() et func_get_args() permettent de rcuprer un argument ou un tableau darguments.

func_num_args()
Retourne le nombre darguments passs une fonction. Syntaxe retour int func_num_args(void) Retourne un nombre correspondant aux nombres dlments passs comme arguments de la fonction.

<?php function elementsVariables() { return func_num_args(); } echo elementsVariables(); // Affiche 0; echo elementsVariables(1, 2, 3); // Affiche 3; echo elementsVariables("toto", 5, TRUE); // Affiche 3; ?>

func_get_arg()
Retourne la valeur dun des lments passs en argument de la fonction. Syntaxe $numArg retour mixed func_get_arg(int $numArg) Position de llment consulter. La valeur de largument.

164

Les fonctions

func_get_args()
Retourne un tableau contenant tous les lments passs en argument la fonction. Syntaxe retour array func_get_args(void) Tableau index contenant la liste des arguments de la fonction.

Voici un exemple de lutilisation qui peut tre faite des trois fonctions prcdemment dcrites :
<?php function elementsVariables() { // Compte le nombre dlments $nombreElements = func_num_args(); // Rcupre tous les lments dans un tableau $tableauElements = func_get_args(); for ($i=0; $i<$nombreElements; $i++) { // Affiche tous les arguments de la fonction echo "lment $i : ".$tableauElements[$i]."<br />"; } // Rcupre llment dsign par le deuxime argument echo "largument n".func_get_arg(1). " = ".func_get_arg(func_get_arg(1))."<br />"; } elementsVariables(10, 0, 3); echo "<br />"; elementsVariables("toto", 3, TRUE, "PHP"); ?>

3. Le langage PHP

Lexcution de ce programme renvoie donc ici :


lment 0 : 10 lment 1 : 0 lment 2 : 3 largument n0 = 10 lment 0 : toto lment 1 : 3 lment 2 : 1 lment 3 : PHP largument n3 = PHP

165

Chapitre 3

Le langage PHP

Le passage de paramtres par rfrence


Lorsque lon passe une variable en paramtre une fonction, la variable transmise na quune porte locale, et la variable manipule au sein de la fonction nest en fait quune copie de la variable transmise par le programme appelant. Ainsi, lexcution de la fonction nentrane aucune modification sur la variable transmise. Lorsque lon souhaite que la fonction modifie la valeur de la variable passe en paramtre, celle-ci doit tre passe non pas par valeur mais par rfrence. Lorsquune variable est passe en rfrence, la nouvelle variable locale ainsi cre pointe sur la mme zone mmoire, mais avec un autre nom que le paramtre. Ainsi, on a un alias de la variable qui se cre dans la fonction, et toutes les modifications qui lui seront apportes seront rpercutes sur loriginal.

3. Le langage PHP

Ce nest toutefois pas lappelant qui dcide si la variable doit tre passe par valeur ou par rfrence, mais la fonction. Ainsi, pour utiliser une rfrence, il suffit simplement de signaler le paramtre de la fonction avec un "&" devant le nom de la variable.
<? $phrase = "Ceci est temporaire"; function citation(&$reference, $nom, $prenom) { $reference = $nom." ".$prenom. " a crit : Les crivains ont mis la langue en libert." } citation($phrase, "Victor", "Hugo"); echo $phrase; // affiche "Victor Hugo a crit : Les crivains ont mis la langue en libert." ?>

Dans lexemple prcdent, nous pouvons constater que les modifications apportes la variable locale $reference se rpercutent sur la variable globale $phrase.

Utilisation des paramtres de type objet Comme nous le verrons dans le chapitre sur la programmation oriente objet, contrairement au comportement dautres langages de programmation, dans les versions de PHP infrieure la version 5 (incluant le moteur Zend2), les objets ne sont pas automatiquement passs par rfrence. Pour ne pas travailler sur une copie de lobjet il est donc, l aussi, ncessaire dutiliser le "et commercial" &.

PHP 5 Avec PHP 5, il est dsormais possible de spcifier une valeur par dfaut l o lon attend un argument pass par rfrence.
function maFonction(&$param = "valeurParDefaut")

Alors que, vous laurez devin, ce ntait pas possible auparavant.

166

Les fonctions

Retourner une valeur


Vous serez sans doute amen vouloir rcuprer le contenu dune variable la suite du traitement dune fonction. Pour effectuer le renvoi dune variable et ainsi terminer lexcution de la fonction, le langage PHP utilise le mot-cl return. Lorsque cette instruction est rencontre, la fonction value la valeur de la variable qui suit et la renvoie dans le programme principal. Exemple dutilisation :
return $valRetour; return 0; return "Laurent";

3. Le langage PHP

Ce qui donne dans le cas dune utilisation :


<?php function fonctionRetour() { return "guitare"; } echo fonctionRetour(); // affiche "guitare" ?>

Sil est possible de placer plusieurs instructions return lintrieur dune fonction, le premier return excut met un terme lexcution de la fonction.
<?php function associationNom($varATester) { if ($varATester=="Laurent") { return "GUEDON"; } elseif ($varATester =="Damien" || $varATester == "Thomas") { return "HEUTE"; } elseif ($varATester =="Pierre-Emmanuel") { return "MULLER"; } else { return "Qui ???"; } } ?>

Linstruction return ne permet de renvoyer quune seule valeur. Si vous souhaitez retourner plusieurs valeurs, deux possibilits soffrent vous :
j j

Retourner un tableau de valeurs ou un objet avec plusieurs attributs. Utiliser plusieurs paramtres passs par rfrence (qui serviront donc plus de valeur retour que de valeur dentre) ; ventuellement, la fonction pourra galement retourner une valeur via return.

Il nest pas vraiment possible de dire a priori quelle est la bonne mthode. Cest un peu au cas par cas. La premire oblige ensuite analyser le contenu dun tableau (et lutilisation dun objet

167

Chapitre 3

Le langage PHP

ne se justifie pas toujours). La seconde mthode nest pas totalement satisfaisante, puisque lon mlange paramtres dentre et paramtres de sortie ; a contrario, elle permet de rserver la valeur retour pour un boolen indiquant si lopration sest bien passe ou non. Voici un exemple utilisant un tableau montrant comment sortir de ce problme, que vous rencontrerez sans doute dans votre carrire de dveloppeur.
<?php function discotheque($choix) { switch ($choix) { case 1 : $artiste = "Placebo"; $titre = "Where is my mind"; break; case 2 : $artiste = "Emiliana Torrini"; $titre = "To be free"; defaut : $artiste = "Radiohead"; $titre = "Creep"; } return array($artiste, $titre); } $disque = discotheque(3); echo "Artiste ".$disque[0] ."\n"; echo "Titre ".$disque[1] ."\n"; ?>

3. Le langage PHP

Ici, la fonction retourne un tableau de valeurs. Il est donc ensuite possible de traiter le tableau et de sortir les diffrentes donnes, comme si la fonction nous avait renvoy plusieurs variables. Le rsultat du petit programme ci-dessus nous donne donc :
Artiste Radiohead Titre Creep

Manipuler des fonctions


Une srie de commandes permet de crer la vole, de tester lexistence des fonctions et de les manipuler. Lune delle permet de crer des fonctions dites anonymes.

create_function()
Permet de crer une fonction anonyme partir de paramtres.

168

Les fonctions

Syntaxe $arguments $code retour

string create_function(string $arguments ,string $code ) Liste des paramtres de la fonction spars par une virgule. Le code de la fonction. Nom attribu la fonction (en sassurant de son unicit).

<?php $fonction = create_function($a,$b,return $a + $b;); echo "Nom de la nouvelle fonction : $fonction<br />"; echo "10 + 5 = ".$fonction(10, 5); // "Nom de la nouvelle fonction : lambda_1" // "10 + 5 = 15" ?>

3. Le langage PHP

retourne
Nom de la nouvelle fonction: lambda_1 10 + 5 = 15

Notez que vous pouvez utiliser des guillemets ( la place des apostrophes) dans la dfinition des arguments et du code de la fonction, condition de ne pas oublier dchapper le caractre $ prcdant les noms de variables comme ceci :
$fonction = create_function("\$a,\$b","return \$a + \$b;");

Il est galement possible de vrifier si une fonction existe ou non. Ceci permet notamment de vrifier si lenvironnement (version de PHP, options de configuration) dans lequel tourne le script permet la ralisation de lopration prvue. Ceci peut galement permettre de crer une fonction mulant une fonction existant dans les dernires versions de PHP, uniquement si celle-ci nest pas disponible dans la version utilise (afin que le script puisse fonctionner sur danciennes versions).

function_exists()
Permet de vrifier si une fonction existe bien. Syntaxe $nomFonction retour boolean function_exists(function $nomFonction) Nom de la fonction vrifier. Retourne TRUE si la fonction a t trouve, FALSE sinon.

<?php if (function_exists("uneFonctionDontJAiBesoin")) { echo "Chouette je peux utiliser la fonction<br />"; uneFonctionDontJAiBesoin(); } else { echo "La fonction nexiste pas tant pis pour vous<br />"; }

169

Chapitre 3

Le langage PHP

if (function_exists("function_exists")) { echo "Par contre la fonction function_exists() existe<br />"; } else { echo "Curieux<br />"; }

retournera
La fonction nexiste pas tant pis pour vous Par contre la fonction function_exists() existe

3. Le langage PHP

On peut aussi simplement lister toutes les fonctions dfinies laide de la fonction get_defined_functions().

get_dened_functions()
Liste toutes les fonctions dfinies. Syntaxe retour array get_defined_functions(void) Tableau associatif contenant les cls. "internal" ayant pour valeur un tableau index contenant les noms des fonctions PHP "natives". "user" ayant pour valeur un tableau index contenant les noms des fonctions dfinies par lutilisateur.
<?php function fonction1($a, $b) { return ($a + $b); } function fonction2($a) { return $a; } function fonction3($a, $b) { return ($a + $b); } function fonction4($a, $b, $c) { return ($a + $b + $c); } function fonction5($a, $b, $c, $d) {

170

Les fonctions

return ($a + $b + $c + $d); } $tableauFonction = get_defined_functions(); print_r($tableauFonction); ?>

Cela affiche toutes les fonctions sous la forme dun tableau de tableaux.
Array ( [internal] => Array ( [0] => zend_version [1] => func_num_args [2] => func_get_arg ...... [1161] => apache_note [1162] => apache_lookup_uri [1163] => apache_child_terminate ) [user] => Array ( [0] => fonction1 [1] => fonction2 [2] => fonction3 [3] => fonction4 [4] => fonction5 ) )

3. Le langage PHP

Listons simplement les fonctions utilisateurs.


<?php while(list ($key, $val)=each($tableauFonction["user"])) { echo "$key => $val<br />"; } ?>

Le rsultat cette fois est simplement :


0 1 2 3 4 => => => => => fonction1 fonction2 fonction3 fonction4 fonction5

Les fonctions utilisateurs peuvent aussi tre appeles laide des commandes call_user_func_array() ou call_user_func(). Ces commandes sont trs utiles lorsquun programme doit faire appel diffrentes fonctions dynamiquement.

171

Chapitre 3

Le langage PHP

call_user_func()
Appelle une fonction utilisateur en lui transmettant des paramtres. Syntaxe $nomFonction $parametre retour mixed call_user_func(string $nomFonction [, mixed $parametre [, mixed ...]]) Nom de la fonction appeler. Liste des paramtres ( transmettre dans le mme ordre que sa dclaration). Renvoie le code retour de la fonction appele.

3. Le langage PHP

call_user_func_array()
Appelle une fonction utilisateur en lui transmettant des paramtres rassembls sous la forme dun tableau. Syntaxe $nomFonction $parametre retour mixed call_user_func_array(string $nomFonction [, array $parametre]) Nom de la fonction appeler. Liste des paramtres ( transmettre sous la forme dun tableau). Renvoie le code retour de la fonction appele.

<?php function nombreCaractere($phrase) { return strlen ($phrase); } echo "phrase 1 = ".call_user_func(nombreCaractere, Ich bin ein Berliner! - JF Kennedy(1963))." caractres<br />"; echo "phrase 2 = ".call_user_func(nombreCaractere, 13 janvier 1898, Zola publia Jaccuse)." caractres<br />"; ?>

Le rsultat de ce programme affiche ici :


phrase 1 = 40 caractres phrase 2 = 38 caractres <?php function function function function fonction1($a, fonction2($a, fonction3($a, fonction4($a, $b) $b) $b) $b) { { { { return return return return $a+$b; $a-$b; $a*$b; $a/$b; } } } }

$tableau = array(10,5);

172

Les fonctions

for ($i=1;$i<=4;$i++) { echo "$i => ".call_user_func_array(fonction.$i, $tableau)."<br />"; } ?> 1 2 3 4 => => => => 15 5 50 2

La rcursivit des fonctions


Une fonction est dite rcursive si elle sappelle elle-mme. Cette utilisation particulire des fonctions est rare (ce qui, entre nous, nest pas forcment un dfaut, car elle est trs gourmande en mmoire.). Et pourtant, si elle nest pas indispensable, elle peut-tre trs pratique lorsquil faut traiter certains problmes comme le parcours dune arborescence. Un exemple de fonction rcursive est celui de la fonction donnant le factoriel dun nombre.
<?php function factorielle($nombre) { if ($nombre==0) { return "1"."<br />"; }else{ return $nombre*factorielle($nombre-1)."<br />"; } } echo factorielle (3); // 3! = 1x2x3 = 6 echo factorielle (3); // 3! = 1x2x3 = 6 ?>

3. Le langage PHP

Juste un exemple... de ce quil ne faut pas faire Si cette mthode est la plus simple pour montrer ce quest une fonction factorielle, cest aussi la plus mauvaise mthode pour implmenter factoriel. De plus, les fonctions rcursives sont trs dlicates manipuler. Il est trs important de vrifier que votre fonction se termine bien un moment donn pour viter des problmes de boucles infinies.
Un des exemples de fonctions rcursives les plus rpandus est la rsolution du problme de la tour de Hano. La tour de Hano se prsente comme un casse-tte. Plusieurs disques sont empils sur une tige, du plus large au plus petit. Deux autres tiges se trouvent ct et le but est de dplacer les disques pour les superposer sur la tige centrale dans le mme ordre, cest--dire du plus grand au plus petit.

173

Chapitre 3

Le langage PHP

Figure 3.9 : La tour de Hano

3. Le langage PHP

<html> <body> <?php function deplaceDisque($disque, $tige1, $tige2) { echo "Dplacer le disque ".$disque." sur la tige ".$tige2."<br />"; } function hanoi($disque, $tige1, $tige2) { if ($disque == 1) // si le disque dplacer est le premier { // on ne fait quun dplacement deplaceDisque (1, $tige1, $tige2); }else{ // sinon il faut dplacer $disque-1 // sur la tige diffrente de $tige1 et $tige2 hanoi($disque-1, $tige1, 3-$tige1-$tige2); deplaceDisque ($disque, $tige1, $tige2); // et on redplace les ($disque-1) disques sur le disque dplac hanoi($disque-1, 3-$tige1-$tige2, $tige2); } } hanoi(4, 0, 1); ?> </body> </html> // 4 disques utiliss

3.8.
j

Les tableaux
Les tableaux indexs o chaque lment du tableau porte un numro (ce qui correspond la reprsentation habituelle dun tableau dans les autres langages de programmation). Par dfaut, la numrotation commence avec lindice 0. Les tableaux associatifs o chaque lment du tableau est associ une cl reprsente par une chane de caractres (ce qui correspond peu de choses prs une table de hash dans les autres langages de programmation).

En PHP, il est possible de distinguer trois types de tableaux.

174

Les tableaux

Les tableaux mixtes o chaque lment du tableau est associ aussi bien un indice qu une cl.

Cette distinction entre les tableaux est surtout "conceptuelle". En effet, leur mode de fonctionnement est totalement identique.

Index et ordre dans le tableau Les index doivent tre perus simplement comme des cls de type entier. La valeur dun index ne prjuge pas de la position dun lment dans le tableau. Un lment peut avoir un index gal 0 et se trouver en fin de tableau. Un tableau est juste un ensemble (ordonn) de couple (cl, valeur).

3. Le langage PHP

Les valeurs dun tableau


Les valeurs contenues dans un tableau peuvent tre de tout type connu. Ainsi, un tableau peut stocker des entiers, des rels, des chanes de caractres, des tableaux, des objets, etc. De plus, les types des valeurs contenues dans un tableau peuvent varier dun indice (ou dune cl) lautre. Le second lment dun tableau pourra contenir une chane de caractres, mme si le premier lment contient un objet.

Initialisation dun tableau


La syntaxe de base de linitialisation dun tableau est la suivante :
$monTableau = array();

Mais, part pour forcer le type dune variable au type tableau, il est bien rare que nous utilisions cette forme pure. Linitialisation du tableau se fait gnralement en mme temps que son remplissage. Ainsi, dans le cas "classique" dun tableau index, on pourra par exemple prciser les valeurs associes aux trois premiers index par :
$monTableau = array(23, "PHP", 12.4);

Ce qui donnera alors :


$monTableau[0] = 23; $monTableau[1] = "PHP"; $monTableau[2] = "12.4";

Dans le cas dun tableau associatif, il faudra prciser la cl et la valeur selon le schma suivant :
$tableauAge = array("Pierre" => 22, "Thierry" => 29, "Jean" => 34);

175

Chapitre 3

Le langage PHP

Pour obtenir :
$tableauAge["Pierre"] = 22; $tableauAge["Thierry"] = 29; $tableauAge["Jean"] = 34;

Et pour un tableau mixte il est possible de prciser :


$monTableau = array("Thierry", 29, "Prnom" => "Thierry", "Age" => 29);

Ce qui donnerait :

3. Le langage PHP

$monTableau[0] = "Thierry"; $monTableau[1] = 29; $monTableau["Prnom"] = "Thierry"; $monTableau["Age"] = 29;

Cas dutilisation des tableaux mixtes Les tableaux mixtes sont utiliss en particulier pour la lecture des enregistrements dune base de donnes. Ainsi, lutilisateur peut faire appel la valeur dun champ soit partir de son index soit partir du nom du champ.

Les subtilits dinitialisation dun tableau


Mme dans le cas dun tableau index, il est possible de prciser pour quel indice vous tes en train de dfinir la valeur ( la manire des tableaux associatifs).
$monTableau = array(1 => "Valeur1", 3 => "Valeur3");

donnera les valeurs suivantes :


$monTableau[1] = "Valeur1"; $monTableau[3] = "Valeur3";
$monTableau[0] et $monTableau[2], quant eux, nauront pas de valeur affecte.

Ordre daffectation Il nest pas ncessaire de prciser les valeurs dans lordre des indices. Ainsi
$monTableau = array(3 => "Valeur3", 1 => "Valeur1");

est tout fait valide.


L encore, il est possible, lors de linitialisation dun tableau, de mlanger cette notation avec celle dun tableau associatif, et mme avec la notation "traditionnelle" dun tableau index. Dans ce dernier cas, les valeurs pour lesquelles on ne prcise pas les index auront ncessairement pour index le dernier index affect + 1 (ou par dfaut 0).
$monTableau = array("Valeur0", 2 => "Valeur2", "Valeur3");

176

Les tableaux

donnera :
$monTableau[0] = "Valeur0"; $monTableau[2] = "Valeur2"; $monTableau[3] = "Valeur3";

Commencer un tableau lindice 1 Cette proprit est bien pratique pour commencer un tableau avec lindice 1.
$monTableau(1 => "Valeur1", "Valeur2", "Valeur3");

3. Le langage PHP

Dans le cas dun tableau index ou associatif, si, dans la chane dinitialisation, plusieurs valeurs sont affectes un mme indice ou une mme cl, la valeur conserve sera toujours la dernire rencontre. Ainsi,
$monTableau = array("Valeur qui va se faire craser", 0 => "Oups... jcrase");

donnera :
$monTableau[0] = "Oups... jcrase";

Remplissage dun tableau


Dune manire tout fait classique, le remplissage (o laffectation des valeurs) dun tableau se fait par un appel du type :
$monTableau[0] = "Valeur";

ou
$monTableau["cle"] = "Valeur";

Mais une des particularits du langage PHP est que la taille des tableaux nest pas fixe. Elle peut donc tre augmente au fil des besoins. Ainsi, pour un tableau index qui a t initialis avec trois lments, il est possible daffecter une valeur llment dindice 10, comme le montre lexemple suivant :
<?php $monTableau = array("valeur1, "valeur2", "valeur3"); $monTableau[10] = "valeur10", ?>

De mme, pour un tableau associatif, il est toujours possible dajouter un lment avec une nouvelle cl. Cela est particulirement utile pour composer une liste dlments. De plus, pour simplifier la tche, le langage PHP nous permet de ne pas prciser dindice ou de cl lors dune affectation, ceci afin dutiliser pour indice le dernier indice affect + 1.

177

Chapitre 3

Le langage PHP

$monTableau[] = "Valeur dindice 0"; $monTableau[] = "Valeur dindice 1";

sera alors quivalent :


$monTableau[0] = "Valeur dindice 0"; $monTableau[1] = "Valeur dindice 1";

Les fonctions de manipulation des tableaux


3. Le langage PHP
Il existe de nombreuses fonctions lies au traitement des tableaux. Certaines sont destines au parcours du tableau, dautres la fusion de tableaux, dautres encore au tri des valeurs ou des cls, etc. Vous dcouvrirez galement dans le chapitre ddi la programmation oriente objet "Les classes, les objets" quil existe galement des objets permettant la manipulation de tableaux.

Fonctions de base

is_array()
Indique si une variable est de type tableau. Syntaxe $variable retour boolean is_array(mixed $variable) Variable tester. TRUE si la variable est de type tableau, FALSE sinon.

count()
Retourne le nombre dlments contenus dans un tableau. Syntaxe $tableau retour int count(array $tableau) Le tableau dont on veut compter le nombre dlments. Le nombre dlments du tableau. Si toutefois le paramtre fourni ne correspond pas un tableau mais une variable existante, alors la valeur retourne est 1. Sil sagit dune variable qui nexiste pas, la fonction retourne 0.

Sil sagit dun tableau index avec des valeurs pour chaque index partir de 0, alors on pourra afficher son contenu grce au code suivant :
<?php $monTableau = array ("PHP", "Cest", "vraiment", "sympa"); for ($i=0; $i<count($monTableau); $i++) echo $monTableau[$i]."<br />"; ?>

178

Les tableaux

La fonction print_r() La fonction print_r() est galement une instruction fort pratique pour visualiser le contenu dun tableau (principalement titre de dbogage).

sizeof()
Est lquivalent de count() (mme syntaxe, mme comportement).

3. Le langage PHP

array_values()
Retourne un tableau index contenant les valeurs des lments dun tableau donn (ce qui peut permettre de rindexer un tableau ou de convertir un tableau associatif en tableau index). Syntaxe $tableau retour array array_values(array $tableau) Tableau de rfrence. Tableau index des valeurs trouves dans $tableau.

Voir aussi array_keys(), qui peut tre utilis pour faire des recherches dans un tableau.

array_unique()
Retourne un tableau dans lequel aucune valeur napparat plusieurs fois (associes diffrentes cls). Syntaxe $tableau retour array array_unique(array $tableau) Tableau de rfrence. Tableau dans lequel chaque valeur napparat quune seule fois. Cest toujours la dernire cl associe une valeur donne qui est conserve.

array_ip()
Intervertit les rles des cls (ou index) et des valeurs dun tableau. Cette fonction nest applicable que si les valeurs peuvent devenir des cls ou, autrement dit, si les valeurs sont des chanes de caractres ou des entiers.

179

Chapitre 3

Le langage PHP

Si le tableau possde plusieurs valeurs identiques, seule la dernire paire (cl, valeur) sera considre. Syntaxe $tableau retour array array_flip(array $tableau) Tableau pour lequel cls et valeurs doivent tre permutes. Tableau pour lequel les cls et les valeurs ont t permutes, ou FALSE en cas dchec.

3. Le langage PHP

array_rand()
Retourne un index (ou une cl) ou un tableau dindex (ou de cls) distincts pris pseudo-alatoirement dans un tableau. Syntaxe $tableau $nbCles retour mixed array_rand(array $tableau, [int $nbCles]) Tableau sur lequel seffectue la recherche. Nombre de cls ou index retourner (par dfaut le nombre de cls est fix 1). Un index (ou une cl) ou un tableau dindex (ou de cls) distincts pris pseudo-alatoirement dans le tableau.

Pseudo-alatoire Comme pour toutes les fonctions pseudo-alatoires, il est fortement conseill de faire au pralable un appel la fonction srand() pour "taper" un peu nimporte o dans la pile des nombres pseudo-alatoires.

Vous pouvez vous reporter au chapitre "Les fonctions mathmatiques" pour plus de dtails sur les nombres pseudo-alatoires et la fonction srand().

Fonctions de recherche dans les tableaux

array_keys()
Retourne un tableau index contenant les cls et index utiliss dans un tableau donn ou, ventuellement, les cls et index associs une valeur donne. Syntaxe $tableau array array_keys(array $tableau [, mixed $valeur]) Tableau de rfrence.

180

Les tableaux

$valeur

Argument optionnel prcisant quelle valeur doivent tre associs les cls et index retourns. Par dfaut, ce sont tous les index et cls du tableau qui sont retourns. Tableau des cls et index trouvs ou un tableau vide si la valeur nest pas trouve.

retour

Listing 3.11 : array_array_keys.php


<?php $sportifs = array("Z. Zidane" => "Foot", "C. Moreau" => "Cyclisme", "T. Henry" => "Foot", "M. Indurain" => "Cyclisme", "J. Durand" => "Cyclisme", "T. Marie" => "Cyclisme"); $cyclistes = array_keys($sportifs, "Cyclisme"); echo "Voici une liste de cyclistes <br />"; for ($i=0; $i<count($cyclistes); $i++) { echo $cyclistes[$i]."<br />"; } ?>

3. Le langage PHP

retournera bien les noms associs au cyclisme. Voici une liste de cyclistes C. Moreau M. Indurain J. Durand T. Marie

array_search()
Retourne la premire cl (ou index) du tableau, associe une valeur donne. Syntaxe $valeur $tableau $strict mixed array_search(mixed $valeur, array $tableau [,boolean $strict]) Valeur recherche. Tableau sur lequel se porte la recherche. Argument optionnel positionner TRUE si lon veut que la comparaison tienne galement compte du type de la valeur cherche. FALSE, par dfaut. Cl (ou index) trouve, FALSE sinon.

retour

181

Chapitre 3

Le langage PHP

array_key_exists()
Indique si un tableau contient ou non une cl donne. Syntaxe $cle $tableau retour boolean array_key_exists(mixed $cle, array $tableau) Cl recherche. Tableau sur lequel se porte la recherche. TRUE si lindex existe, FALSE sinon.

3. Le langage PHP

in_array()
Indique si un tableau contient ou non une valeur donne. Syntaxe $valeur $tableau $strict boolean in_array(mixed $valeur, array $tableau [, boolean $strict]) Valeur recherche. Tableau sur lequel se porte la recherche. Argument optionnel positionner TRUE si lon veut que la comparaison tienne galement compte du type de la valeur cherche. FALSE, par dfaut. TRUE si la valeur a t trouve dans $tableau. FALSE sinon.

retour

Fonctions de manipulation de portions de tableau

range()
Retourne un tableau compos des entiers compris entre une valeur de dbut et une valeur de fin. Syntaxe $debut $fin retour array range(int $debut, int $fin) Premier entier du tableau. Dernier entier du tableau (doit ncessairement tre suprieur ou gal $debut). Tableau compos des entiers compris entre la valeur de dbut (incluse) et la valeur de fin (inclus) ou bien un tableau vide en cas dchec.

182

Les tableaux

array_ll()
Retourne un tableau index construit partir de la rptition dune valeur. Syntaxe $indexDebut $nombre $valeur retour array array_fill(int $indexDebut, int $nombre, mixed $valeur) Premier index du tableau. Nombre dlments dans le tableau. Valeur donner chaque lment du tableau. Tableau index de $indexDebut $indexDebut+$nombre1 ne contenant que la valeur $valeur.

3. Le langage PHP

array_pad()
Retourne un tableau complt ( droite ou gauche) avec une valeur donne pour atteindre un nombre total dlments spcifis. Syntaxe $tableau $taille array array_pad(array $tableau, int $taille, mixed $valeur) Tableau de rfrence. Taille (en valeur absolue) souhaite pour le tableau rsultat. Si vous souhaitez complter le tableau gauche, indiquez alors la valeur en ngatif. Valeur utiliser pour complter le tableau. Retourne le tableau spcifi, complt par la valeur pour atteindre la taille demande. Si celle-ci (en valeur absolue) est infrieure la taille initiale du tableau, ce dernier nest tout simplement pas complt, mais sa taille nen est pas pour autant rduite.

$valeur retour

array_slice()
Retourne un tableau extrait dun autre tableau. Syntaxe $tableau $debut array array_slice(array $tableau, int $debut [, int $longueur]) Tableau de rfrence. Numro dordre du premier lment du tableau extraire. Au premier lment du tableau correspond le numro 0. Ce numro dordre est indpendant de lindex (en particulier aprs un appel la fonction array_reverse() avec comme second argument la valeur TRUE, llment dindex 0 peut se retrouver en fin de tableau). Si $debut est ngatif, alors le compte se fait en partant de la fin du tableau.

183

Chapitre 3

Le langage PHP

$longueur

Argument optionnel prcisant le nombre dlments extraire. Par dfaut, ce sont tous les lments suivants du tableau qui sont extraits. Si $longueur est ngatif, ce sont tous les lments jusqu llment qui se trouve abs($longueur) de la fin qui sont extraits. Tableau des lments extraits. Les cls sont conserves mais pas les index.

retour

Listing 3.12 : array_array_slice.php


<?php $tableau = array("cle" => "element0", 2 => "element1", 1 => "element2");

3. Le langage PHP

print_r(array_slice($tableau, 0, 2)); ?>

retourne par exemple : Array ( [cle] => element0 [0] => element1 )

array_splice()
Supprime les lments dun tableau ; ventuellement, insre des lments dans le tableau et retourne le tableau des lments supprims. Syntaxe $tableau $debut array array_splice(array $tableau, int $debut [, int $longueur [, array $remplacement]]) Tableau modifier. Numro dordre du premier lment du tableau supprimer. Au premier lment du tableau correspond le numro 0. Ce numro dordre est indpendant de lindex (en particulier aprs un appel la fonction array_reverse() avec comme second argument la valeur TRUE, llment dindex 0 peut se retrouver en fin de tableau). Si $debut est ngatif, alors le compte se fait en partant de la fin du tableau. Argument optionnel prcisant le nombre dlments supprimer. Par dfaut, ce sont tous les lments suivants du tableau qui sont supprims. Si $longueur est ngatif, ce sont tous les lments jusqu llment qui se trouve abs($longueur) de la fin qui sont supprims. Tableau optionnel contenant les valeurs insrer dans le tableau partir de llment point par $dbut. Si le nombre dlments insrs est suprieur au nombre dlments supprims, alors le reste du tableau est dcal. Dans ce cas, les cls sont conserves mais pas les index. Par dfaut, les lments sont simplement supprims. Tableau des lments supprims.

$longueur

$remplacement

retour

184

Les tableaux

array_chunk()
Retourne un tableau index ayant pour valeurs les morceaux dun tableau dcoup en morceaux. Syntaxe $tableau $taille $mode array array_chunk(array $tableau, int $taille [, boolean $mode]) Tableau dcouper en morceaux. Taille des morceaux (nombre dlments). Prcise si les cls du tableau doivent tre conserves :

3. Le langage PHP

TRUE, les cls sont conserves. FALSE (valeur par dfaut), chaque morceau de tableau est rindex en commenant par 0. retour Tableau index contenant des tableaux issus de la dcoupe en morceaux du tableau dentre.

Fonctions de manipulation des cls dun tableau

array_change_key_case()
Retourne un tableau avec la casse des cls modifie. Syntaxe $tableau $casse array array_change_key_case(array $tableau [, int $casse]) Tableau de rfrence. Au choix, lune des deux constantes suivantes : CASE_LOWER (valeur par dfaut), pour mettre toutes les cls en minuscules. CASE_UPPER, pour mettre toutes les cls en majuscules. retour Tableau avec tous les index en majuscules ou minuscules.

Fonctions de conversion tableau <-> variable

list()
Construit une liste de variables partir des donnes dun tableau. Ce nest pas une vritable fonction, puisquelle sutilise de la faon suivante :

185

Chapitre 3

Le langage PHP

list($variable1, $variable2, ...) = $tableau

Syntaxe $variable1 $variable2 ...

void list(mixed $variable1 [,mixed $variable2, ...]) Variable laquelle doit tre affecte la premire valeur du tableau. Variable laquelle doit tre affecte la seconde valeur du tableau. etc.

extract()
3. Le langage PHP
Construit une liste de variables partir des donnes dun tableau, les noms des variables tant bass sur les cls du tableau. Syntaxe $tableau $modeExtraction int extract(array $tableau [, int $modeExtraction [, string $prefixe]]) Tableau (associatif) dont on veut se servir pour crer des variables. Argument optionnel indiquant quelle stratgie adopter, principalement si la variable que lon souhaite crer existe dj. Cet argument peut prendre une valeur parmi : EXTR_OVERWRITE (valeur par dfaut) remplace la valeur de la variable par la valeur trouve dans le tableau si la cl correspond une variable existante. EXTR_SKIP ignore llment rencontr si la cl correspond une variable existante. EXTR_PREFIX_SAME fait prcder le nom de la variable par $prefixe si la cl correspond une variable existante. EXTR_PREFIX_ALL fait systmatiquement prcder le nom de la variable par $prefixe. EXTR_PREFIX_INVALID fait prcder le nom de la variable par $prefixe si la cl ne permet pas de crer un nom de variable valide (par exemple si la cl est en fait un index). $prefixe Argument optionnel prciser si $modeExtraction prend lune des valeurs suivantes : EXTR_PREFIX_SAME, EXTR_PREFIX_ALL, EXTR_PREFIX_INVALID. Nombre de variables gnres.

retour

compact()
Retourne un tableau associatif cr partir des noms de variables (qui seront les cls du tableau) et de leurs valeurs.

186

Les tableaux

Syntaxe $variable1, ...

array compact(string $variable1 [, string $variable2, ...]) Noms des variables ajouter au tableau. Ces arguments peuvent, en fait, galement tre des tableaux contenant des chanes de caractres prcisant des noms de variables (ou des tableaux). Chaque argument sous forme de tableau est trait de faon rcursive. Tableau associatif contenant lensemble des paires (cl, valeur) correspondant aux noms de variables donns.

retour

Fonctions de parcours de tableau


Les tableaux tant en fait des listes de couples (cl, valeur) ou (index, valeur), ils peuvent tre parcourus non pas uniquement en sappuyant sur les cls ou les index, mais galement grce un pointeur se dplaant dans la liste.

3. Le langage PHP

current()
Retourne la valeur actuellement pointe par le pointeur interne du tableau (sans avancer le pointeur). Syntaxe $tableau retour mixed current(array $tableau) Tableau parcourir. Valeur actuellement pointe par le pointeur interne de $tableau. FALSE si le pointeur est en dehors du tableau.

pos()
quivalent de current().

key()
Retourne la cl (ou index) de llment actuellement point par le pointeur interne du tableau (sans avancer le pointeur). Syntaxe $tableau retour mixed key(array $tableau) Tableau parcourir. Cl (ou index) de llment actuellement point par le pointeur interne de $tableau. FALSE si le pointeur est en dehors du tableau.

187

Chapitre 3

Le langage PHP

reset()
Remet le pointeur interne au dbut du tableau et retourne le premier lment. Syntaxe $tableau retour mixed reset(array $tableau) Tableau parcourir. Premier lment du tableau. FALSE si le tableau est vide.

3. Le langage PHP

next()
Avance le pointeur interne du tableau et retourne le nouvel lment point. Syntaxe $tableau retour mixed next(array $tableau) Tableau parcourir. lment suivant du tableau. FALSE si lon a dpass la fin du tableau.

Listing 3.13 : array_next.php


<?php // Exemple de parcours dun tableau // avec le pointeur interne et la fonction // next(); $tableau = array( "Dbut", "", "Milieu", 0, "Fin"); // Ici, lappel reset() nest pas ncessaire // puisque aprs initialisation le pointeur // de tableau est au debut. $valeur = reset($tableau); // Tant que valeur est diffrente de FALSE // ATTENTION: // 1 - Bien prendre soin de mettre les 2 signes = // afin de comparer galement les types // car 0 == FALSE (mme valeur) // alors que 0 !== FALSE (mme valeur mais pas mme type) // 2 - Ce type de parcours nest valable // que si le tableau ne possde aucun // lment valant FALSE while ($valeur !== FALSE) { echo "$valeur<br />"; $valeur = next($tableau); } ?>

188

Les tableaux

aura pour effet dafficher : Dbut


Milieu 0 Fin

prev()
Recule le pointeur interne du tableau et retourne le nouvel lment point. Syntaxe $tableau retour mixed prev(array $tableau) Tableau parcourir. lment prcdent du tableau. FALSE si le dbut du tableau a t dplac.

3. Le langage PHP

end()
Place le pointeur interne la fin du tableau et retourne le dernier lment. Syntaxe $tableau retour mixed end(array $tableau) Tableau parcourir. Dernier lment du tableau. FALSE si le tableau est vide.

each()
Retourne un tableau contenant la cl et la valeur de llment actuellement point par le pointeur interne du tableau, puis avance le pointeur. Syntaxe $tableau retour array each(array $tableau) Tableau parcourir. Tableau compos de quatre lments. llment dindex 0 et llment de cl "key" est associe la cl (ou lindex) de llment point. llment dindex 1 et llment de cl "value" est associe la valeur de llment point. FALSE si la fin du tableau est dpasse.

each() et list() un duo trs apprci en concurrence avec foreach Le tableau issu de lappel each() est souvent associ list() afin de manipuler de simples chanes plutt que des tableaux selon le shma list($cle, $valeur) = each ($tableau);. Ainsi, les tableaux sont souvent parcourus de la faon suivante : 189

Chapitre 3

Le langage PHP

reset($tableau); while (list($cle, $valeur) = each($tableau)) { echo "A la cl $cle est associ la valeur $valeur<br />"; }

Une autre solution consiste utiliser foreach. Mais il est galement possible de le faire de la faon suivante :
foreach($tableau as $cle => $valeur) echo "A la cl $cle est associe la valeur $valeur<br />";

3. Le langage PHP

Fonctions de gestion de piles


Il est possible dutiliser les tableaux PHP comme des piles, cest--dire comme des listes dans lesquelles sempilent les lments et auxquelles on peut accder en prenant le premier ou le dernier lment.

array_push()
Ajoute un ou plusieurs lments la fin du tableau (au-dessus de la pile). Syntaxe $tableau $valeur1, ... retour int array_push(array $tableau, mixed $valeur1, [mixed $valeur2, ...]) Tableau auquel vous souhaitez ajouter des lments. Valeurs (ou donnes) que vous souhaitez ajouter au tableau. Retourne le nombre dlments du tableau aprs ajout.

quivalent de array_push() la valeur retour prs, array_push($tableau, $valeur1) quivaut


$tableau[] = $valeur1;

array_pop()
Retourne et supprime le dernier lment du tableau (celui du dessus de la pile). Syntaxe $tableau retour mixed array_pop(array $tableau) Tableau que lon veut "dpiler". Le dernier lment du tableau ou NULL si le tableau est vide (ou si largument nest pas un tableau).

190

Les tableaux

array_unshift()
Ajoute un ou plusieurs lments au dbut du tableau (au bas de la pile). Syntaxe $tableau $valeur1, ... retour int array_unshift(array $tableau, mixed $valeur1, [mixed $valeur2, ...]) Tableau auquel vous souhaitez ajouter des lments. Valeurs (ou donnes) que vous souhaitez ajouter au tableau. La premire valeur donne correspondra la premire valeur du tableau rsultat. Retourne le nombre dlments du tableau aprs ajout.

3. Le langage PHP

array_shift()
Retourne et supprime le premier lment du tableau (celui du bas de la pile). Syntaxe $tableau retour mixed array_shift(array $tableau) Tableau que lon veut "dpiler" par le bas. Le premier lment du tableau ou NULL si le tableau est vide (ou si largument nest pas un tableau).

Fonctions de tri
Tri inverse

array_reverse()
Retourne un tableau avec les valeurs dans lordre inverse de celui spcifi. Syntaxe $tableau $avecCle array array_reverse(array $tableau, [boolean $avecCle]) Tableau de rfrence. Argument optionnel positionner TRUE si lassociation cl->valeur doit tre conserve (pour un tableau index, les valeurs conserveront galement leur index). Par dfaut $avecCle = FALSE ; le tableau rsultat est alors obligatoirement un tableau index entre 0 et la taille du tableau -1. Retourne le tableau spcifi avec les valeurs classes dans lordre inverse.

retour

191

Chapitre 3

Le langage PHP

Tri selon lordre croissant des valeurs

sort()
Trie les lments dun tableau dans lordre croissant des valeurs. Les cls (ou index) ne sont pas conserves ; le tableau devient obligatoirement un tableau index entre 0 et la taille du tableau-1. Syntaxe void sort(array $tableau) Tableau trier.

3. Le langage PHP

$tableau

Listing 3.14 : array_sort.php


<?php $tableauVille = array("Circuit" => "Le Mans", "Braderie" => "Lille", "Horloge" => "Rouen", "Place Stanislas" => "Nancy"); sort($tableauVille); for ($i=0; $i<count($tableauVille); $i++) { echo $i." - ".$tableauVille[$i]."<br />"; } ?>

affichera
0 1 2 3 Le Mans Lille Nancy Rouen

asort()
Trie les lments dun tableau dans lordre croissant des valeurs, tout en conservant lassociation cl => valeur. Syntaxe $tableau void asort(array $tableau) Tableau trier.

natsort()
Trie les lments dun tableau dans lordre croissant, dit "naturel", des valeurs. Ce tri ne se contente pas de comparer les chanes de caractres, caractre par caractre, mais distingue les parties numriques des parties alphabtiques. Ainsi, dans lordre "naturel", "mot2" apparat

192

Les tableaux

avant "mot10". Les cls ou index ne sont pas conservs ; le tableau devient obligatoirement un tableau index entre 0 et la taille du tableau-1. Syntaxe $tableau void natsort(array $tableau) Tableau trier.

natcasesort()
Trie les lments dun tableau dans lordre croissant, dit "naturel", des valeurs sans tenir compte de la casse. Ce tri ne se contente pas de comparer les chanes de caractres, caractre par caractre, mais distingue les parties numriques des parties alphabtiques. Ainsi, dans lordre "naturel", "mot2" apparat avant "mot10". Les cls ou index ne sont pas conservs ; le tableau devient obligatoirement un tableau index entre 0 et la taille du tableau -1. Syntaxe $tableau void natcasesort(array $tableau) Tableau trier.

3. Le langage PHP

natsort(), natcasesort() et ordre dcroissant Les fonctions natsort() et natcasesort() ne proposent pas dquivalent pour un tri dcroissant. Pour un tel tri, vous devrez faire appel natsort() ou natcasesort() puis $tableau = array_reverse($tableau);.

Tri selon lordre dcroissant des valeurs

rsort()
Trie les tableaux dans lordre dcroissant des valeurs. Les cls (ou index) ne sont pas conserves ; le tableau devient obligatoirement un tableau index entre 0 et la taille du tableau-1. Syntaxe $tableau void rsort(array $tableau) Tableau trier.

Voir lexemple associ la fonction sort().

arsort()
Trie les lments dun tableau dans lordre dcroissant des valeurs, tout en conservant lassociation cl => valeur.

193

Chapitre 3

Le langage PHP

Syntaxe $tableau

void arsort(array $tableau) Tableau trier.

Tri personnalis des valeurs

usort()
3. Le langage PHP
Trie les lments dun tableau dans lordre croissant des valeurs, en dterminant lordre des valeurs partir dune fonction dfinie par lutilisateur. Les cls (ou index) ne sont pas conserves ; le tableau devient obligatoirement un tableau index entre 0 et la taille du tableau-1. Syntaxe $tableau boolean usort(array $tableau, fonction $fonctionComparaison) Tableau trier.

$fonctionComparaison Nom de la fonction utiliser pour comparer les valeurs. Cette fonction doit accepter deux arguments et retourner : 0 en cas dgalit, 1 en cas de supriorit du premier argument sur le deuxime et 1 sinon. boolean TRUE.

Listing 3.15 : array_usort.php


<?php function maFonction($valeur1, $valeur2) { // La fonction suivante retourne // un pourcentage de similarit entre // les 2 chanes de caractres. // On pourra ainsi dire[ ]laquelle des 2 chanes // des 2 valeurs se rapproche le plus // de "Etretat" $s1 = similar_text($valeur1, "Etretat"); $s2 = similar_text($valeur2, "Etretat"); if ($s1 == $s2) return 0; return ($s1 > $s2) ? -1 : 1; } $tableauMot = array("Etat", "Etretat", "Etretot", "Arrete"); // Tri du plus proche du mot "Etretat" // au plus loign. usort($tableauMot, "maFonction"); print_r($tableauMot); ?>

retourne bien les lments du tableau du plus proche du mot "Etretat" au plus loign. Array ( [0] => Etretat [1] => Etretot [2] => Etat [3] => Arrete )

194

Les tableaux

Cas dutilisation Ce type de fonction est particulirement utile dans le cas dune mthode de comparaison un peu complexe (comme lorsque, dans lexemple, il sagit de calculer la similarit entre chanes de caractres), et surtout lorsque les lments du tableau sont des objets et que les comparaisons sappliquent sur les attributs de lobjet.

uasort()
3. Le langage PHP
Trie les lments dun tableau dans lordre croissant des valeurs, en dterminant lordre des valeurs partir dune fonction dfinie par lutilisateur. Les cls (ou index) ne sont pas conserves ; le tableau devient obligatoirement un tableau index entre 0 et la taille du tableau-1. Syntaxe $tableau boolean uasort(array $tableau, fonction $fonctionComparaison) Tableau trier.

$fonctionComparaison Nom de la fonction utiliser pour comparer les valeurs. Cette fonction doit accepter deux arguments et retourner : 0 en cas dgalit, 1 en cas de supriorit du premier argument sur le deuxime et 1 sinon. retour TRUE.

Tri selon lordre croissant des cls

ksort()
Trie les lments dun tableau dans lordre croissant des cls, tout en conservant lassociation cl => valeur. Syntaxe $tableau retour boolean ksort(array $tableau) Tableau trier. TRUE.

Tri selon lordre dcroissant des cls

krsort()
Trie les tableaux dans lordre dcroissant des cls, tout en conservant lassociation cl => valeur.

195

Chapitre 3

Le langage PHP

Syntaxe $tableau retour

boolean krsort(array $tableau) Tableau trier. TRUE.

Tri personnalis des cls

uksort()
3. Le langage PHP
Trie les lments dun tableau dans lordre croissant des cls, en dterminant lordre des cls partir dune fonction dfinie par lutilisateur. Syntaxe $tableau boolean uksort(array $tableau, fonction $fonctionComparaison) Tableau trier.

$fonctionComparaison Nom de la fonction utiliser pour comparer les cls. Cette fonction doit accepter deux arguments et retourner : 0 en cas dgalit, 1 en cas de supriorit du premier argument sur le deuxime et 1 sinon. retour TRUE.

Voir lexemple associ la fonction usort().

Tri sur des tableaux lis

array_multisort()
Trie les lments des tableaux selon lordre du premier tableau indiqu. Syntaxe $tableau1 $mode1 boolean array_multisort(array $tableau1 [,int $mode1] [, int $mode2] , array $tableau2 [, array $tableau3]) Tableau trier prendre comme rfrence pour le tri. Sens de tri. SORT_ASC pour un tri croissant. SORT_DESC pour un tri dcroissant. $mode2 Option de tri: SORT_REGULAR pour une comparaison "traditionnelle" des valeurs. SORT_NUMERIC pour une comparaison numrique des valeurs. SORT_STRING pour une comparaison alphabtique des valeurs. $tableau2, ... Tableaux sur lesquels les permutations effectues sur $tableau1 doivent tre rpercutes.

196

Les tableaux

Listing 3.16 : array_array_multisort.php


<?php // Exemple de 2 tableaux lis // Nom et Notes doivent toujours correspondre ... $eleves = array("Pierre", "Jean", "Henri", "Odille"); $notes = array(12, 15, 13, 10); // ... et pourtant on voudrait trier // selon les prnoms des lves. array_multisort($eleves, $notes);

3. Le langage PHP

echo "<b>Elves</b>:"; print_r($eleves); echo "<br />"; echo "<b>Notes</b>:"; print_r($notes); echo "<br />"; // ... ou encore selon lordre dcroissant // des notes. array_multisort($notes, SORT_DESC, $eleves); echo "<br />"; echo "<b>Elves</b>:"; print_r($eleves); echo "<br />"; echo "<b>Notes</b>:"; print_r($notes); ?>

affichera
Elves:Array ( [0] => Henri [1] => Jean [2] => Odille [3] => Pierre ) Notes:Array ( [0] => 13 [1] => 15 [2] => 10 [3] => 12 ) Elves:Array ( [0] => Jean [1] => Henri [2] => Pierre [3] => Odille ) Notes:Array ( [0] => 15 [1] => 13 [2] => 12 [3] => 10 )

197

Chapitre 3

Le langage PHP

Tri alatoire

shuffle()
Trie les lments dun tableau dans lordre.... alatoire. Autrement dit, mlange les lments dun tableau. Les cls (ou index) ne sont pas conserves ; le tableau devient obligatoirement un tableau index entre 0 et la taille du tableau -1. Syntaxe $tableau boolean shuffle(array $tableau) Tableau mlanger. TRUE.

3. Le langage PHP

retour

Fonctions de statistiques
Il existe quatre fonctions que lon peut assimiler des fonctions de statistiques.

array_sum()
Retourne la somme des valeurs des lments dun tableau (fort pratique pour calculer les moyennes). Syntaxe $tableau retour mixed array_sum(array $tableau) Tableau sur lequel doit seffectuer lopration. La somme des valeurs des lments du tableau, de type entier ou rel, selon le contenu du tableau.

array_count_values()
Retourne un tableau prcisant le nombre doccurrences dune valeur dans un tableau donn. Syntaxe $tableau retour array array_count_values(array $tableau) Tableau sur lequel doit seffectuer lopration. Tableau associatif ayant comme cls les valeurs du tableau sur lequel a t effectue lopration et comme valeur le nombre doccurrences de la cl.

Listing 3.17 : array_array_count_values


<?php $tableauNote = array ("Pierre" => 10, "Marcel" => 12, "Franck" => 10, "Jean" => 10, "Marie" => 15, "Cecile" => 12);

198

Les tableaux

$stats = array_count_values($tableauNote); echo "A ce devoir ...<br />\n"; while (list($note, $nb) = each($stats)) { echo "$nb lves ont eu $note<br />"; } ?>

donnera le rsultat
A 3 2 1 ce devoir ... lves ont eu 10 lves ont eu 12 lves ont eu 15

3. Le langage PHP

(nous vous laissons le soin damliorer ce script pour traiter le cas o $nb = 1).

Voir aussi les fonctions min() et max() dveloppes dans le chapitre "Les fonctions mathmatiques".

Fonctions mettant en uvre plusieurs tableaux


Comparaison de tableaux

array_diff()
Retourne un tableau prsentant les valeurs contenues dans un tableau, mais absentes dautres tableaux. Syntaxe $tableau1 $tableau2, ... retour array array_diff(array $tableau1, array $tableau2, [array $tableau3, ...]) Tableau dont on veut comparer le contenu avec ceux des autres tableaux. Tableaux dans lesquels on recherche lventuelle prsence des valeurs du tableau 1. Tableau prsentant toutes les valeurs contenues dans $tableau1 et qui nont t trouves dans aucun des autres tableaux prciss. Les cls sont conserves (identiques celle de $tableau1).

array_intersect()
Retourne un tableau prsentant les valeurs contenues dans un tableau et dans un ensemble dautres tableaux.

199

Chapitre 3

Le langage PHP

Syntaxe $tableau1 $tableau2, ... retour

array array_intersect(array $tableau1, array $tableau2, [array $tableau3, ...]) Tableau dont on veut comparer le contenu avec ceux des autres tableaux. Tableaux dans lesquels on recherche lventuelle prsence des valeurs du tableau 1. Tableau prsentant toutes les valeurs contenues dans $tableau1 et qui ont t trouves dans tous les autres tableaux prciss. Les cls sont conserves (identiques celle de $tableau1). Sil ny a pas de valeurs communes alors cest un tableau vide qui est retourn.

3. Le langage PHP

array_intersect_assoc()
Retourne un tableau prsentant les valeurs et les cls associes celle-ci, contenues dans un tableau et dans un ensemble dautres tableaux. Syntaxe : $tableau1 $tableau2, ... retour array array_intersect_assoc(array $tableau1, array $tableau2, [array $tableau3, ...]) Tableau dont on veut comparer le contenu avec ceux des autres tableaux. Tableaux dans lesquels on recherche lventuelle prsence des valeurs du tableau 1. Tableau prsentant toutes les valeurs et les clefs contenues dans $tableau1 et qui ont t trouves dans tous les autres tableaux prciss. Les cls sont conserves (identiques celle de $tableau1).

<?php $tableau1 = array(0=>"Belgique", 1=>"France", 2=>"Italie", 3=>"Suisse"); $tableau2 = array(1=>"France", 3=>"Italie", 2=>"Irlande"); $tableauFinal = array_intersect_assoc($tableau1, $tableau2); print_r($tableauFinal); ?> Array ( 1 => France )

Fusion de tableaux

array_merge()
Retourne un tableau issu de la fusion dun ensemble de tableaux.

200

Les tableaux

Syntaxe $tableau1, ... retour

array array_merge(array $tableau1, array $tableau2, [array $tableau3, ...]) Les tableaux fusionner. Tableau prsentant toutes les valeurs contenues dans les diffrents tableaux. Au fil du parcours des tableaux fusionner, les valeurs ont t ajoutes la fin du tableau rsultat. Les valeurs lies des cls peuvent tre crases si la cl est rencontre plusieurs fois.

array_merge_recursive()
Retourne un tableau issu de la fusion dun ensemble de tableaux. Dans ce cas, si une cl donne est rencontre plusieurs fois, la valeur dans le tableau rsultat ne sera pas la dernire valeur rencontre, mais la fusion (dans un tableau) des valeurs rencontres. Syntaxe $tableau1, ... retour array array_merge_recursive(array $tableau1, array $tableau2, [array $tableau3, ...]) Les tableaux fusionner. Tableau prsentant toutes les valeurs contenues dans les diffrents tableaux. Au fil du parcours des tableaux fusionner, les valeurs ont t ajoutes la fin du tableau rsultat. Les valeurs lies des cls rencontres plusieurs fois sont regroupes dans un tableau.

3. Le langage PHP

Listing 3.18 : array_array_merge_recursive.php


<?php $agenda1 = array("Lundi" => "Mdecin", "Mardi" => "Coiffeur"); $agenda2 = array("Mardi" => "Runion", "Vendredi" => "VTT"); $agenda = array_merge_recursive($agenda1, $agenda2); print_r($agenda); ?>

Voil comment fusionner intelligemment deux agendas...


Array ( [Lundi] => Mdecin [Mardi] => Array ( [0] => Coiffeur [1] => Runion ) [Vendredi] => VTT )

Fonctions de traitement personnalis des tableaux

array_lter()
Retourne un tableau filtr partir dune fonction crite par lutilisateur.

201

Chapitre 3

Le langage PHP

Syntaxe $tableau $fonctionFiltre

array array_filter(array $tableau [, function $fonctionFiltre]) Tableau filtrer. Fonction appeler pour dterminer si llment doit tre conserv ou non dans le tableau rsultat. Cette fonction doit prendre en compte un argument, et retourner TRUE si llment doit tre conserv, FALSE sinon. Ce paramtre est (curieusement) optionnel. Si aucune fonction de filtrage nest fournie, alors le tableau est restitu tel quel. Retourne le tableau dentre sans les lments qui ont t indiqus, par la fonction $fonctionFiltre, comme tant filtrer. Les cls et index du tableau sont conservs.

retour

3. Le langage PHP

Listing 3.19 : array_array_filter.php


<?php // Exemple de filtre qui ne conserve que les // prnoms commenant par M function monFiltre($prenom) { return ($prenom[0] == "M"); } $prenoms = array("Stphane", "Marie", "Thierry", "Abi", "Christophe", "Manu", "Anne"); print_r(array_filter($prenoms , "monFiltre")); ?>

ne conserve bien que les prnoms commenant par M.


Array ( [1] => Marie [5] => Manu )

array_map()
Retourne un tableau issu du rsultat de lapplication dune fonction crite par lutilisateur, et prenant en compte les donnes dun ou de plusieurs tableaux. Syntaxe $fonction array array_map(function $fonction, array $tableau1 [, array $tableau2, ...]) Fonction appeler pour chaque lment des tableaux $tableau1, $tableau2, etc. Cette fonction doit prendre en compte autant darguments que de tableaux fournis. Tableaux contenant les valeurs sur lesquelles doit sappliquer la fonction. Si certains tableaux sont moins longs que le plus grand des tableaux, des valeurs nulles compltent ces tableaux. Ces tableaux sont traits dans lordre de leurs lments (et non de leur index).

$tableau1, ...

202

Les tableaux

retour

Tableau index de la taille du plus grand des tableaux passs en paramtre et ayant pour valeurs le rsultat de la fonction applique aux lments des tableaux passs en paramtre.

Listing 3.20 : array_array_map.php


<?php // // // // Exemple de 2 tableaux servant stocker des coordonnes Cest pas aussi beau que la programmation objet mais des fois a dpanne

$tabX = array (1, 5, 2, 4); $tabY = array (10, 2, 3, 2);

3. Le langage PHP

// Exemple dune fonction permettant // le calcul de la distance entre un point // et le centre (0, 0) function distance($x, $y) { return sqrt($x*$x + $y*$y); } // Et, hop, dun simple appel // array_map jai mes distances // pour tous les points. print_r(array_map("distance", $tabX, $tabY)); ?>

retournera le tableau des distances suivant :


Array ( [0] => 10.049875621121 [1] => 5.3851648071345 [2] => 3.605551275464 [3] => 4.4721359549996 )

array_reduce()
Retourne le rsultat dune opration dfinie par lutilisateur, applique itrativement sur lensemble des valeurs dun tableau. Syntaxe $tableau $fonction mixed array_reduce(array $tableau, function $fonction [,int $valeurInitiale]) Tableau contenant les valeurs sur lesquelles doivent seffectuer lopration. Fonction appeler itrativement sur chaque lment du tableau. Cette fonction doit prendre en compte deux arguments, le premier tant le rsultat du calcul trouv jusque-l, le second tant la valeur prendre en compte pour la poursuite du calcul. La fonction doit retourner le nouveau rsultat obtenu.

203

Chapitre 3

Le langage PHP

$valeurInitiale retour

Argument optionnel, prcisant la valeur initiale utilise pour le calcul. Par dfaut $valeurInitiale = 0. Le rsultat du calcul voire la valeur initiale si le tableau est vide.

Listing 3.21 : array_array_reduce.php


<?php // // // // // // // // // // Calcul de P(x0) o P polynme P(x) = x^4 + 2x^3 + x^2 + 4x + 6 = (((x + 2)*x + 1)*x +4)*x + 6 Soit le calcul itratif Resultat = 1 Resultat = Resultat*x0 + 2 Resultat = Resultat*x0 + 1 Resultat = Resultat*x0 + 4 Resultat = Resultat*x0 + 6

3. Le langage PHP

// Ainsi avec le tableau des coefficients $tabCoef = array(2, 1, 4, 6); // et la chtite fonction function polynome($resultat, $coef) { $x0=5; // Calcul pour x0=5; return $resultat*$x0 + $coef; } // Jai mon rsultat echo "P(5)=".array_reduce($tabCoef, "polynome", 1); ?>

Si vous souhaitez vraiment le savoir, cela retourne :


P(5)=926

array_walk()
Appelle une fonction utilisateur sur chaque lment dun tableau. Syntaxe $tableau $fonction boolean array_walk(array $tableau, function $fonction [, mixed $argument]) Tableau contenant les valeurs sur lesquelles doivent seffectuer les oprations. Fonction appeler pour chaque lment du tableau. Cette fonction doit prendre en compte deux arguments (ou trois si $argument est spcifi), le premier argument tant la valeur de llment actuellement considr,

204

Les tableaux

le second tant la cl (ou index) de llment actuellement considr. Le troisime argument prendra la valeur de $argument). Attention ! il nest pas possible dans ce cas dappeler une fonction PHP, vous devez ncessairement crer votre propre fonction. $argument retour Argument optionnel, pass en troisime paramtre de la fonction utilisateur. TRUE si lopration sest bien passe, FALSE sinon.

Passage par valeur Noubliez pas que, par dfaut, les paramtres passs aux fonctions le sont par valeur. Si vous souhaitez utiliser array_walk() pour modifier les valeurs du tableau, noubliez pas dutiliser une interface similaire mafonction(&$valeur, $cl).

3. Le langage PHP

Listing 3.22 : array_array_walk.php


<?php $menu = array ("Accueil", "Forum", "A propos"); // Fonction pour afficher le contenu // du menu avec lindex et un sparateur function affiche($valeur, $key, $separateur) { echo ($key+1)." $separateur ".$valeur."<br />"; } // Fonction pour modifier les tiquettes // du menu function patch(&$valeur, $key) { $valeur="[".$valeur."]"; } // Affiche le menu array_walk($menu, "affiche", "-"); // Patche le menu array_walk($menu, "patch"); // ce qui donne le rsultat print_r($menu); ?>

retournera
1 - Accueil 2 - Forum 3 - A propos Array ( [0] => [Accueil] [1] => [Forum] [2] => [A propos] )

205

Chapitre 3

Le langage PHP

3.9.

Les inclusions de chiers

Le langage PHP permet dinsrer, dans un script, du code qui provient dun (ou de plusieurs) autres fichiers. Pour cela, PHP propose quatre fonctions (ou plutt, instructions) :
j j
require(); include();

et leurs variantes, depuis PHP 4.0.1,

3. Le langage PHP

j j

require_once(); include_once().

Ces instructions sont gnralement utilises pour intgrer des scripts dans lesquels des objets ou des fonctions rutilisables ont t dfinis (dans ce cas, les fichiers inclus font office de bibliothques de fonctions), ou bien pour intgrer des portions de code contenant les paramtres du script (dans ce cas, les fichiers inclus font office de fichiers de configuration).

Listing 3.23 : include_01.php


<?php // Inclut les paramtres include("include_01a.php"); // Inclut les fonctions include("include_01b.php"); monEcho($maChaine); ?>

Listing 3.24 : include_01a.php


<?php // Exemple de fichier de configuration // vraiment minimaliste $maChaine = "Bonjour tout le monde"; ?>

Listing 3.25 : include_01b.php


<?php // Exemple de bibliothque de fonctions // encore une fois bien minimaliste function monEcho($chaine)

206

Les inclusions de fichiers

{ echo $chaine; } ?>

sera alors quivalent (commentaires exclus) :

Listing 3.26 : include_01equiv.php


<?php $maChaine = "Bonjour tout le monde"; function monEcho($chaine) { echo $chaine; } monEcho($maChaine); ?>

3. Le langage PHP

Fonction ou instruction ? require() et include() ne sont pas de vritables fonctions, et lon peut aussi bien crire :
j j
include("nom de fichier"); include "nom de fichier";

Ces instructions peuvent tre utilises de faon conditionnelle ou bien encore dans des boucles, comme le montrent les exemples suivants :

Listing 3.27 : include_02.php


Je suis le script principal<br /> je vais tenter dinsrer les scripts<br /> aprs avoir test leur existence<br /> <?php if (file_exists("include_02a.php")) { include("include_02a.php"); } if (file_exists("fichierinconnu.php")) { include("fichierinconnu.php"); } ?>

207

Chapitre 3

Le langage PHP

Listing 3.28 : include_02a.php


* Je suis un simple script inclure nomm include_02a.php

affichera :
Je suis le script principal je vais tenter dinsrer les scripts aprs avoir test leur existence * Je suis un simple script inclure nomm include_02a.php

3. Le langage PHP

Le tout sans gnrer derreur, puisque le script principal ne tentera jamais dinclure le fichier inexistant.

Accolades ncessaires Notez la prsence des accolades qui dfinissent le bloc contenant uniquement linstruction include. Ces accolades sont ncessaires, il ne faut donc pas les omettre.

Listing 3.29 : include_03.php


Je suis le script principal<br /> je vais tenter dinsrer un script en boucle<br /> <?php for ($i=0; $i<3; $i++) { include("include_03a.php"); } ?>

Listing 3.30 : include_03a.php


* Je suis un simple script inclure nomm include_03a.php<br />

affichera, quant lui :


Je suis le script principal je vais tenter dinsrer un script en boucle aprs avoir test leur existence * Je suis un simple script inclure nomm include_03a.php * Je suis un simple script inclure nomm include_03a.php * Je suis un simple script inclure nomm include_03a.php

volution de linstruction require() Mme si cela ntait pas vrai auparavant pour linstruction require(), depuis la version 4.0.2, les fonctions require() et include() se comportent sensiblement de la mme faon (la commande require() stant rallie au comportement de la commande include()).

208

Les inclusions de fichiers

Comme cela se devine dans les exemples prcdents, les scripts insrs commencent sur la base dun texte brut (ou code HTML) ; il faudra donc rouvrir les balises PHP pour les portions de code PHP. De ce fait, les scripts insrs sont similaires aux scripts principaux.

Inclusions multiples
Il peut arriver que, sans vritablement le vouloir, un script soit inclus plusieurs fois. Cela arrive notamment lorsquun script A inclut un script B et un script C, alors que le script B lui-mme inclut le script C (cest gnralement ce qui arrive si les rgles de codage ne sont pas suffisamment claires sur ce point). Si le script inclus de multiples fois contient des dclarations de fonctions (ou dobjets) alors, invitablement, vous vous retrouverez avec un message derreur indiquant que la fonction (ou lobjet) a dj t dfinie. Afin de vous affranchir de ce problme, vous pouvez faire appel linstruction include_once() ou require_once() afin de ninclure le script quau premier appel. Ainsi, si lon reprend lexemple prcdent avec include_once(), cela donnera :

3. Le langage PHP

Listing 3.31 : include_04.php


Je suis le script principal<br /> je vais tenter dinsrer un script en boucle<br /> <?php for ($i=0; $i<3; $i++) { include_once("include_03a.php"); } ?>

et affichera seulement :
Je suis le script principal je vais tenter dinsrer un script en boucle aprs avoir test leur existence * Je suis un simple script inclure nomm include_03a.php

Notez, cette occasion, quil est tout moment possible de connatre la liste des fichiers inclus grce la fonction get_included_files() (ou son alias get_required_files()).

get_included_les()
Retourne la liste des fichiers inclus. Syntaxe retour array get_included_files(void) Tableau index contenant la liste des noms complets (chemins absolus) des fichiers inclus par include(), require(), include_once() ou require_once(). Les noms des fichiers inclus plusieurs fois napparaissent quune fois.

209

Chapitre 3

Le langage PHP

Les noms des chiers inclus


Les noms des fichiers inclus peuvent porter nimporte quelle extension. Mais, dans la pratique, il faut tre prudent et bien choisir son extension. Nous vous conseillons une extension "_inc.php".

Extension des fichiers inclus et risques de piratage Si vous ne donnez pas lextension .php, les fichiers inclus, sils sont accds directement, ne seront pas interprts et livreront tous leurs secrets. En effet, si, par exemple, votre script principal inclut un fichier nomm config.in" et quun pirate connat lexistence de ce fichier, il pourra lappeler directement depuis son navigateur et lire simplement son contenu, comme pour tout bon fichier texte (et il y trouvera certainement des choses intressantes du genre $motdepasse = secret;). Sil sagit dun fichier contenant des fonctions ou des classes, le pirate pourra rcuprer votre code source (et votre savoir-faire). Et pourtant, le moyen de se protger est trs simple : si vous ajoutez simplement lextension .php vos scripts inclus, le code PHP, avant dtre envoy au navigateur du pirate, sera interprt, et le pirate ne pourra lire que le rsultat de linterprtation (gnralement un simple page blanche, puisque par exemple $motdepasse = secret; naffichera rien).

3. Le langage PHP

Les chiers insrs distants


Les fichiers insrer sont gnralement sur le mme serveur que le script principal, mais il est galement possible dinsrer un fichier situ sur un autre serveur. Pour cela, il suffit de prciser lURL complte du fichier, par exemple http://www.php.net/chemin/ condition toutefois que la directive de compilation fichier.html, disableurlfopenwrapper nait pas t utilise. Il est noter que, dans ce cas, si vous appelez un script PHP, seul le rsultat de linterprtation du script par le serveur distant sera inclus dans le script principal (et non le code source du script inclus).

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur la compilation de PHP. Ouf ! Nous sommes protgs La remarque prcdente est importante. Elle implique que, tant que vous utilisez lextension .php et que votre serveur interprte les fichiers .php, un pirate ne peut pas esprer lire vos fichiers de configuration par un simple include("http: //www.serveurquejaimeraispirater.com/fichierconfig.php");.

210

Les inclusions de fichiers

Le passage de paramtres
Les fichiers tant tout btement intgrs dans le script principal, les variables globales qui auront t dfinies avant les commandes include() ou require() seront accessibles par les scripts intgrs. Et, rciproquement, les variables globales dfinies (ou modifies) dans les fichiers inclus (interprts localement) seront accessibles par les fichiers inclus suivants ainsi que par le script principal. Ainsi, si le script inclus ncessite un certain nombre de paramtres, il nest pas ncessaire (et cela ne fonctionnera pas) de faire :
<?php include("fichier_inc.php?parametre1=valeur1&parametre2=valeur2") ?>

3. Le langage PHP

mais plutt :
<?php $parametre1 = valeur1; $parametre2 = valeur2; include("fichier_inc.php"); ?>

Le seul cas o, dans un include(), on peut tre amen passer des paramtres, cest celui o le fichier inclus est un script PHP distant qui ncessite des paramtres. Cest un cas bien particulier, puisqualors le script inclus sera interprt par le serveur distant avant dtre inclus (et non inclus tel quel dans le script principal).
<?php include("http://www.php.net/script.php?param1=valeur1"); ?>

Les chemins relatifs


Les chemins prciss dans ces commandes, sils ne sont pas absolus, sont toujours relatifs au script en cours dexcution. Cela peut, premire vue, paratre banal, mais, cest en fait lourd de consquences. Si votre script principal.php du projet projet est stock dans un rpertoire projet et quil inclut un script inclus1_inc.php de la bibliothque biblio stock dans un rpertoire biblio, vous serez tent de mettre la commande include("../biblio/inclus1_inc.php"). vrai dire, jusque-l, tout va bien. Mais si votre script inclus1_inc.php a besoin dun autre fichier inclus2_inc.php (disons) de la mme bibliothque, ce dernier aura probablement utilis la commande include("inclus2_inc.php"). Et cest l le problme. Si vous dcidez dexcuter le script inclus1_inc.php, cela fonctionnera parfaitement. Mais, pour le script principal.php le chemin prcis dans la commande include de inclus1_inc.php sera relatif au script en cours (relatif au rpertoire projet). Autrement dit, on va chercher inclus2_inc .php sous projet et non sous ../biblio, ce qui, de toute vidence, ne fonctionnera pas.

211

Chapitre 3

Le langage PHP

Cela voudrait dire que, pour corriger le problme, nous devrions remplacer le chemin prcis dans inclus1_inc.php par un chemin relatif projet. En dautre termes, remplacer include("inclus2_inc.php") par include("../biblio/inclus2_inc.php"). Toutefois, cela est insatisfaisant plus dun titre. 1. 2. 3. la lecture de la bibliothque biblio cette rfrence ../biblio est plutt incongrue. Cette solution ne serait pas satisfaisante pour un projet situ dans un autre niveau darborescence. Lappel direct inclus1_inc.php fonctionne toujours, mais uniquement parce que nous avons pris un cas de figure plutt simple (projet et biblio sont au mme niveau darborescence).

Pour pallier ce problme, nous avons deux solutions possibles :

3. Le langage PHP

j j

Modifier le paramtre include_path. Toujours utiliser des chemins absolus.

Le paramtre include_path est un paramtre du fichier php.ini qui indique o aller chercher le fichier inclure. Ce paramtre dfinit une liste de chemins spars par des : sous Linux/ UNIX, mais par des ; sous Windows. Dans ce cas, il vous faudra modifier le fichier php.ini pour chaque bibliothque ajoute (et pour chacun des serveurs).

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini.
Ce paramtre include_path peut toutefois tre modifi au niveau du script (avant de faire lappel include() ou require()) grce la fonction ini_set(), selon le modle ini_set("include_path","<nouvelle liste de rpertoires>");.

Construction automatique de chemins absolus premire vue, lide de toujours prciser des chemins absolus lorsque lon dsire inclure des fichiers peut sembler extrmement contraignante. En effet, cela signifie, en thorie, que si lon souhaite dplacer lespace hbergeant lensemble des scripts (ou installer les scripts sur une autre machine proposant une autre arborescence), tous les chemins seront modifier. Mais heureusement, en pratique, il est possible de construire dynamiquement ces chemins absolus. En effet, la constante __FILE__ retourne le chemin absolu et le nom du fichier inclus. Le chemin absolu du fichier ayant un chemin relatif (au fichier inclus) cheminRelatif/fichier.php sera alors :
dirname(__FILE__)."/cheminRelatif/fichier.php"

Il suffit donc de remplacer lintuitif


include("cheminRelatif/fichier.php");

par
include(dirname(__FILE__)."/cheminRelatif/fichier.php").

212

Les inclusions de fichiers

Cas derreur et code retour


Si le script inclure nest pas trouv alors :
j j

Linstruction include() gnrera un message derreur de type "alerte" (WARNING) et le droulement du script principal se poursuivra. Linstruction require() gnrera un message derreur de type "fatale" (FATAL) et le droulement du script principal sinterrompra.

Si une erreur est leve (mme une erreur de type "fatale") dans un script inclus, cela ninterrompt pas pour autant lexcution du script principal (que ce soit avec include() ou require()).

3. Le langage PHP

Linstruction include() retourne un code derreur, ce qui nest pas le cas de linstruction
require().

Par dfaut, le code retour de linstruction include() est : TRUE en cas de succs et FALSE en cas dchec. Mais il est galement possible de gnrer son propre code retour (en cas de succs de linclusion) en sortant du script inclus par linstruction return() suivie de la valeur retourner (comme nous le ferions pour une simple fonction).

Listing 3.32 : include_05.php


<?php $retour = include("include_05_inc.php"); echo "Code retourn par le fichier inclus = $retour<br />"; ?>

Listing 3.33 : include_05_inc.php


<?php echo "* Je suis le fichier inclus,<br />"; echo "je me contente dafficher ce message<br />"; echo "et de retourner 5<br />"; return 5; ?>

affichera donc :
* Je suis le fichier inclus, je me contente dafficher ce message et de retourner 5 Code retourn par le fichier inclus = 5

Diffrences entre include() et require() Depuis la version 4.0.2, les instructions include() et require() ne diffrent que sur deux des points voqus dans ce chapitre :
j j

Comportement en cas dinexistence du fichier inclure ; Prsence ou non dun code retour.

213

Chapitre 3

Le langage PHP

Un cas dutilisation pratique mais potentiellement dangereux


La fonction include() est souvent utilise pour muler lutilisation de frames sans faire appel la balise HTML <frame>. Dans ce cas, la page principale du site contient, gnralement, un en-tte, un ou des menus (dans un bandeau suprieur, gauche ou droit), le contenu et, ventuellement, une ligne de copyright. Le tout pouvant prendre la forme dun tableau, o , quasiment, seule la partie "contenu" change (dune page lautre). Lide consiste alors fournir au script principal un paramtre indiquant quelle page de contenu afficher (techniquement, cela consiste en un simple include). Ce qui donne peu de choses prs (je vous laisse fignoler) le code suivant :

Listing 3.34 : include_frame01.php

3. Le langage PHP

<html> <body> <table width="100%"> <tr><td colspan="3" align="center">Entte</td></tr> <tr><td>Menu Gauche</td> <td> <?php include($_GET["url"]); ?> </td> <td>Menu Droit</td> </tr> <tr><td colspan="3" align="center">Copyright</td></tr> </table> </body> </html>

qui pourra tre appel comme suit :


include_frame01.php?url="accueil.html" include_frame01.php?url="mavie.html

Pourquoi viter la balise <frame> ? Le problme que lon peut rencontrer en utilisant des frames HTML est li au fait que ce qui apparat dans le navigateur nest pas le rsultat de linterprtation dune seule URL mais de plusieurs (celle qui dfinit les frames et celles qui dfinissent leur contenu). Ainsi, les moteurs de recherche, lorsquils indexent des sites contenant des frames, ne font pas de distinction entre ces diffrentes URL ce qui bien souvent les amne proposer une rorientation vers une des frames hors de son contexte, masquant gnralement la frame qui contient le menu principal, et empchant ainsi la navigation sur le site. Il existe de nombreux moyens de contourner ce problme : lutilisation du Javascript en est un, mais lidal est certainement de navoir quune page unique.

214

Les inclusions de fichiers

Cependant, ce type dimplmentation pose de srieux problmes de scurit. En effet, rien nempche un pirate dappeler lui-mme
include_frame01.php?url=http://www.sitedupirate.com/scriptmechant.txt.

Et si scriptmechant.txt affiche (mais nexcute pas) un texte contenant un script PHP, ce script sera excut sur VOTRE serveur au moment de linclude. Le pirate pourra alors faire ce que bon lui semble sur VOTRE serveur, commencer par excuter une commande afin darchiver du code source de votre site (et rcuprer ainsi vos mots de passe daccs la base de donnes). Dans ce cas de figure, la premire prcaution prendre consiste donc empcher linclusion de fichiers distants. Une solution simple et doublement utile consiste faire prcder la commande include() dun test dexistence du fichier par file_exists(). Cela vous vitera, dune part, de tenter dinclure des fichiers qui nexistent pas et, dautre part, comme file_exists() retourne FALSE dans le cas de fichiers distants, dinclure de tels fichiers.

3. Le langage PHP

Listing 3.35 : include_frame02.php


<html> <body> <table width="100%"> <tr><td colspan="3" align="center">Entte</td></tr> <tr><td>Menu Gauche</td> <td> <?php if (file_exists($_GET["url"])) include($_GET["url"]); ?> </td> <td>Menu Droit</td> </tr> <tr><td colspan="3" align="center">Copyright</td></tr> </table> </body> </html>

Vous voil rassur ? Eh bien, vous avez tort ! Ce nest pas parce que le fichier est sur votre serveur et quil existe (et quil est accessible depuis votre compte) que vous tes labri. Eh oui, les pirates sont de petits malins (cest dailleurs bien souvent par dfi que les pirates svissent). La plupart des serveurs web sont configurs pour tracer les vnements ( titre statistique ou de surveillance). Avec Apache, les fichiers de traces sont, par dfaut, access_log et error_log : ils contiennent gnralement (selon la configuration) lURL de la page demande, ladresse IP du client, etc. Lun est destin aux accs russis, lautre aux accs ayant chous. videmment, ces fichiers sont lisibles par le serveur et un appel file_exists() sur ces fichiers retournera TRUE. Si le pirate fait pointer $url sur ces fichiers, ils seront donc inclus. Vous me direz "oui, mais quest-ce que a va lui apporter de lire le contenu de ce fichier ?". premire vue rien, sinon que... je vous lai dit, ils sont malins !. Il lui suffit de trouver le moyen dinclure dans ces fichiers (et plutt dans le fichier error_log) le code PHP quil souhaite excuter. Pour cela, il suffit quil appelle une URL bidon dans laquelle il intgre le code (ex. : http://www.siteattaque.com/<moncode>). Et voil, le tour est jou !

215

Chapitre 3

Le langage PHP

Conclusion, il faut galement sassurer que le fichier inclus ne pourra tre, dune manire ou dune autre, un fichier altr par un pirate (ex. : contenu dun livre dor sil est stock dans un fichier et non dans une base de donnes). Si vous ne crez aucun fichier (style livre dor) dans lespace de votre serveur, vous pouvez alors certainement vous protger de ce type dattaque en remplaant le test prcdant par
if (eregi("^".$_SERVER["DOCUMENT_ROOT"], realPath($url))) ...

qui

vrifiera

que

le

chemin

rel

de

lURL

spcifie

commence

bien

par

$_SERVER["DOCUMENT_ROOT"] (la racine du serveur web).

3. Le langage PHP

Les pirates Noubliez pas : il y a probablement plus de mauvais administrateurs rseaux et de mauvais programmeurs que de pirates mal intentionns. De plus, les attaques que lon peut subir apprennent gnralement plus quelles ne causent de dsagrments (hormis une grosse perte de temps).

3.10. Les classes, les objets


Avec la version 5, PHP se tourne un peu plus vers le monde des langages orients objets (notez limportance, ici, du terme "orient"). Ce nest toutefois pas un langage objets comme peut l"tre Eiffel et contrairement aux autres langages orients objets, tels que C++ ou Java, PHP reste un langage de script.

Le langage Eiffel Cr par Bertrand Meyer, le langage Eiffel a trouv sa place dans le milieu universitaire en tant quoutil denseignement de la "philosophie" objet des langages de programmation. Son typage trs fort le rend particulirement intransigeant.
Avant dexpliquer comment cela se gre au niveau de PHP, il peut tre intressant de rappeler ce quest la programmation objet. Lide est davoir un langage de programmation o les donnes dune mme nature et les fonctions qui permettent de les manipuler sont intimement lies au sien dentits appeles objets. Les classes associes ces objets auront une fonction dinitialisation (appele "constructeur"), des attributs et des fonctions (proprits) qui leur sont propres (appels mthodes). Toutes ces entits rpondront aux exigences de lobjet. Prenons un exemple simple : une boutique dinformatique. On pourra dfinir un ordinateur partir de plusieurs classes :
j j j

Une classe Ordinateur (on appellera ordinateur lassociation dun botier, dun cran, dun clavier et dune souris) ; Une classe Boitier (on estime quun botier est dj quip) ; Une classe Ecran ;

216

Les classes, les objets

j j

Une classe Clavier ; Une classe Souris.

Chacune de ces classes comportera un certain nombre dattributs et de mthodes :


j j j j j
Souris : une souris sera dfinie par son prix et son modele. On ajoutera deux fonctions permettant de modifier le prix et le modle : modifierPrix(), modifierModele(). Clavier : dans un premier temps, nous nous contenterons des mmes informations que celles dfinies pour la classe Souris. Ecran : idem. Boitier : idem mais modifierDetails().

nous ajouterons un attribut details et la fonction

3. Le langage PHP

Ordinateur : on peut associer un identifiant unique un ordinateur identifiant, et une mthode pour calculer son prix calculerPrix() en fonction des lments qui le constitue. Quatre attributs pourront dfinir chacune des pices dun ordinateur : boitier, ecran, clavier, souris.

Alors que la plupart des attributs seront de type simple: rel (pour le prix), chane de caractres (pour le modle); La classe Ordinateur, elle, utilise des attributs boitier, ecran, clavier, souris qui sont des types complexes: savoir les classes prcdemment dfinies. La cration dun objet (instanciation dune classe) passe par lappel dune mthode particulire appele constructeur. Le constructeur des classes Souris, Clavier et Ecran aura comme paramtres le prix et le modle. Le constructeur de la classe Boitier aura comme paramtres le prix, le modle et une description. La classe Ordinateur aura un constructeur ayant comme attributs un botier, un cran, un clavier et une souris. Ce qui donne en notation "abstraite" :

Classe Ordinateur
Constructeur :
j

ordinateur (botier : BOITIER, cran : ECRAN, clavier : CLAVIER, souris : SOURIS).

Attributs :
j j j j
boitier : BOITIER ; ecran : ECRAN ; clavier : CLAVIER ; souris : SOURIS.

Fonctions :
j
calculerPrix() : REAL

217

Chapitre 3

Le langage PHP

Classe Boitier
Constructeur :
j

botier (modele : STRING, details : STRING, prix : REAL).

Attributs :
j j j
modele : STRING ; details : STRING ; prix : REAL.

3. Le langage PHP

Fonctions :
j j j
modifierModele (modele:STRING) : VOID ; modifierDetails (details : STRING) : VOID ; modifierPrix (details:STRING) : VOID.

Classe Ecran
Constructeur :
j

cran (modele : STRING, prix : REAL).

Attributs :
j j
modele : STRING ; prix : REAL.

Fonctions:
j j
modifierModele (modele : STRING) : VOID ; modifierPrix (details : STRING) : VOID.

Classe Clavier
Constructeur :
j

clavier (modele : STRING, prix : REAL).

Attributs :
j j
modele : STRING ; prix : REAL.

Fonctions :
j
modifierModele (modele : STRING) : VOID ;

218

Les classes, les objets

modifierPrix (details : STRING) : VOID.

Classe Souris
Constructeur :
j

souris (modele : STRING, prix : REAL).

Attributs :
j j
modele : STRING ; prix : REAL.

3. Le langage PHP

Fonctions :
j j
modifierModele (modele : STRING) : VOID ; modifierPrix (details : STRING) : VOID.

Ce modle dfinit simplement un ordinateur tel quil a t dcrit. Lavantage de ce type de programmation, cest quil est trs facilement modifiable et corrigible. Sil est dcid que le calcul du cot dun ordinateur nest plus la simple addition des pices le composant, mais le cot des pices plus un cot de montage, il suffit de modifier la mthode calculerPrix() de la classe Ordinateur. Nous verrons par la suite quil est possible de faire bien mieux encore en se servant de ce qui est appel lhritage.

la POO en deux mots Ceci nest quun aperu de la programmation oriente objet (POO) ; un aperu qui na dailleurs pas dautre ambition que dinitier. Il existe de nombreux livres et sites Internet qui en parlent longuement, de manire gnrale ou associ un langage en particulier.

Dnir une classe


Il est dusage de dfinir une seule classe par fichier, mais cela nest pas obligatoire. Voici le squelette dune classe :
<?php class Ordinateur { // on placera ici le constructeur, les attributs et les mthodes. } ?>

219

Chapitre 3

Le langage PHP

Une classe, un fichier Une classe par fichier est sans aucun doute la meilleure faon de sy retrouver : le nom du fichier peut ainsi prendre le nom de la classe (ventuellement suffix par "_class"), et il est alors trs facile de retrouver la classe sur laquelle on veut travailler.

stdClass Vous ne devez en aucun cas appeler une classe stdClass, ce nom tant rserv PHP. 3. Le langage PHP

Les constructeurs
Un constructeur est une mthode (fonction) appele lors de linstanciation (la cration dun objet), qui sert gnralement initialiser des attributs. Le nom du constructeur doit tre "__construct".

Compatibilit ascendante Avec PHP 4, le nom du constructeur devait tre identique au nom de la classe. Ne vous inquitez pas ! Ce nest pas parce que vous avez, dans vos tiroirs, des scripts crits en objet pour PHP 4, que vous devez ncessairement vous empresser de les corriger pour les faire fonctionner avec PHP 5. En fait, si la mthode __construct nest pas trouve, linterprteur continuera rechercher une mthode portant le mme nom que la classe et sen servira comme constructeur.
<?php class Ordinateur { // on placera ici les attributs. function { echo echo echo echo echo } __construct($boitier, $ecran, $clavier, $souris) "Le constructeur a t appel avec les paramtres:<br />"; $boitier."<br />"; $ecran."<br />"; $clavier."<br/>"; $souris."<br />";

// on placera ici les mthodes. } ?>

Pour crer un objet, il suffit dutiliser linstruction new comme suit :

220

Les classes, les objets

$monOrdinateur = new Ordinateur($monBoitier, $monEcran, $monClavier, $maSouris);

Lexemple ici suppose que $monBoitier, $monEcran, $monClavier et $maSouris sont de type chane de caractres (ce qui nest pas ce que lon souhaite terme). A tout moment, il vous est possible de vrifier si un objet appartient (ou drive dune) classe donne en faisant appel linstruction instanceOf.
<?php // Nous supposons que la classe MaClasse a t dfinie prcdemment $obj = new MaClasse(); if ($obj instanceOf MaClasse) { echo "Oui, cest bien le type dobjet que jattendais"; } else { echo "Mais cest quoi cet objet ?"; } ?>

3. Le langage PHP

Les attributs
Les attributs sont des variables ou des constantes associes un objet. Ils sont prcds du mot-cl public, protected ou private.
<?php class Ordinateur { public $boitier; public $ecran; public $clavier; public $souris; function __construct($boitier, $ecran, $clavier, $souris) { $this->boitier = $boitier; $this->ecran = $ecran; $this->clavier = $clavier; $this->souris = $souris; } // on placera ici les mthodes. } ?>

var PHP4 Du temps de PHP4, les modificateurs de porte: public, protected et private nexistaient pas. Il fallait alors utiliser le mot cl var (qui reste toutefois compatible avec PHP 5 et qui se comporte comme public)

221

Chapitre 3

Le langage PHP

Dans cet exemple, le constructeur joue bien son rle dinitialisation. $this est lobjet courant. $this>boitier fait donc appel lattribut boitier de linstance "courante" de Ordinateur. Les attributs ayant t dclars public, ils sont accessibles depuis "tout endroit du code": savoir au sein de la classe (via $this>boitier) tout comme en dehors de la classe par linstruction :
$monBoitier = $monOrdinateur->boitier;

Et comme nous le verrons plus tard, un attribut public est galement accessible depuis une classe drive (Cf. hritage).

3. Le langage PHP

Appel dattributs Une erreur courante consiste crire $monOrdinateur>$boitier au lieu de $monOrdinateur>boitier. Bien entendu, la premire version ne peut fonctionner, car elle devient $monOrdinateur>"" si $boitier nest pas dfini.

Les constantes
Il est possible de dfinir des constantes au sein dune classe, pour cela, il suffit dutiliser linstruction const. Celles ci sont alors uniquement accessibles via un appel statique (MonObjet::MA_CONSTANTE). Notez quune constante dfinie au niveau de la classe sera prioritaire sur une constante portant le mme nom, mais dfinie en dehors de la classe via linstruction define.
<?php class Divers { const MODE_RAPIDE = "rapide" const MODE_PRECIS = "precis"; } ?> echo Divers::MODE_RAPIDE."<br />";

Valeur initiale des attributs Comme pour les variables statiques des fonctions, il nest pas possible dinitialiser les valeurs des variables en faisant appel des oprateurs (ex: public $val = 5 + 7;) ou des fonctions (ex: public $val = sqrt(25);).

attributs statiques
Au besoin, vous pourrez galement utiliser le modificateur "static" qui permet de dfinir une variable partage par toutes les instances de lobjet. Une variable statique sadresse selon le schma MonObjet::$maVariable.

222

Les classes, les objets

<?php class Divers { static $compteur = 0; function incrementeCompteur() { self::$compteur++; } function afficheCompteur() { echo self::$compteur; } } $obj1 = new Divers(); $obj1->incrementeCompteur(); $obj2 = new Divers(); $obj1->afficheCompteur(); $obj2->afficheCompteur();

3. Le langage PHP

?>

affichera donc :
2 2

Ce qui montre bien que la variable statique est partage par les deux instances.

On nest jamais mieux servi que par soi-mme Dans le cas dun attribut ou dune mthode statique, pour faire rfrence la classe courante vous devez utiliser linstruction self::.

Les mthodes
Les mthodes sont des fonctions propres une classe donne qui permettent de manipuler ou accder aux attributs dun objet. Elles se dclarent comme des fonctions mais sont dfinies au sein dune classe.
<?php class Ordinateur { public $boitier; public $ecran; public $clavier; public $souris; function __construct($boitier, $ecran, $clavier, $souris) { $this->boitier = $boitier;

223

Chapitre 3

Le langage PHP

$this->ecran = $ecran; $this->clavier = $clavier; $this->souris = $souris; } // La fonction calculer_prix renvoie la somme des prix des composants function calculerPrix() { $boitier = $this->boitier; $ecran = $this->ecran; $clavier = $this->clavier; $souris = $this->souris; return $boitier->prix+$ecran->prix+$clavier->prix+$souris->prix; } ?>

3. Le langage PHP

Lappel une mthode se fait selon le schma suivant:


$monObject->maMethode();

Noms de mthodes Deux classes peuvent avoir les mmes noms de mthodes, vu quelles sont prcdes, lors de leur appel, dun objet typ. Aucune confusion nest alors possible.
Les remarques, prsentes dans le chapitre sur les fonctions, concernant la porte des variables (globales, statiques ou locales) sappliquent exactement de la mme manire pour les mthodes.

Noms de mthodes rservs Afin de ne pas prendre le risque de rentrer en conflit avec des mthodes (appeles "fonctions magiques") utilises pour le fonctionnement interne de PHP, vous ne devez pas faire prcder le nom de vos mthodes par "__".

Les mthodes statiques


Une mthode ne faisant pas appel un attribut de lobjet (ou une autre mthode non statique) est dit statique.
<?php class Souris { function afficher() { echo "Cet objet reprsente une souris dordinateur"; } } ?>

224

Les classes, les objets

Pour appeler une telle mthode, il est inutile de crer un objet (par un appel new). Il est donc possible dutiliser loprateur :: (au lieu de >) . Ainsi, le script suivant aura pour effet dafficher "Cet objet reprsente une souris dordinateur" sans pour autant avoir eu besoin de crer un objet Souris.
<?php Souris::afficher(); ?>

Passage par rfrence et drfrencement


Passage par rfrence
Avec PHP 5, les objets sont systmatiquement passs par rfrence (comme dans un langage tel que Java) et non plus par copie. Il nest donc pas ncessaire de faire prcder le nom du paramtre dun & comme ce ft le cas avec PHP 4. Ainsi, lexemple suivant :

3. Le langage PHP

Listing 3.36 : Exemple


<?php class MaClasse { var $msg; function MaClasse() { $this->msg = "Message par dfaut"; } } function modifieMessage($objet) { $objet->msg = "Message modifi par la fonction"; } $obj = new MaClasse(); modifieMessage($obj); echo $obj->msg; }

retournera
Message modifi par la fonction

alors quavec PHP 4, il retournait


Message par dfaut

puisque la modification portait sur une copie de lobjet.

225

Chapitre 3

Le langage PHP

Objet retour Bien que cela soit plus difficile dmontrer, cest galement vrai pour les objets retourns par les fonctions (par return). Dans ce cas, ce nest pas une copie de lobjet cr dans la fonction qui est retourn, mais une rfrence sur lobjet.
En fait, ce sont toutes les manipulations dobjets qui se font par rfrence (comme cest traditionnellement le cas avec un langage de programmation orient objet) et non plus par copie. Ainsi le code suivant :
<?php $obj = new MaClasse(); $obj2 = $obj1; $obj2->msg = "Message attribu \$obj2"; echo $obj1->msg; ?>

3. Le langage PHP

retournera:
Message attribu $obj2

Alors quavec PHP 4, il retournerait :


Message par dfaut

Drfrencement
A supposer que lune des mthodes de lobjet retourne un objet comme par exemple la mthode suivante:
function recupereEcran() { return $ecran; }

Il est dsormais possible de rcuprer en un seul appel la valeur dun attribut de lobjet ainsi retourn en utilisant la syntaxe $ordinateur>recupereEcran()>prix. On parle alors de drfrencement.

PHP 4 et le drfrencement Notez bien que cela ntait pas possible avec PHP 4. Nous tions alors contraints de passer par une variable intermdiaire, selon le modle suivant: $ecran = $ordinateur>recupereEcran(), puis $ecran>prix. Lappel suivant tait, en revanche, tout fait valide $ordinateur>ecran>prix.

226

Les classes, les objets

Typage
Sans que PHP ne soit devenu un langage fortement typ avec la venue de la version 5. Celle-ci permet toutefois de prciser le type (uniquement sil sagit dun objet) des paramtres des mthodes. Comme le montre lexemple suivant (la classe Boitier est dcrite un peu plus loin):
function changerBoitier(Boitier $boitier) { $this->boitier = $boitier; }

En cas de passage de paramtre dun mauvais type, lerreur ne sera pas dtecte lors de la compilation mais lors de lexcution de la mthode. Il sagit alors dune erreur de niveau "fatal" et non une exception qui est leve.

3. Le langage PHP

Modicateurs de mthodes
Sur le mme principe que pour les attributs, la dclaration des mthodes peut tre affine grce aux modificateurs "private", "protected" ou par dfaut "public" pour ce qui est de la porte et "final" pour ce qui est des droits en modification (voir hritage).

Lhritage
Si lon reprend lensemble des classes (La classe Ordinateur ayant t prcdemment dfinie) nous obtenons:

Classe Boitier
<?php class Boitier { public $modele; public $details; public $prix; // Constructeur function __construct($modele, $prix, $details) { $this->modele = $modele; $this->details = $details; $this->prix = $prix; } // Mthodes. function modifierModele($modele) { $this->modele = $modele; } function modifierDetails($details)

227

Chapitre 3

Le langage PHP

{ $this->details = $details; } function modifierPrix($prix) { $this->prix = $prix; } ?>

Classe Ecran
3. Le langage PHP
<?php class Ecran { public $modele; public $prix; // Constructeur function __construct($modele, $prix) { $this->modele = $modele; $this->prix = $prix; } // Mthodes. function modifierModele($modele) { $this->modele = $modele; } function modifierPrix($prix) { $this->prix = $prix; } ?>

Classe Clavier
<?php class Clavier { public $modele; public $prix; // Constructeur function __construct($modele, $prix) { $this->modele = $modele; $this->prix = $prix; }

228

Les classes, les objets

// Mthodes. function modifierModele($modele) { $this->modele = $modele; } function modifierPrix($prix) { $this->prix = $prix; } ?>

3. Le langage PHP

Classe Souris
<?php class Souris { public $modele; public $prix; // Constructeur function __construct($modele, $prix) { $this->modele = $modele; $this->prix = $prix; } // Mthodes. function modifierModele($modele) { $this->modele = $modele; } function modifierPrix($prix) { $this->prix = $prix; } ?>

Ces quatre dernires classes se ressemblant normment, il serait prfrable de crer une classe commune Composant. Cest lobjet de ce sous-chapitre. La programmation objet permet de faire de lhritage. On parle dhritage lorsquune classe bnficie (hrite) des proprits (mthodes et attributs) dune autre. La classe qui hrite des proprits pourra implmenter dautres proprits ; on dit alors quelle "tend" la classe parente. Dans notre exemple, nous allons crer une classe Composant dont hriteront les classes Boitier, Clavier et Souris.

229

Chapitre 3

Le langage PHP

Classe Composant
<?php class Composant { public $modele; public $prix; // Constructeur function __construct($modele, $prix) { $this->modele = $modele; $this->prix = $prix; } // Mthodes. function modifierModele($modele) { $this->modele = $modele; } function modifierPrix($prix) { $this->prix = $prix; } ?>

3. Le langage PHP

Maintenant, si les classes Boitier, Clavier et Souris hritent de la classe Composant, elles vont considrablement se simplifier. Pour cela, il suffit de prciser "extends <classe parente>" lors de la dclaration de la classe.

Classe Souris
<?php class Souris extends Composant { } ?>

Cette dclaration suffit dfinir la classe Souris comme fait prcdemment. Cette classe vide peut sembler inutile, mais elle peut savrer trs utile si lon veut ajouter une information sur le nombre de boutons ou sur le fait quelle soit sans fil, par exemple (information qui naurait pas de sens pour les autres composants). Nous verrons avec la classe Boitier comment ajouter des mthodes propres une classe.

Classe Clavier
<?php class Clavier extends Composant {

230

Les classes, les objets

} ?>

Ce fichier suffit dfinir la classe Clavier comme fait prcdemment. De mme que pour la classe Souris, il pourrait tre intressant dajouter le nombre de touches ou le fait que ce soit un clavier avec ou sans fil.

Classe Boitier
<?php class Boitier extends Composant { private $details; // Constructeur function __construct($modele, $prix, $details) { new Composant($modele,$prix); $this->details = $details; } // Mthodes. function modifierDetails($details) { $this->details = $details; } } ?>

3. Le langage PHP

Ainsi

dfini, la classe Boitier bnficie des mthodes modifierModele() et modifierPrix() dfinies dans la classe Composant. Mais comme la classe que nous souhaitons obtenir est "plus riche" que la classe Composant dont elle hrite, il a fallu redfinir le constructeur, et ajouter une mthode et un attribut. La classe Ordinateur reste inchange. Dans le cas de lhritage, la classe parente peut tre rfrence laide du mot-cl parent. Ainsi, linstruction parent::modifierModele() fera appel la fonction modifierModele() de la classe parente mme si celle-ci a t redfinie au niveau de la classe fille.

Hritage et appel du constructeur Lorsque la classe qui hrite ne redfinit pas le constructeur, alors cest le constructeur de la classe parente qui est appel. Lorsque la classe qui hrite redfinit le constructeur, alors cest le constructeur de la classe fille qui est appel, sans que le soit le constructeur de la classe parente ( moins dun appel explicite parent::__construct()). Ce comportement est diffrent de celui de certains langages, et de Java en particulier.

231

Chapitre 3

Le langage PHP

Hritage multiple Il nest pas certain que PHP intgre un jour lhritage multiple mais comme le prouve Java, on peut trs bien vivre sans (tout en svitant bien des soucis).

Rcriture de mthode
Comme nous lavons vu avec lexemple de la classe Boitier, une classe fille peut trs bien r-crire une mthode de la classe mre. Dans ce cas, la signature de la mthode reste inchang mais son comportement pourra tre totalement (ou en partie modifi).

3. Le langage PHP

Si vous ne souhaitez pas que vous ou un quelconque utilisateur de votre classe ne fasse une grosse bourde en rcrivant maladroitement une des mthodes de la classe alors dclarez l final .
<?php class ClassMereAvecUneMethodeCritique { final function methodeCritique() { // Cest une methode critique a ne surtout pas // r-crire. } } ?>

Porte des attributs et mthodes (public, protected, private)


Comme cela a t voqu prcdemment, les attributs et les mthodes peuvent tre dclars public", "protected" ou "private". Un attribut ou une mthode dclar public est accessible librement. Un attribut ou une mthode dclar private nest accessible que depuis une mthode de la classe dans laquelle il a t dfini. Un attribut ou une mthode dclar protected nest accessible que depuis une mthode de la classe dans laquelle il a t dfini ou dune classe en hritant. Lutilisation de ces modificateurs de porte nest pas ngliger. Il peut tre par exemple ncessaire de rendre des attributs private ou protected afin dobliger lutilisation dune mthode pour affecter ces valeurs. Ces mthodes appeles accesseurs pourront au besoin pr-traiter la demande ou en contrler la validit avant de modifier ou retourner la valeur de lattribut.
<?php class Composant { private $modele; private $prix; // Constructeur

232

Les classes, les objets

function __construct($modele, $prix) { $this->modele = $modele; $this->prix = $prix; } // Mthodes. function modifierModele($modele) { if ($modele == "inconnu") $modele = NULL; $this->modele = $modele; }

3. Le langage PHP

function modifierPrix($prix) { if ($prix < 0) $prix = 0; $this->prix = $prix; } ?>

Avec cette classe, lappel $monBoitier>prix = 10; nest plus possible. Il faut ncessairement passer par la mthode modifierPrix() comme suit $monBoitier>modifierPrix(10); ce qui permettra de vrifier que le prix indiqu nest pas ngatif.

Les interfaces
Lorsquelle est correctement matrise, la programmation oriente objet permet de faire des choses vraiment formidables. Il est ainsi possible de crer des classes (et leurs mthodes) qui manipulent des objets de faon tout fait gnrique sans en connatre leur implmentation exacte mais en sappuyant simplement sur les mthodes quils proposent. Dans ce cas, il faut toutefois sassurer que les objets manipuls implmentent effectivement ces mthodes. Pour sen assurer, il suffit alors de dfinir une interface dcrivant lensemble des mthodes qui doivent tre implmentes.
<?php interface MonInterface { public function afficher(); } ?>

Nous avons ici dcrit linterface dune classe devant implmenter une mthode afficher(). Les classes prtendant implmenter cette interface devront alors le prciser avec le mot cl implements.
<?php class ClasseQuiImplemente implements MonInterface { function afficher() { echo "Moi quand jaffiche cest lcran"; }

233

Chapitre 3

Le langage PHP

} ?>

Une telle classe pourra alors tre utilise par la classe suivante:
<?php class ClasseQuiFaitLeTraitement { var $obj; function __construct($obj) { $this->obj = obj; } function traitement() { // Quelques lignes de traitement puis $this->obj->afficher(); } } $objAffichage = new ClasseQuiImplemente(); $objTraitement = new ClasseQuiFaitLeTraitement($objAffichage) $objTraitement->traitement(); ?>

3. Le langage PHP

Les classes abstraites


Un peu dans le mme esprit que les interfaces, il existe galement les classes abstraites. Il sagit alors de classes qui peuvent implmenter un certain nombre de mthodes et laisse le soin dautres dimplmenter un certain nombre dautres mthodes alors dclares comme abstract (abstraites). Une classe contenant des mthodes abstraites est elle-mme abstraite et ne peut tre instancie. Une classe abstraite ne peut tre que drive (par hritage). Lexemple prcdent donnerait alors
<?php abstract class MaClasseAbstraite { abstract public function afficher(); function autreMethode() { // Eventuellement une methode qui // a t implmente ici } } class ClasseQuiImplemente extends MaClasseAbstraite { function afficher() { echo "Moi quand jaffiche cest lcran"; } }

234

Les classes, les objets

class ClasseQuiFaitLeTraitement { var $obj; function __construct(MaClasseAbstraite $obj) { $this->obj = obj; } function traitement() { // Quelques lignes de traitement puis $this->obj->afficher(); } } $objAffichage = new ClassQuiImplemente(); $objTraitement = new ClasseQuiFaitLeTraitement($objAffichage) $objTraitement->traitement(); ?>

3. Le langage PHP

Vous noterez que dans ce cas, il est possible de vrifier que le classe passe en paramtre du constructeur hrite bien de la classe abstraite (et donc implmente bien la mthode afficher()).

Les exceptions
Lensemble des langages de programmation oriente objet offrent une alternative lhabituel code derreur retourn par une fonction: la place, lorsquune classe lve une erreur, elle interrompt son droulement et redonne la main au programme appelant en mettant un objet appel Exception. PHP nchappe pas cette rgle. La gnration de ces "messages" est alors contrle et gre dans un bloc try... catch..

Listing 3.37 : exception.php


<?php class ObjetMathematique { function division($a, $b) { if ($b == 0) throw new Exception("Division par zero.", 10); else return $a/$b; } } try { $obj = new ObjetMathematique(); echo $obj->division(4, 2)."<br />\n"; echo $obj->division(4, 0)."<br />\n"; echo $obj->division(8, 4)."<br />\n"; } catch (Exception $ex) { echo "getMessage() ".$ex->getMessage()."<br />\n";

235

Chapitre 3

Le langage PHP

echo "getCode() ".$ex->getCode()."<br />\n"; echo "getFile() ".$ex->getFile()."<br />\n"; echo "getLine() ".$ex->getLine()."<br />\n"; echo "getTrace() "; var_dump($ex->getTrace()); echo "<br />\n"; echo "getTraceAsString() ".$ex->getTraceAsString()."<br />\n"; } ?>

Cela retournera alors :


2<br /> getMessage() Division par zero.<br /> getCode() 10<br /> getFile() /usr/local/apache/htdocs/regtest/poo/_exception.php<br /> getLine() 7<br /> getTrace() array(1) { [0]=> array(6) { ["file"]=> string(51) "/usr/local/apache/htdocs/regtest/poo/_exception.php" ["line"]=> int(15) ["function"]=> string(8) "division" ["class"]=> string(17) "ObjetMathematique" ["type"]=> string(2) "->" ["args"]=> array(2) { [0]=> int(4) [1]=> int(0) } } } <br /> getTraceAsString() #0 /usr/local/apache/htdocs/regtest/poo/_exception.php(15): ObjetMathematique->division(4, 0) #1 {main}<br />

3. Le langage PHP

En effet, lorsque nous avons appel la mthode division avec un diviseur gal 0, la mthode a lev une exception grce linstruction throw. Ceci a donc mis un terme lexcution de la mthode ainsi qu celle du bloc try du programme appelant, lexcution se poursuivant par le bloc catch correspondant lobjet exception gnr. (Ici, nous navons quun bloc catch, mais il est possible den avoir autant quil y a dexceptions diffrentes). Le reste du programme ( la suite du bloc try...catch) se droule alors normalement.

236

Les classes, les objets

Dans cet exemple, nous avons utilis la classe prdfinie Exception, nous aurions galement pu dfinir notre propre classe dexception condition quelle hrite de Exception. La classe Exception prsente un constructeur permettant de prciser un message derreur ainsi quun code derreur.

Exception->__construct()
Instancie un objet Exception.

3. Le langage PHP

Syntaxe $message $codeErreur

new Exception([string $message [, int $codeErreur]]) Message derreur. Code derreur.

Cette classe possde de nombreuses mthodes:

Exception->getMessage()
Retourne le message derreur de lException. Syntaxe retour string getMessage() Message derreur.

Exception->getCode()
Retourne le code derreur de lException. Syntaxe retour int getCode() Code derreur.

Exception->getFile()
Retourne le nom du fichier dans lequel lException a t leve. Syntaxe retour string getFile() Nom du fichier.

237

Chapitre 3

Le langage PHP

Exception->getLine()
Retourne le numro de la ligne du fichier o lException a t leve. Syntaxe retour int getLine() Ligne dans le fichier.

3. Le langage PHP

Exception->getTrace()
Retourne le tableau des enchanements des appels de fonctions ayant conduit lException. Syntaxe retour array getTrace() Tableau index contenant une entre par fonction dans la pile dappel. Chacune des valeurs de ce tableau est un tableau associatif contenant les cls: file, prcisant le nom du fichier contenant lappel; .line, prcisant la ligne o a eu lieu lappel, function, prcisant le nom de la fonction (ou mthode) appele, class, prcisant le nom de la classe implique, type, prcisant le type dappel (ex: -> pour un appel de mthode non statique) et enfin args, prcisant les paramtres passs la fonction.

PHP 4 (ne) fait (pas) Exception PHP 4 ne grait pas les exceptions.

Les fonctions de manipulation des objets


PHP propose un ensemble de fonctions applicables des objets. Il sagit essentiellement de fonctions dintrospection: cest dire des fonctions retournant des informations sur un objet comme par exemple la liste des attributs et mthodes quil expose.

get_class()
Retourne le nom de la classe dont lobjet spcifi est une instance. Syntaxe $objet retour string get_class(object $objet) Objet dont vous souhaitez dterminer la classe. Nom de la classe ou FALSE en cas dchec.

238

Les classes, les objets

class_exists()
Vrifie si une classe existe ou non. Syntaxe $classe $chargement Automatique retour boolean class_exists(string $classe [, boolean $chargementAutomatique]) Nom de la classe que vous souhaitez tester. TRUE (valeur par dfaut) si vous souhaitez utiliser le chargement automatique de la classe (cf. __autoload), FALSE sinon.

3. Le langage PHP

TRUE si la classe existe, FALSE sinon.

get_class_methods()
Retourne la liste des mthodes exposes par une classe ou un objet. Syntaxe $classe retour array get_class_methods(mixed $classe) Nom de la classe ou une instance (lobjet directement). Tableau index ayant pour valeurs les noms des mthodes ou NULL si la classe nexiste pas.

method_exists()
Vrifie si un objet expose une mthode donne ou non. Syntaxe $objet boolean method_exists(object $objet, string $methode) Objet que vous souhaitez tester (contrairement get_class_method() il nest pas possible de spcifier le nom de la classe la place). Nom de la mthode. TRUE si la mthode existe, FALSE sinon.

$classe retour

get_class_vars()
Retourne la liste des attributs dune classe et leur valeur (initiale).

239

Chapitre 3

Le langage PHP

Syntaxe $classe retour

array get_class_vars(string $classe) Nom de la classe (contrairement get_class_method() il nest pas possible de spcifier lobjet directement). Tableau index ayant pour cls les noms des attributs et pour valeur la valeur initiale des attributs ou FALSE si la classe nexiste pas.

get_object_vars()
3. Le langage PHP
Retourne la liste des attributs dun objet et leur valeur. Syntaxe $objet retour array get_object_vars(object $objet) Objet dont vous souhaitez obtenir la liste de valeur des attributs. Tableau index ayant pour cls les noms des attributs et pour valeur la valeur des attributs ou FALSE en cas derreur.

Dautres fonctions sont plus spcifiquement lies la notion dhritage.

get_parent_class()
Retourne le nom de la classe mre de la classe teste. Syntaxe $classe retour string get_parent_class(mixed $classe) Nom de la classe ou instance (lobjet directement). Nom de la classe mre ou FALSE en cas derreur.

is_subclass_of()
Vrifie si un objet hrite dune classe donne ou non. Syntaxe $objet $classe retour boolean is_subclass_of(object $objet, string $classe) Objet tester. Nom de la classe dont lobjet est susceptible dhriter. TRUE si lobjet hrite bien de la classe indique, FALSE sinon.

Il est galement possible de rcuprer la liste de lensemble des classes et interfaces connues du script.

240

Les classes, les objets

get_declared_classes()
Retourne la liste des classes connues (on y retrouve videmment stdClass, Exception, etc.). Syntaxe retour array get_declared_classes() Tableau index ayant pour valeurs les noms des classes.

get_declared_interfaces()
Retourne la liste des interfaces connues. Syntaxe retour array get_declared_interfaces() Tableau index ayant pour valeurs les noms des interfaces.

3. Le langage PHP

Programmation avance
Mmoriser des objets
Il est parfois intressant de stocker un objet dans un fichier (une variable de session ou encore une base de donnes). Ce nest pas, a priori, une tche aise, mais elle se rvle trs simple sil est possible de transformer un objet en chane de caractres et une chane de caractres en objet. Cest ce que lon appelle la srialisation et la dsrialisation. La srialisation seffectue laide de la fonction serialize() ; lopration inverse laide de la fonction unserialize(). Pour pouvoir relire cette chane de caractres et la transformer en objet, la classe doit tre dfinie au moment de lopration de dsrialisation. Dans lexemple suivant, nous sauvegarderons un objet souris, puis nous le rcuprerons dans un autre script en se servant dun fichier texte pour mmoriser cet objet.

Listing 3.38 : sauvegarde.php


<?php // Inclusion du contenu du fichier Souris.php // contenant la dfinition de la classe include("Souris.php"); $souris = new Souris("Souris Facile",9.98); $chaine_souris = serialize($souris); $fichier = fopen("sauvegarde", "w"); // Le fichier sauvegarde // est ouvert en criture

241

Chapitre 3

Le langage PHP

fputs($fichier, $chaine_souris); fclose($fichier); ?>

// Le contenu de la chane de // caractres est crit // Le fichier est referm

Listing 3.39 : lecture.php


<?php // Il est indispensable dinclure la dfinition de la classe // Souris pour que unserialize() fonctionne correctement include("Souris.php");

3. Le langage PHP

$souris = implode("", @file("sauvegarde")); //la chane stocke // est rcupre unserialize($souris); // la chane est transforme en son objet associ

// $souris se traite dsormais comme un objet. $souris->modifier_prix(9.99); ?>

Les sessions Dans le cas des sessions, si vous utilisez la fonction session_register() sur un objet, celui-ci est automatiquement srialis. Il faut donc faire bien attention inclure la dfinition de la classe dans chacun des fichiers accessibles ds le moment o lobjet est enregistr en session. Sinon celui-ci se transforme en objet de classe stdClass et na aucune utilit, car, alors, aucune des mthodes nest accessible.

__sleep
La fonction __sleep() est appele avant toute srialisation. Cette fonction renvoie un tableau des valeurs mmoriser. Elle permet de nindiquer que les valeurs utiles stocker et de fermer les connexions aux bases de donnes par exemple.

__wakeup
La fonction unserialize() fait appel cette mthode au moment de recrer lobjet. Cela peut permettre de rtablir des connexions aux bases de donnes par exemple.
<?php class Test { var $attribut1; var $attribut2; var $attribut3; function Test($attribut1, $attribut2) {

242

Les classes, les objets

$this->attribut1=$attribut1; $this->attribut2=$attribut2; $this->attribut3=$attribut1+$attribut2; } function __sleep() { return array(attribut1, attribut2); } function __wakeup() { $this->attribut3 = $this->attribut1 + $this->attribut2; }

3. Le langage PHP

} ?>

En faisant ceci, on conomise en mmoire, car $attribut3, qui peut tre calcul partir de $attribut1 et $attribut2, nest pas stock (en effet, la fonction __sleep ordonne de ne stocker que les attributs attribut1 et attribut2). Il est cependant recalcul au moment de reconstituer lobjet.

Destruction des objets


Lorsquun objet nest plus utilis (ou tout simplement lorsque la fin du script arrive), les objets sont dtruits. Jusqualors, il ntait pas possible de demander PHP dexcuter certaines fonctions (ex. : fermeture dun fichier, dconnexion dune base de donnes, etc.) avant de dtruire dfinitivement lobjet. Cest dsormais possible en crivant une mthode __destruct() contenant le code excuter avant la destruction de lobjet.
<?php class ObjetMortBruyante { var $msg; function __construct() { $this->msg = "Je suis un objet qui ne sait pas mourir en silence"; } function __destruct() { echo "Arrgggg.... je meurs"; } } $obj = new ObjetMortBrutante(); // la fin du script entraine la destruction de lobjet ?>

Ce script retournera donc :


Arrgggg.... je meurs

indiquant bien que la mthode __destruct() a t appele.

243

Chapitre 3

Le langage PHP

__destruct() et lhritage En cas dhritage, tout comme pour le constructeur, le destructeur de la classe parente nest pas appel automatiquement. Si vous souhaitez appeler ce dernier vous devrez inclure un appel parent::__destruct().

Clonage
Avec larrive de PHP 5 et de son moteur Zend2, il est dsormais possible de prciser comme doit se faire la copie dun objet en crant une mthode __clone().

3. Le langage PHP

Il est alors possible par exemple de rinitialiser certaines valeurs (les caractristiques propres la copie) tout en demandant la copie de certaines autres (les caractristiques gnrales de lobjet copi). Pour accder aux donnes de lobjet copi, vous devrez faire appel $that (qui joue le rle du $this mais pour lobjet copi).

This or That ? Nous devons avouer notre perplexit sur ce point. Il se trouve que dans les premires documentations et premires implmentations de PHP 5. Il fallait effectivement utiliser $that. Cependant, lexemple suivant qui fonctionnait tel que nous lavions imagin prcdemment ne fonctionne pas exactement pareil avec PHP 5.0.1.
Ainsi lexemple suivant :
<?php class ObjetMutant() { var $msg, $msg2; function ObjetMutant() { $this->msg = "Je suis un mutant"; $this->msg2 = "et je reste un mutant."; } function __clone() { $this->msg = "Jai mut"; $this->msg2 = $that->msg2; } } $obj = new ObjetMutant(); $obj2 = clone $obj; echo $obj->msg." ".$obj->msg2."<br />"; echo $obj2->msg." ".$obj2->msg2."<br />"; ?>

retournera donc (ou tout du moins retournait) :


Je suis mutant et je reste un mutant. Jai mut et je reste un mutant.

244

Les classes, les objets

Il retourne dsormais
Je suis mutant et je reste un mutant. Jai mut

A moins de remplacer le $that par un $this. Quoiquil en soit, une chose est sure, lappel de linstruction clone, la mthode __clone() a bien t excute. Notez, que la mthode __clone() ne peut tre appele directement.

Nouvelles mthodes "internes"


PHP 5 utilise de nouvelles mthodes internes. En particulier lors de la rcupration du contenu dun attribut selon le schma $objet>attribut, PHP retournera la valeur de lattribut sil existe, sinon il appellera la mthode __get() avec pour paramtre le nom de lattribut. Mthode quil est possible de redfinir.
<?php class MaClasse { var $attr1; function __contruct() { $attr1 = "demo"; } function __get($nom) { return "Dsol, $nom nest pas un attribut connu"; } } $obj = new MaClasse(); echo $obj->attr1; echo $obj->attr2; ?>

3. Le langage PHP

retournera donc: demo Dsol, attr2 nest pas un attribut connu Il en est de mme avec laffectation de valeur une variable et la mthode interne __set() ainsi que pour lappel de mthode et la fonction __call(). Dans ce dernier cas, la mthode reoit deux paramtres, le premier tant le nom de la mthode appele et le second tant un tableau index des paramtres de lappel.

autres fonctions
Il est prvu de pouvoir dfinir son propre traitement lorsquil est fait rfrence une classe qui nexiste pas. Pour cela, il suffit de redfinir la fonction __autoload() qui accepte pour unique paramtre le nom de la classe appele. Notez toutefois qu lissu de lappel cette fonction, linstanciation dun objet de la classe invoque devra tre possible sinon le script sarrtera avec

245

Chapitre 3

Le langage PHP

un message derreur. En fait, cette fonction pour objectif principal de vous permettre dinclure au vol le fichier contenant la dclaration de la classe.

Les tableaux en POO


PHP propose un objet appel ArrayObject charg de manipuler un tableau comme nimporte quel objet.

3. Le langage PHP

ArrayObject->__construct()
Instancie un objet ArrayObject. Syntaxe $tableau new ArrayObject([mixed $tableau]) Lobjet ArrayObject peut tre initialis aussi bien avec un autre objet ArrayObject quavec un tableau "classique".

Sil nest pas pr-rempli lors de lappel du constructeur, lobjet peut tre aliment par des appels successif la mthode append().

ArrayObject->append()
Ajoute un lment un objet ArrayObject. Syntaxe $valeur void append(mixed $valeur) Elment ajouter lobjet ArrayObject.

Cette mthode prsente toutefois linconvnient majeur de ne pas permettre de prciser la cl associe la valeur. Pour cela, nous privilgierons la mthode offsetSet().

ArrayObject->offsetSet()
Ajoute un lment un objet ArrayObject en prcisant la cl associe. Syntaxe $cle $valeur void offsetSet(mixed $cle, mixed $valeur) Cl associe llment ajouter lobjet ArrayObject. Elment ajouter lobjet ArrayObject.

A linverse, il est possible de rcuprer la valeur associe une cl par

246

Les classes, les objets

ArrayObject->offsetGet()
Retourne llment dun objet ArrayObject associ une cl donne. Syntaxe $cle retour mixed offsetGet(mixed $cle) Cl associe llment rcuprer. Elment associ la cl dans lobjet ArrayObject.

Pour supprimer un lment du tableau on fera appel

3. Le langage PHP

ArrayObject->offsetUnset()
Supprime llment dun objet ArrayObject associ une cl donne. Syntaxe $cle void offsetUnset(mixed $cle) Cl associe llment supprimer.

Il est galement possible den vrifier lexistence

ArrayObject->offsetExists()
Teste la prsence dun lment dun objet ArrayObject associ une cl donne. Syntaxe $cle retour boolean offsetExists(mixed $cle) Cl rechercher. TRUE, si un des lments du tableau est associ la cl, FALSE sinon.

Il est videmment, tout moment possible de vrifier la taille du tableau

ArrayObject->count()
Retourne le nombre dlment contenu dans un objet ArrayObject. Syntaxe retour int count() Nombre dlments dans le tableau.

247

Chapitre 3

Le langage PHP

Les itrateurs de tableau


Afin de parcourir le contenu dun tableau, PHP met disposition un objet ArrayIterator. Celui ci peut tre obtenu en appelant la mthode getIterator() dun ArrayObject.

ArrayObject->getIterator()
Retourne un itrateur sur un objet ArrayObject.

3. Le langage PHP

Syntaxe retour

ArrayIterator getIterator() Itrateur sur lArrayObject.

Lobjet ArrayIterator agit comme un pointeur sur un lment du tableau. Pointeur qui permet de progresser du premier lment au dernier.

ArrayIterator->valid()
Vrifie que litrateur pointe toujours sur un lment de lobjet ArrayObject. Syntaxe retour boolean valid() TRUE si litrateur pointe sur un lment du tableau, FALSE sinon.

ArrayIterator->current()
Retourne llment "courant" du tableau (celui sur lequel litrateur pointe). Syntaxe retour mixed current() Valeur de llement du tableau actuellement point.

ArrayIterator->key()
Retourne la cl de llment "courant" du tableau (celui sur lequel litrateur pointe). Syntaxe retour mixed key() Cl de llement du tableau actuellement point.

248

Les classes, les objets

ArrayIterator->next()
Dplace litrateur sur llment suivant du tableau. Syntaxe void next() Ainsi typiquement le parcours dun tableau seffectue comme ceci:
<?php $tableau["cle1"] = "element1"; $tableau["cle2"] = "element2"; $tableau["cle3"] = "element3"; $monArrayObject = new ArrayObject($tableau); echo "Ce tableau contient ".$monArrayObject->count()." echo "Jutilise un iterateur pour le parcourir:<br />"; $iterateur = $monArrayObject->getIterator(); while ($iterateur->valid()) { echo "cle = ". $iterateur->key() . " valeur = ". $iterateur->current() . "<br />"; $iterateur->next(); } ?> elements.<br />";

3. Le langage PHP

Ceci dit litrateur peut tre utilis pour naviguer librement au sein du tableau.

ArrayIterator->seek()
Dplace le pointeur de litrateur sur un lment quelconque du tableau. Syntaxe $position void seek(int $position) Position dans le tableau (0 = premier lment) o doit tre dplac le pointeur de litrateur.

ArrayIterator->rewind()
Dplace le pointeur de litrateur sur le premier lment du tableau. Equivalent de seek(0). Syntaxe void rewind()

249

Chapitre 3

Le langage PHP

Listing 3.40 : arrayObject.php


<?php $tableau[] = "element1"; $tableau[] = "element2"; $tableau[] = "element3"; $monArrayObject = new ArrayObject($tableau); $monAutreArrayObject = new ArrayObject($monArrayObject); echo "Ce tableau contient ".$monArrayObject->count()." elements.<br />"; echo "Jutilise un iterateur pour le parcourir:<br />"; $iterateur = $monAutreArrayObject->getIterator(); echo "Je saute directement au 2eme element:<br />"; $iterateur->seek(1); echo $iterateur->current()."<br />"; echo "Je reviens au premier:<br />"; $iterateur->rewind(); echo $iterateur->current()."<br />"; ?>

3. Le langage PHP 250

Chapitre 4

Les en-ttes HTTP


4.1 4.2 4.3 4.4 4.5 Principe gnral . . . . . . . . . . . . . . . . . Gestion personnalise de len-tte HTTP . . Cookies . . . . . . . . . . . . . . . . . . . . . . . Sessions . . . . . . . . . . . . . . . . . . . . . . Mise en cache avant mission des donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 258 261 271 287

Principe gnral

utilisation explicite ou implicite des en-ttes va vous permettre de rediriger un client vers un autre site, et dutiliser des cookies ou des variables de session afin de stocker (temporairement) des informations. Mais, avant daborder ces chapitres, il est important de bien comprendre le fonctionnement du dialogue client-serveur avec HTTP.

4.1.

Principe gnral
Historique Le protocole HTTP (HyperText Transfer Protocol), mis en uvre lors de lchange dinformations entre le client et le serveur, est une norme cre en 1990 par Tim Berners-Lee (qui est prsent prsident du Consortium du World Wide Web appel plus communment W3C). Ce protocole est bas sur un systme de communication par requtes/rponses. 4. Les en-ttes HTTP

Ainsi, le client se connecte sur le serveur, sur un port spcifique (gnralement le port 80), pour envoyer un message (que lon appelle requte). Ce dernier doit respecter un schma prcis rgi par une norme : ce doit tre une mthode (de type GET, POST, HEAD, PUT, DEL ou TRACE) suivie dune URI (adresse Internet). Au besoin, le client complte la requte laide dun message de type MIME (Multipurpose Internet Mail Extension). Il indique ainsi les informations particulires dont il a besoin, dcline son identit (signature du client) et indique la version du protocole utilis. Le serveur, quant lui, renvoie ensuite une rponse comprenant un en-tte HTTP comportant diverses informations sur le serveur et sur comment le client doit analyser le rsultat, suivi du corps du document.

Figure 4.1 : On peut schmatiser une requte HTTP comme ceci

Le client envoie donc un en-tte HTTP comprenant dans lordre :


j

Une ligne de requte : elle comprend le type de document demand ainsi que la mthode et la version du protocole quil lui est demand dutiliser. Cette ligne peut tre schmatise comme ceci : <METHODE> <URL> <VERSION>.

253

Chapitre 4

Les en-ttes HTTP

Tableau 4.1 : Les diffrentes mthodes pouvant tre utilises


Mthode POST GET HEAD Signification La mthode POST est utilise pour une soumission de donnes vers une URI cible. La mthode GET est utilise pour rcuprer un contenu identifi par lURI spcifie. La mthode HEAD est identique la mthode GET sauf quelle ne rclame que len-tte du document spcifi. Le document lui-mme nest ainsi pas renvoy. Permet le dpt dun fichier donn directement sur le serveur distant. Commande demandant au serveur distant de dtruire un document indiqu lURI spcifie. Version HTTP/1.0 HTTP/1.0 HTTP/1.0

PUT DELETE TRACE

HTTP/1.1 HTTP/1.1

4. Les en-ttes HTTP

La mthode TRACE permet au client de voir ce qui est reu HTTP/1.1 par le serveur. Son utilisation est utile dans les phases de test ou de diagnostic. Cette mthode est rserve pour une utilisation par un proxy pouvant dynamiquement tre bascul vers un tunnel (ex. : un tunnel SSL). HTTP/1.1

CONNECT

Les en-ttes de la requte (autant de lignes que ncessaire) : ces lignes facultatives (hormis linformation Host dans le cas du protocole HTTP/1.1) permettent de donner des informations complmentaires la requte, comme lorigine du client et lidentification (ou signature) de ce client (nom du navigateur, systme dexploitation, etc.). Ces informations (une par ligne) sont donnes comme un identifiant suivi immdiatement de deux points :, une espace et de sa valeur : <IDENTIFIANT>: <valeur>.

Tableau 4.2 : Exemple den-ttes pouvant tre utiliss


Identifiant (en-tte) Accept AcceptCharset Date From Host Referer UserAgent Signification Type de contenu que le navigateur est susceptible daccepter (ex. : text/html, audio/xaiff, image/jpeg, etc.). Le type de caractre que le navigateur attend en rponse (ex : ISO-8859-1). Date et heure du client (ex. : Sat, 27 Apr 2002 15:59:53 GMT) Spcifie une adresse e-mail pour le client. Nom de la machine cliente. Adresse de la page depuis laquelle la requte a t effectue. Chane didentification du client (ex. : Mozilla/5.001 [windows; U; NT4.0; enus] Gecko/25250101 pour un navigateur Mozilla sur un systme Windows NT4.0).

254

Principe gnral

Vous pouvez vous reporter lannexe "En-ttes et variables externes" pour une liste plus complte den-ttes.
j

Le corps de la requte : ces lignes sont utilises dans le cas dune mthode de type POST pour lenvoi de donnes (comme les paramtres dun formulaire).

Comme aucune explication ne vaut un bon exemple, ouvrez un client telnet en ligne de commande,
telnet www.linux.org 80

et tapez la commande suivante :


GET / HTTP/1.0

Pour valider votre requte, finissez en tapant deux fois sur la touche [Entre].

4. Les en-ttes HTTP

Le client telnet de Windows Notez que le client telnet de Windows ne permet pas de visualiser ce que vous rentrez depuis le clavier. Alors, ne vous trompez pas dans la commande, et respectez bien les majuscules et minuscules.
Figure 4.2 : Voici une page telle quelle est envoye par un serveur web

Vous voyez apparatre la rponse du serveur (ici, le code source de la page). Ce qui nous intresse dans le cas prsent, ce sont les premires lignes de ce document, savoir len-tte de la page. Si vous voulez ne voir que cet en-tte, rentrez la commande HEAD / HTTP/1.0. Ainsi seul lentte renvoy par le serveur saffichera dans le client telnet.
HTTP/1.1 200 OK Date: Sat, 27 Apr 2002 15:59:53 GMT Server: Apache/1.3.24 (Unix) (Red-Hat/Linux) mod_ssl/2.8.8 OpenSSL/0.9.6b mod_perl/1.26 Cache-Control: max-age=60 Expires: Sat, 27 Apr 2002 16:00:53 GMT

255

Chapitre 4

Les en-ttes HTTP

Pragma: no-cache Connection: close Content-Type: text/html <HTML> ...

Vous remarquez quil y a une ligne vide entre len-tte et le corps du document. Cest ce saut de ligne qui signale la fin de len-tte HTTP et indique que ce qui suit est le corps du document. Ainsi, une fois envoy, len-tte ne peut plus tre modifi. Vous verrez dans ce chapitre que le langage PHP permet des modifications de len-tte, mais cause une erreur si vous essayez de le modifier aprs lenvoi du dbut du document. Vous pouvez excuter prsent, toujours laide de votre client telnet, la commande suivante :
telnet www.linux.org 80 GET / HTTP/1.1 host:www.linux.org

4. Les en-ttes HTTP

Comme indiqu prcdemment, le protocole HTTP/1.1 rclame une information supplmentaire host. En effet, cette dernire mouture de HTTP a permis ladoption des htes virtuels, cest--dire que plusieurs noms de domaines peuvent se partager une mme adresse IP. Dautres avantages du protocole 1.1 sur le 1.0 sont rpertoris dans la RFC2616.

Les RFC Pour toutes les informations complmentaires sur les protocoles HTTP/1.0 et HTTP/ 1.1, consultez les RFC (Request For Comment). Ces documents ont la particularit de reprsenter une notice pour une documentation gnrale, un standard ou la description dun protocole. Il est noter que lcriture mme dune RFC est dfinie dans une autre RFC (la RFC1543). Pour HTTP/1.0, la RFC1945 est disponible ladresse http://abcdrfc.free.fr/rfc-vf/ rfc1945.html (traduction franaise). Pour HTTP/1.1, la RFC2616 est disponible (en anglais) ladresse http://www.w3.org/Protocols/rfc2616/rfc2616.html. Ces documentations trs compltes vous apprendront tout ce quil faut savoir pour effectuer un change de donnes entre un navigateur Internet et un serveur web.
Voyons prsent ce que signifie cette rponse (i.e. comment le navigateur interprte ce message).
j

La premire ligne indique le code de retour. Ici le code 200 signifie que tout sest bien pass. Tous les internautes connaissent au moins un autre code : le tristement clbre 404, qui comme vous le savez, signifie que le serveur na pas trouv la page demande.

256

Principe gnral

Tableau 4.3 : Les diffrentes catgories de code que peut renvoyer un serveur web et leurs significations
Intervalle de code 100 199 200 299 300 399 400 499 500 599 Signification Les informations sont retournes. La requte a t traite avec succs. Demande de redirection. La requte est incomplte. Indique une erreur du serveur HTTP.

Vous pouvez vous reporter lannexe sur les "Codes derreur HTTP" pour une liste plus dtaille. 4. Les en-ttes HTTP
Puis vient une srie de valeurs prcdes par un nom de paramtre. Avant de poursuivre, voici quelques paramtres den-tte possibles. Cette liste est non exhaustive, mais comprend les paramtres les plus courants quun serveur peut renvoyer.

Tableau 4.4 : Quelques-uns des messages que peut renvoyer un serveur dans son en-tte
Identifiant den-tte ContentEncoding ContentLanguage ContentLength Description Cest le type de codage du document renvoy (ex. : compress, xgzip, xzip, etc.). Cest le langage utilis dans le corps de la rponse ("fr" pour franais, "en" pour anglais, "it" pour italien, etc.). Cest la longueur de la rponse. Cette valeur est donne en octets. Cette donne permet au client dtre certain quil a bien reu la totalit du document. Cest le type MIME du document (ex. : text/html, image/gif, application/postscript, text/plain, audio/basic, video/mpeg, etc.). Date du serveur au dbut du transfert des donnes. Date limite de validit du document (particulirement utile dans le cas de lutilisation dun cache). Demande la redirection vers une nouvelle URL. Nom ou signature du serveur qui renvoie les informations.

ContentType

Date Expires Location Server

Vous pouvez vous reporter lannexe "En-ttes et variables externes" pour un liste plus complte den-ttes.

257

Chapitre 4

Les en-ttes HTTP

Nous pouvons maintenant revenir notre exemple et analyser sa rponse. Cet en-tte nous apprend donc plusieurs choses :
j j

La deuxime ligne de notre exemple indique simplement la date et lheure du serveur web. La ligne suivante est la signature du serveur web. Dans notre exemple, le serveur hbergeant le site de Linux.org nous signale quil tourne sous le systme dexploitation Linux (est-ce tonnant ?) avec le serveur Apache et que celui-ci est compil avec les modules SSL et Perl. La ligne Cachecontrol nest valide que pour la version 1.1 du protocole HTTP. Cette ligne indique comment un client, et en particulier un proxy cache, doit traiter cette page (si le proxy doit mettre en cache la page, la relire chaque fois, et combien de temps le cache de la page est valide. Ici, la page peut tre archive pendant 60 secondes au plus.) Pour les navigateurs utilisant le protocole HTTP/1.0, le serveur renvoie deux lignes la suite qui permettent de dfinir la gestion du cache et la dure de celle-ci. Enfin, la ligne ContentType indique votre client web le type MIME de ce qui lui est envoy. Cela peut tre du texte, de lHTML, une image, un fichier son, etc.

j j

4. Les en-ttes HTTP

Vous pouvez consulter lannexe sur "Les types MIME" pour une liste plus complte des types.

4.2.

Gestion personnalise de len-tte HTTP

Dune manire gnrale, avec PHP, il est possible de prciser la valeur des paramtres spcifis dans len-tte, grce la fonction header().

header()
Spcifie un lment de len-tte de la rponse HTTP. Syntaxe $ligneEntete $remplace $reponseHTTP void header(string $ligneEntete [, boolean $remplace [, int $reponseHTTP]]) Information ajouter len-tte. TRUE si cette ligne doit remplacer la valeur donne prcdemment au mme paramtre den-tte, FALSE (par dfaut) si elle doit tre ajoute. Permet de forcer la reponse HTTP (par exemple 404 pour simuler une page manquante). Cette option est apparue avec la version 4.3.0 de PHP.

Headers already sent... Comme cela a dj t voqu, ds que des informations (corps du document) sont envoyes au navigateur, len-tte est envoy au pralable. Par consquent, il nest plus question, ce moment-l, de demander des modifications de cet en-tte. 258

Gestion personnalise de len-tte HTTP

Concrtement, vous ne devez absolument pas "afficher" le moindre message avant un appel header(). Donc : pas de echo(), print(), etc., pas de message derreur et aucun code HTML ou texte quelconque, en dehors des balises <?php ... ?>. Faites galement attention ne pas laisser traner despaces ou de lignes blanches avant ou aprs les balises <?php ... ?> des fichiers inclus avant lappel header().
Si besoin, vous disposez dune fonction permettant de dterminer si len-tte a dj t envoy au client.

headers_sent()
Teste si len-tte HTTP a dj t envoy au client.

4. Les en-ttes HTTP

Syntaxe $fichier

boolean headers_sent([string &$fichier [, int &$ligne]]) Si cette option est passee et quil a dj t crit sur la sortie, alors $fichier contiendra le nom du fichier dans lequel lcriture a commence (option disponible depuis PHP 4.3.0). Si cette option est passee et quil a dj t crit sur la sortie, alors $ligne contiendra le numero de la ligne dans lequel lcriture a commence (option disponible depuis PHP 4.3.0). TRUE si len-tte a dj t mis, FALSE sinon.

$ligne

retour

Voici un court exemple de cette fonction :


<?php // rien ne va sur la sortie for ($i=0; $i<10; $i++) { // ici encore, rien nest "ecrit" } $fichier="none"; $ligne=0; echo "Par contre la lentete est envoye a cause de echo()\n"; if (headers_sent(&$fichier, &$ligne)==true) echo "Lentete a ete envoye par $fichier a la ligne $ligne\n"; else echo "Lentete na pas ete envoye\n"; ?>

Dont le rsultat serait le suivant :


Par contre la lentete est envoye a cause de echo() Lentete a ete envoye par c:\program files\apache group\apache\htdocs\tests\headers_sent.php a la ligne 9

Les exemples dapplications sont nombreux ; nous en dtaillerons trois dans ce chapitre.

259

Chapitre 4

Les en-ttes HTTP

Redirection
Il nest pas rare davoir rediriger le visiteur vers telle ou telle page en fonction de certains paramtres. Par exemple, si le visiteur est un homme, il peut tre intressant de lenvoyer vers le rayon homme dun magasin de vtements. Lutilisation des en-ttes permet, entre autres, ce type de manipulation. Pour cela, il suffit dutiliser len-tte Location avec, pour paramtre, ladresse vers laquelle rediriger le navigateur. Voici la syntaxe de la rorientation vers http://www.php.net:
header("Location: http://www.php.net");

La version 1.1 du protocole HTTP ncessite, comme paramtre, un chemin absolu. Si vous souhaitez faire une redirection au sein mme de votre serveur vers un chemin relatif la position du script appel et tre conforme cette norme, voici un moyen de transformer une adresse relative en chemin absolu laide du langage PHP.

4. Les en-ttes HTTP

header("Location: http://".$_SERVER[SERVER_NAME] ."/".dirname($_SERVER[PHP_SELF]) ."/".$chemin_relatif);

PHP se charge non seulement denvoyer len-tte au navigateur, mais il lui retourne galement le code 302 correspondant REDIRECT. Il est galement possible de retourner directement un code au navigateur. Si vous voulez renvoyer le code 404 correspondant au code derreur dun fichier inexistant, il suffit dcrire :
header("HTTP/1.0 404 Not Found");

Voici un exemple de script redirigeant le navigateur du client en fonction du sexe de la personne ; on imagine que la variable $sexe a t indique prcdemment.
<?php if ($sexe == "homme") { header("Location: rayon_homme.html"); } else { header("Location: rayon_femme.html"); } ?>

Dclaration du type MIME


PHP est principalement utilis pour gnrer du code HTML mais, comme nous le verrons par la suite, il permet galement de gnrer toutes sortes de documents et notamment des images. Or, par dfaut, la configuration de PHP veut que le serveur dclare que le document mis est un document de type text/html. Dans tous les cas o le document mis nest pas une page HTML, il convient donc den prciser le type, comme dans lexemple suivant (sil sagit dune image gif) :
header("Content-type: image/gif");

260

Cookies

Vous pouvez vous reporter lannexe sur "Les types MIME" pour avoir une liste plus complte des valeurs possibles.

Gestion des caches (des navigateurs)


Gnralement, les navigateurs (et ventuellement les systmes intermdiaires comme les proxys) utilisent des caches pour stocker localement des documents (HTML, images, etc..) rcuprs afin de ne pas avoir les redemander aux serveurs lorsque ceux-ci sont rappels (ex. : un logo que lon trouve sur toutes les pages). Si cela acclre grandement laffichage des pages dun site, il arrive quen certaines circonstances cela devienne un problme. Le cas de figure le plus flagrant est certainement celui o le document est conserv une semaine dans le cache du navigateur, alors que vous mettez jour la page quotidiennement. En fait, les navigateurs sont gnralement configurs pour vrifier une fois par jour si le document demand diffre de celui du cache. De ce fait, quelle que soit votre faon de procder en tant que concepteur de sites web, vous tes relativement labri dune plainte de ce ct-l. Le problme est plus "grave" si certains de vos scripts retournent un rsultat diffrent en fonction de variables de sessions ou de donnes externes (base de donnes) qui varient dun instant lautre, car lappel au script, lui, ne varie pas (pas de paramtre GET diffrent dun appel lautre et pas de paramtre POST). Le nom et les paramtres du script ne variant pas, le navigateur ira systmatiquement prendre la version disponible dans le cache au lieu daller chercher sa nouvelle variante. Dans ce cas, il est donc prfrable de demander au navigateur (et autres proxys) de ne pas garder de version du document dans son cache, grce aux appels suivants :
header("Cache-Control: no-cache"); header("Pragma: no-cache");

4. Les en-ttes HTTP

4.3.

Cookies

Les cookies ont t introduits par la socit Netscape dans le but de stocker des informations sur la machine cliente, ce qui permet de personnaliser un site en fonction de lidentit et des prfrences du visiteur. Ces cookies contiennent les informations que le client a bien voulu communiquer (en ayant, par exemple, rpondu un questionnaire sur ses gots). Votre site peut alors trs bien se servir de ces informations pour faciliter le parcours du visiteur. Un site de vtements peut, par exemple, demander le sexe du client et le style de vtements quil recherche pour ensuite le rediriger directement (et ce chaque nouvelle connexion) vers le rayon sport homme si cela correspond au profil enregistr dans le cookie.

Plus dinformations sur les cookies Les cookies sont dfinis dans la RFC 2109 disponible en anglais ladresse suivante : http://www.faqs.org/rfcs/rfc2109.html ou encore http://www.netscape.com/newsref/std/cookie_spec.html.

261

Chapitre 4

Les en-ttes HTTP

Gnralits
Utilisation
Les cookies doivent tre utiliss pour des informations de faible importance (pour compter, par exemple, le nombre de visites dun client). Un bon site doit pouvoir se passer des cookies pour fonctionner : on peut les utiliser, mais cela ne doit pas mettre en pril le fonctionnement du site si lutilisateur les refuse. En effet, il faut avoir lesprit que les informations sont stockes ct client, do labsence de garantie de prennit des informations.
j

Chaque navigateur a son propre systme de gestion des cookies : deux navigateurs sur la mme machine impliquent deux systmes de gestion des cookies (information en double et problmes de mise jour...). Du fait que lutilisateur peut lui-mme changer la valeur des cookies, le programmeur na aucune garantie de "last value" (cest--dire que lon ne peut pas tre certain de rcuprer la valeur qui a t stocke prcdemment). Enfin, la fonction de gestion des cookies peut tre active ou dsactive au niveau du navigateur ou simplement refuse par le visiteur.

4. Les en-ttes HTTP

Fonctionnement
Les instructions permettant la gestion des cookies sont places dans les en-ttes HTTP. Lors de lcriture dun cookie, le serveur envoie la requte HTTP et le navigateur se charge dcrire ou de modifier le cookie.

Stockage
Les cookies sont stocks de faon diffrente sur les divers navigateurs. Pour nvoquer que des deux principaux navigateurs, Internet Explorer utilise un fichier recensant tous les cookies et un fichier par cookie, tandis que Netscape utilise un seul fichier pour tous les cookies.

Cration
Pour que le serveur demande la cration dun cookie sur le poste client, len-tte de la rponse HTTP doit contenir une ligne avec la syntaxe suivante :
Set-Cookie : <NOM_COOKIE>=<valeur>; domain=<nom_de_domaine>; expires=<DATE>

Il existe dautres attributs disponibles pour dfinir un cookie ; ils sont prsents dans le tableau suivant :

262

Cookies

Tableau 4.5 : Attributs dfinissant un cookie


Attribut NOM_COOKIE Valeur VALEUR_COOKIE Type Description moins de passer par NOM_COOKIE est le seul lencodage URL, le nom et attribut obligatoire. la valeur dun cookie ne peuvent pas contenir les caractres point-virgule ;, virgule ,, et espace . Date au format : Jour_en_anglais, JJMoiAA HH:MM:SS GMT Par exemple : Saturday, 03Aug02 09:14:23 GMT est une date valide. Expires permet de dfinir une date de validit. Une fois cette date passe, la valeur du cookie ne doit plus tre prise en compte et le cookie peut tre effac par le navigateur.

Expires

DATE

4. Les en-ttes HTTP

Domain

Nom de domaine Adresse Internet contenant deux fois le caractre point (.). Xxx.xxxxxxx.xxx Par exemple : www.toutestfacile.com est une adresse valide ; php.toutestfacile.com galement. Chemin /chemin/ Par exemple : /php/ est valide.

Si le nom de domaine est laiss vide (cest gnralement le cas), le nom du serveur appelant est assign par dfaut. Il nest possible de spcifier que son propre nom de domaine ou de sous-domaine. Cet attribut permet de dfinir un sous-rpertoire o le cookie est valide, afin de rduire son champ daction. En effet, en spcifiant lattribut path, le cookie ne sera accessible que dans le sous-rpertoire dfini. Cet attribut permet de spcifier que le cookie ne pourra tre envoy que si la connexion est scurise par SSL ou S-http.

Path

Secure

Aucun

Les limites des cookies


j j j

Un cookie ne pourra excder 4 Ko. Un client ne pourra grer plus de 300 cookies. Un serveur ne pourra crer plus de 20 cookies sur un client.

263

Chapitre 4

Les en-ttes HTTP

Accs
Quand un client se connecte sur un site pour lequel il possde dj des cookies, ceux-ci sont directement envoys dans len-tte de la requte HTTP. Ce dernier contient alors une ligne ayant laspect suivant :
Cookie : <NOM1>=<valeur1> ; <NOM2>=<valeur2> ; ...

Le moyen de rcuprer cette information dpendra alors du script utilis (CGI, ASP, PHP, etc.).

Disponibilit Un cookie ntant disponible que lorsque le client le communique au serveur, un cookie dfini dans un script ne sera disponible que des scripts chargs par la suite (et non pas dans la page courante). 4. Les en-ttes HTTP

En PHP
Pour envoyer un cookie, il suffit dutiliser la fonction setCookie().

setCookie()
Dfinit un cookie qui sera ajout aux autres lments de len-tte HTTP. Syntaxe boolean setCookie(string $nomCookie [, string $valeurCookie [, int $dateExpiration [, string $chemin [, string $domaine [, boolean $securite]]]]]) Nom du cookie. Valeur du cookie. Date dexpiration du cookie (vous pouvez indiquer NULL si vous ne souhaitez pas spcifier ce paramtre). Il doit sagir dun timestamp UNIX tel que peuvent retourner les fonctions time() ou mktime(). Rpertoire de validit du cookie dans le site (vous pouvez indiquer NULL si vous ne souhaitez pas spcifier ce paramtre). Domaine de validit du cookie (vous pouvez indiquer NULL si vous ne souhaitez pas spcifier ce paramtre). TRUE si vous souhaitez que ce cookie ne soit communiqu que lors de lutilisation de connexions scurises (SSL ou SHTTP), FALSE (valeur par dfaut) sinon. TRUE en cas de succs, FALSE sinon.

$nomCookie $valeurCookie $dateExpiration

$chemin $domaine $securite

retour

Seul lattribut $nomCookie est obligatoire. Si cest le seul attribut dfini, alors le cookie correspondant sera dtruit sur la machine cliente.

264

Cookies

setCookie(), header(), mme combat Utiliser setCookie() revient spcifier des donnes de len-tte. La remarque que lon a vue pour la fonction header() sapplique donc l aussi : aucun lment du document ne doit avoir t mis avant lappel setCookie().

Erreur frquente Les cookies doivent tre effacs avec les mmes paramtres que lors de leur cration.

Ordre dappel En PHP 4 les appels setCookie() se font dans lordre naturel, de haut en bas, alors quen PHP 3 les appels se faisaient dans lordre inverse. Ainsi, pour effacer un cookie avant de dclarer une nouvelle valeur, il faut mettre linsertion avant leffacement en PHP 3 et faire le contraire en PHP 4.
Voici quelques exemples de cration de cookies :
// exemple simple sans date de validit setcookie("test", "ceci est un test"); // exemple dun cookie valide pour une heure setcookie("test", "ceci est un test", time()+3600); // exemple dun cookie valide uniquement // dans les pages scurises de http://www.toutestfacile.com/php setcookie("test", "ceci est un test", NULL, "/php/", ".toutestfacile.com", TRUE);

4. Les en-ttes HTTP

Une fois le cookie dfini, son contenu est disponible lors de lappel des scripts suivants, $_COOKIE["nomDuCookie"] (ou dans $HTTP_COOKIE_VARS directement dans ["nomDuCookie"] pour les versions de PHP<4.1.0).

Du pass faisons table rase Dans les versions de PHP antrieures 4.2.0, la configuration par dfaut fixait le paramtre register_globals du fichier php.ini on (activ). Pour des raisons de scurit (voques dans le chapitre traitant des variables externes) cela nest plus le cas. Avec loption register_globals active, le contenu du cookie tait directement disponible dans une variable portant le nom du cookie ($nomDuCookie).

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini.

265

Chapitre 4

Les en-ttes HTTP

Un tour de magie connatre Par dfaut, le fichier de configuration php.ini active loption magic_quote_gpc, et ceci pour les paramtres GET, POST et les cookies. Ceci a pour effet dautomatiquement "chapper" les apostrophes. Autrement dit, cela ajoute un anti-slash devant les apostrophes des paramtres passs par les mthodes GET, POST et les cookies. Si cest trs pratique pour stocker le paramtre en base de donnes, cela peut devenir gnant pour un affichage dans le document. Si vous souhaitez supprimer ces anti-slashes, il vous suffit dappliquer la fonction stripSlashes() sur ces valeurs.
Il est possible de stocker directement plusieurs valeurs dun tableau. Un cookie sera cr par entre dans le tableau. Au moment de rcuprer ces valeurs, il suffira dy accder comme pour nimporte quel autre tableau. Par exemple, pour stocker ce tableau contenant trois valeurs :
setcookie ("tableau[un]", "valeur1"); setcookie ("tableau[deux]", "valeur2"); setcookie ("tableau[trois]", "valeur3");

4. Les en-ttes HTTP

Pour afficher ces valeurs, il suffit dcrire :


while (list ($cle, $valeur) = each ($_COOKIE["tableau"])) { echo "$cle: $valeur<br>\n"; }

Exemple utilisant des cookies


Mise en situation
Lexemple est celui dun magasin dinstruments de musique voulant offrir la possibilit ses clients de mettre des articles dans un panier virtuel (les utilisateurs refusant les cookies ne pourront pas utiliser ce panier). Les fonctionnalits de ce panier virtuel seront simples. Il faudra tre en mesure dajouter des articles un un, de vider le panier et de calculer le montant total des articles contenus dans le panier. Pour simplifier, on considrera que ce vendeur ne propose que trois articles : une guitare, une basse et une batterie (ce qui est suffisant pour monter un groupe). Les informations lies au panier seront stockes dans des cookies sous la forme dun tableau.

Agencement des chiers


Pour cet exemple, nous utiliserons quatre fichiers :
j j j

Une page daccueil accueil.html. Une page dinitialisation initialisation.php qui sera en charge dinitialiser les cookies permettant la gestion du panier. Une page pour ajouter un article ajout_article.php, cette page sera la page principale pour linterface, et cest l que lutilisateur ajoutera des articles, videra son panier ou calculera le montant de celui-ci.

266

Cookies

Une page pour calculer le montant total du panier calcul_total.php. Ce fichier calculera la somme des montants des articles prsents virtuellement dans le panier. Lutilisateur aura alors le choix dajouter dautres articles ou de vider son panier.

Voici un graphe reprsentant les interactions entre les diffrents scripts.


Figure 4.3 : Les diffrents appels

4. Les en-ttes HTTP

j j j j j j

accueil.htm propose un lien vers initialisation.php. initialisation.php redirige vers ajout_article.php aprs avoir initialis les donnes. ajout_article.php propose un lien vers initialisation.php pour rinitialiser les donnes. chaque ajout darticle, ajout_article sappelle lui-mme pour se mettre jour. ajout_article propose un lien vers calcul_total.php. Et calcul_total.php propose des liens vers initialisation.php (pour repartir de zro) et ajout_article.php (pour complter le panier).

Contenu des chiers accueil.html


Listing 4.1 : accueil.html
<html> <head> <title>Mon magasin de musique</title> </head> <body bgcolor="#FFFFFF"> <p align="center"><b>Bienvenu chez MusicAGogo!!!</b></p> <p align="center">Votre panier est vide</p> <p align="center"> <a href="initialisation.php">cliquer ici pour le remplir </a> </p> </body> </html>

267

Chapitre 4

Les en-ttes HTTP

Le script daccueil est une simple page au format HTML, avec un lien vers le script dinitialisation des cookies.

initialisation.php
Listing 4.2 : initialisation.php
<?php setCookie("panier[guitare]", 0); setCookie("panier[basse]", 0); setCookie("panier[batterie]", 0); header("Location: ajout_article.php"); ?>

4. Les en-ttes HTTP

Le script dinitialisation met zro le tableau qui reprsentera notre panier. Une fois les trois valeurs du tableau initialises, le navigateur du client est redirig vers la page de linterface principale. Comme nous lavons dit prcdemment, la gestion des cookies est appele avant toute autre fonction den-tte.

ajout_article.php
Listing 4.3 : ajout_article.php
<?php $panier=$_COOKIE["panier"]; switch (@$_GET["ajout"]) { case "guitare": $panier["guitare"]++; setCookie("panier[guitare]", $panier["guitare"]); break; case "basse": $panier["basse"]++; setCookie("panier[basse]", $panier["basse"]); break; case "batterie": $panier["batterie"]++; setCookie("panier[batterie]", $panier["batterie"]); break; } ?> <html> <head> <title>Mon magasin de musique</title> </head> <body bgcolor="#FFFFFF"> <table border="4" cellspacing="4" cellpadding="4" align="center"> <tr align="center">

268

Cookies

<td>Ajouter</td> <td>Votre commande</td> </tr> <tr align="center"> <td> <a href="ajout_article.php?ajout=guitare">Une guitare</a> (199E) </td> <td><?php echo $panier["guitare"]?> guitare(s)</td> </tr> <tr align="center"> <td> <a href="ajout_article.php?ajout=basse">Une basse</a> (199E) </td> <td><?php echo $panier["basse"]?> basse(s)</td> </tr> <tr align="center"> <td> <a href="ajout_article.php?ajout=batterie">Une batterie</a> (2499E) </td> <td><?php echo $panier["batterie"]?> batterie(s)</td> </tr> </table> <p align="center"> <a href="initialisation.php">vider mon panier</a> </p> <p align="center"> <a href="calcul_total.php">calculer le total</a> </p> </body> </html> Figure 4.4 :

4. Les en-ttes HTTP

Interface principale

Aprs avoir rcupr la valeur du tableau contenue dans les cookies, une comparaison est effectue entre la valeur de la variable $ajout et les diffrentes chanes de caractres possibles. Ensuite, la valeur est incrmente puis stocke nouveau dans le cookie correspondant.

269

Chapitre 4

Les en-ttes HTTP

Cette page fait des appels elle-mme, ce qui permet dajouter constamment des articles. Un lien vers initialisation.php est disponible, qui a pour effet de remettre zro le contenu du panier. Un autre lien vers le calcul du montant du panier est disponible. Comme cela a dj t signal, la nouvelle valeur dun cookie nest disponible quaprs avoir recharg la page ou chang de page. Pour afficher dans ce script le nombre exact darticles contenus dans le panier, on ne peut faire appel la valeur courante du cookie (par $_COOKIE) ; cest donc le contenu de la variable du tableau $panier qui a t utilis (aprs avoir t incrment puis stock).

calcul_total.php
Listing 4.4 : calcul_total.php
<?php $panier = $_COOKIE["panier"]; $total = 0; $total += $panier["guitare"]*199; $total += $panier["basse"]*199; $total += $panier["batterie"]*2499; ?> <html> <head> <title>Mon magasin de musique</title> </head> <body bgcolor="#FFFFFF"> <p align="center">Le total de votre panier: <?php echo $total?> Euros.</p> <p align="center"> <a href="ajout_article.php">Modifier mon panier</a> </p> <p align="center"> <a href="initialisation.php">Vider mon panier</a> </p> </body> </html>

4. Les en-ttes HTTP

Ce script trs simple reprend les valeurs stockes dans le panier pour calculer le montant total de celui-ci. Deux liens sont disponibles : lun vers linitialisation (remise zro) des variables, lautre vers linterface principale.

270

Sessions

Figure 4.5 : Montant total

4.4.

Sessions

4. Les en-ttes HTTP

Les sessions proposes dans PHP depuis la version 4 permettent, comme les cookies, de stocker des informations spcifiques lutilisateur. Mais, alors que les cookies permettent de stocker des informations (en petite quantit) sur le poste du client pour une priode pouvant aller de quelques secondes plusieurs semaines, les sessions permettent de stocker autant dinformations que ncessaire. Pour cela, le serveur assigne au client un identifiant unique (appel identifiant de session) li une instance de navigateur sur une machine (adresse IP) donne. Du fait que le client peut tout moment arrter et relancer son navigateur ou changer dIP (aprs stre dconnect du rseau Internet), la dure de vie de la session nexcde quasiment jamais une journe. Les sessions ne sont donc utilises que pour conserver en mmoire des informations tout au long de la visite du client (mais pas plus longtemps). Par consquent, il est mme conseill de mettre un terme la session aprs une priode donne dinactivit (de lordre de 20 mn, temps au-del duquel on peut considrer que le visiteur a dfinitivement quitt le site) afin de librer les ressources. Vous avez certainement rencontr ce genre de situation o lon vous demande de vous identifier nouveau. En contrepartie, avec les sessions, vous pouvez tre sr que votre site fonctionnera quels que soient le navigateur et lattitude du visiteur (rappelons quun visiteur peut refuser un cookie). Lautre diffrence principale rside dans le fait que les sessions sont stockes sur le serveur ; le contrle des sessions est donc gr 100 % par lauteur des scripts (il ne peut y avoir de modification ou de suppression par le visiteur). Comme cela a dj t dit, chaque utilisateur est attribu un identifiant de session. Afin de garder la trace de ce dernier, lidentifiant est transmis de page en page. Cela peut se faire de deux faons :
j j

Par le navigateur qui, chaque appel au serveur, communiquera le cookie contenant lidentifiant de session que le serveur lui aura pralablement demand de crer. Par le serveur qui, pour chaque page gnre, compltera les URL relatives des liens (donc celles qui pointent vers le serveur lui-mme, mais pas les liens vers un site tiers) avec un paramtre indiquant lidentifiant de session (cest ce que lon appelle l"URL rewriting" ou la rcriture dURL).

271

Chapitre 4

Les en-ttes HTTP

La premire solution est la plus simple pour le serveur, mais elle ne peut tre utilise si le client refuse les cookies ; il faut alors se rabattre sur la seconde. Comme nous le verrons un peu plus loin, ceci peut se faire tant manuellement quautomatiquement. Pour chaque page ncessitant lutilisation de variables de sessions, il faudra appeler la fonction session_start() afin de permettre au serveur de dterminer si un identifiant de session a dj t assign au visiteur. Si cest le cas, il lui suffit de le rcuprer soit dans le cookie soit depuis lURL, tout comme les valeurs des diffrentes variables ; sinon, il doit le crer, et le serveur doit demander la gnration dun cookie. Si celle-ci choue, il optera alors pour la rcriture dURL.

session_start()
Rclame lutilisation de variables de sessions au cours du script.

4. Les en-ttes HTTP

Syntaxe retour

boolean session_start() TRUE

session_start() et cookie() : ami-ami Il va de soi que si lidentifiant de session doit tre stock dans un cookie, alors les contraintes dutilisation de session_start() sont les mmes que celles de cookie(). Ainsi, session_start() ne peut plus tre appel une fois le dbut du document mis (i.e. une fois len-tte HTP envoy).
Il sera possible de se passer de lappel session_start() si PHP est configur de telle sorte que le paramtre session.auto_start de php.ini soit activ (i.e. mis 1).

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini.

la manire des cookies, les variables de sessions sont disponibles directement dans le tableau $_SESSION. Pour accder une valeur donne, il suffit donc dappeler quelque chose comme $_SESSION["maVariable"] (ou $HTTP_SESSION_VARS["maVariable"] pour les versions de PHP infrieures 4.1).

Du pass faisons table rase Dans les versions de PHP antrieures 4.2.0, la configuration par dfaut fixait le paramtre register_globals du fichier php.ini on (activ). Pour des raisons de scurit (voques dans le chapitre traitant des variables externes) cela nest plus le cas.

272

Sessions

Avec loption register_globals active, le contenu de la variable de session tait directement disponible dans une variable portant le nom de la variable de session ($nomVariableSession).

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini.
Voici un exemple dutilisation. Il sagit tout simplement dun compteur qui est incrment chaque appel de la page (si la variable de session nexiste pas, cest quil sagit dune nouvelle session et le compteur est initialis la valeur 0).
<?php session_start(); if (!isset($_SESSION[maVariable])) { $_SESSION[maVariable] = 0; } else { $_SESSION[maVariable]++; } echo $_SESSION[maVariable]; ?>

4. Les en-ttes HTTP

Pour grer les sessions de faon optimale, il est possible de configurer PHP laide des nombreuses options offertes par le fichier de configuration.

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini.
Ces options peuvent tre visualises par un simple appel phpinfo().
Figure 4.6 : phpinfo()

273

Chapitre 4

Les en-ttes HTTP

Jusqu la version 4.1.1 (comprise), lutilisation de la rcriture (automatique) dURL ne pouvait se faire que si PHP avait t compil avec loption enabletranssid. Il fallait en outre lactiver ou la dsactiver avec loption session.usetranssid, introduite dans la version 4.0.3 ( positionner 1 pour lactiver, 0 sinon). Depuis la version 4.2.0, lutilisation de la rcriture (automatique) dURL ne ncessite plus lutilisation de directives de compilation. Lactivation de ce procd ne dpend plus que de loption session.usetranssid (qui est, par dfaut, active). La liste des balises HTML contrles est dfinie dans le paramtre url_rewriter.tags et, outre le fait que iframe napparaisse pas dans la liste, il faut garder lesprit que tous les liens crs par des fonctions Javascript (par exemple) ne profiteront pas de cette manipulation. Il faudra donc ncessairement ajouter manuellement lidentifiant de session lURL (si lon souhaite que cela fonctionne avec les navigateurs refusant les cookies) pour ces liens.

Exemple utilisant des sessions


4. Les en-ttes HTTP

Mise en situation
Reprenons le mme exemple que pour les cookies, cest--dire celui dun magasin de musique vendant trois instruments et proposant un panier virtuel aux visiteurs de son site Internet.

Contenu des chiers accueil.html


Listing 4.5 : accueil.html
<html> <head> <title>Mon magasin de musique</title> </head> <body bgcolor="#FFFFFF"> <p align="center"><b>Bienvenu chez MusicAGogo!!!</b></p> <p align="center">Votre panier est vide</p> <p align="center"> <a href="initialisation.php">cliquer ici pour le remplir </a> </p> </body> </html>

Le script daccueil est une simple page au format HTML, avec un lien vers le script dinitialisation des sessions.

274

Sessions

initialisation.php
Listing 4.6 : initialisation.php
<?php session_start(); $_SESSION[panier] = array("guitare"=>0, "basse"=>0, "batterie"=>0); header("Location: ajout_article.php"); ?>

Une fois la session existante rappele ou cre, le tableau panier est initialis et stock dans la session ; le navigateur du client est ensuite redirig vers la page dajout dlments au panier. Ce script fonctionnera tel quel condition que lutilisateur accepte les cookies. Si ce nest pas le cas, il fonctionnera galement si la rcriture (automatique) dURL est active (sachant que ce script ne contient que des URL relatives). Vous constaterez alors que les URL (qui saffichent dans la barre du navigateur) ont t compltes pour ajouter un identifiant de session. Dans les autres cas, si vous souhaitez que votre script fonctionne mme si le visiteur refuse les cookies, il faut ajouter lURL la chane de caractres stocke dans la constante SID (pour raliser manuellement ce que loption session.use_trans_sid = 1 permet). Ce qui donne :
header("Location: ajout_article.php?".SID);

4. Les en-ttes HTTP

La constante SID est compose de la concatnation du nom de lidentifiant de session (disponible via la fonction session_name() et qui par dfaut vaut "PHPSESSID"), dun signe gal et de la valeur de lidentifiant de session (disponible via la fonction session_id()). Ainsi, SID vaut session_name()."=".session_id().

ajout_article.php
Listing 4.7 : ajout_article.php
<?php session_start(); $panier=$_SESSION[panier]; switch (@$_GET["ajout"]) { case "guitare": $panier["guitare"]++; break; case "basse": $panier["basse"]++; break; case "batterie": $panier["batterie"]++; break; } $_SESSION[panier] =

275

Chapitre 4

Les en-ttes HTTP

?>

array("guitare" => $panier["guitare"], "basse" => $panier["basse"], "batterie"=> $panier["batterie"]);

<html> <head> <title>Mon magasin de musique</title> </head> <body bgcolor="#FFFFFF"> <table border="4" cellspacing="4" cellpadding="4" align="center"> <tr align="center"> <td>Ajouter</td> <td>Votre commande</td> </tr> <tr align="center"> <td><a href="ajout_article.php?ajout=guitare"> Une guitare</a> (199E) </td> <td><?php echo $panier["guitare"]?> guitare(s)</td> </tr> <tr align="center"> <td><a href="ajout_article.php?ajout=basse"> Une basse</a> (199E) </td> <td><?php echo $panier["basse"]?> basse(s)</td> </tr> <tr align="center"> <td><a href="ajout_article.php?ajout=batterie"> Une batterie</a> (2499E) </td> <td><?php echo $panier["batterie"]?> batterie(s)</td> </tr> </table> <p align="center"><a href="initialisation.php"> vider mon panier</a></p> <p align="center"><a href="calcul_total.php"> calculer le total</a></p> </body> </html>

4. Les en-ttes HTTP

Une fois la session rappele, la variable $panier est rcupre, puis $ajout est teste afin dincrmenter la bonne valeur. Une fois ce test effectu, la session est mise jour avec les nouvelles valeurs. L encore, si votre serveur nest pas configur pour raliser automatiquement la rcriture dURL, vous devez complter les URL avec la constante SID si vous voulez quil fonctionne galement pour les clients refusant les cookies.

276

Sessions

calcul_total.php
Listing 4.8 : calcul_total.php
<?php session_start(); $panier = $_SESSION["panier"]; $total = 0; $total += $panier["guitare"]*199; $total += $panier["basse"]*199; $total += $panier["batterie"]*2499; ?> <html> <head> <title>Mon magasin de musique</title> </head> <body bgcolor="#FFFFFF"> <p align="center"> Le total de votre panier: <?php echo $total?> Euros. </p> <p align="center"> <a href="ajout_article.php">Modifier mon panier</a> </p> <p align="center"> <a href="initialisation.php">Vider mon panier</a> </p> </body> </html>

4. Les en-ttes HTTP

Ce script est plus simple comprendre que le prcdent. La session est rcupre puis la variable $panier en est extraite. Bien entendu, si besoin est, il faut prendre soin, l encore, de passer lidentifiant de session en paramtre.

Stockage personnalis des variables de sessions


Par dfaut les variables de sessions sont stockes dans des fichiers temporaires (comme lindique le paramtre session.save_handler du fichier php.ini fix la valeur "files"). En modifiant ce paramtre user, il est possible de redfinir soi-mme la faon dont seront gres les sessions.

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini.
Il est, par exemple, possible de stocker les paramtres dans une base de donnes (lexemple que nous donnerons ici utilisera une base de donnes MySQL).

277

Chapitre 4

Les en-ttes HTTP

Vous pouvez vous reporter au chapitre "Lutilisation des bases de donnes" pour en savoir plus sur lutilisation de MySQL avec PHP.
Pour cela, nous crerons une table avec trois champs : lidentifiant de session, la date dexpiration, et la valeur des variables de sessions. Notez bien que les variables de sessions seront automatiquement srialises et dsrialises (autrement dit, toutes les valeurs seront regroupes en une chane de caractres et inversement. Voir plus loin les fonctions session_encode() et session_decode()) par PHP). Voici la syntaxe SQL pour la table sessions.
CREATE TABLE sessions ( idsession CHAR(32) NOT NULL, expiration INT(11) NOT NULL, valeur TEXT NOT NULL, PRIMARY KEY (idsession) );

4. Les en-ttes HTTP

Pour grer les sessions, PHP appelle six fonctions. Pour personnaliser lutilisation des sessions, il faut donc crer six fonctions auxquelles PHP fournira les paramtres, et indiquer PHP dutiliser ces fonctions en lieu et place des fonctions par dfaut.
boolean ouvrirSession($cheminSession, $nomSession)

Cette fonction permet dinitialiser la gestion de sessions. En paramtre, lon trouve le chemin (dans le cas dune gestion par fichiers) o stocker les sessions. Il sagit en fait du paramtre session.save_path du fichier php.ini qui peut contenir nimporte quelle information sans que ce soit ncessairement un chemin. $nomSession est le nom de la session tel quil est dfini dans le fichier de configuration de PHP sous le nom session.name (par dfaut, cest PHPSESSID). Elle devra retourner TRUE en cas de succs, FALSE sinon. Dans notre exemple, cette fonction servira tablir la connexion avec la base de donnes.
boolean fermerSession()

Cette fonction permet de librer dventuelles ressources occupes pour la gestion des sessions. Elle devra retourner TRUE en cas de succs, FALSE sinon. Dans notre exemple utilisant une connexion persistante, rien naura besoin dtre fait dans cette fonction. Sinon, nous aurions pu envisager de clore la connexion.
boolean ecrireSession($idSession, $valeur)

Cest cette fonction que lon va indiquer comment stocker les variables de sessions. $idSession est lidentifiant de session, qui servira stocker la session (il pourra servir dfinir le nom du fichier, qui sera donc unique, ou une entre en base de donnes...). $valeur est la valeur stocker dans la session ; elle est fournie srialise. Elle devra retourner TRUE en cas de succs, FALSE sinon.

278

Sessions

Dans notre exemple, cest ici quil faut faire linsertion en base de donnes en faisant attention de crer une nouvelle entre sil nexiste pas dentre pour cet identifiant, ou de modifier lentre existante.
mixed lireSession($idSession)

La fonction de lecture a pour paramtre un identifiant de session. Il faut retourner la valeur (srialise) sauvegarde, ou FALSE en cas derreur. Dans lexemple, il suffira de faire une recherche dans la table de la valeur correspondant la lidentifiant de session fourni.
boolean detruireSession($idSession)

Cette fonction dtruit la session dont lidentifiant est pass en paramtre. Elle devra retourner TRUE en cas de succs, FALSE sinon. Dans notre exemple, il suffira de supprimer lentre correspondant lidentifiant pass en paramtre.
boolean nettoyerSession($dureeVie)

4. Les en-ttes HTTP

Cest la fonction qui sera appele alatoirement pour nettoyer les sessions invalides. La dure de vie, dfinie dans le fichier de configuration par le paramtre session.gc_maxlifetime, est passe en paramtre. Elle devra retourner TRUE en cas de succs, FALSE sinon. Dans notre exemple, il suffira de supprimer toutes les entres dont la date dexpiration est passe. Enfin, pour indiquer PHP dutiliser les fonctions ainsi dfinies, vous devrez faire appel la fonction session_set_save_handler().

session_set_save_handler()
Indique PHP dutiliser des fonctions personnalises pour la gestion des sessions. Syntaxe void session_set_save_handler(function $ouvrirSession, function $fermerSession, function $lireSession, function $ecrireSession, function $detruireSession, function $nettoyerSession) Nom de la fonction appeler louverture de la session (cf. ci-avant). Nom de la fonction appeler la fermeture de la session (cf. ci-avant). Nom de la fonction appeler la lecture du contenu dune session. Nom de la fonction appeler la sauvegarde du contenu dune session. Nom de la fonction appeler la destruction du contenu dune session. Nom de la fonction appeler pour dtruire les sessions primes.

$ouvrirSession $fermerSession $lireSession $ecrireSession $detruireSession $nettoyerSession

279

Chapitre 4

Les en-ttes HTTP

session_mysql.php
Listing 4.9 : session_mysql.php
<?php define("HOTE", "localhost"); define("UTILISATEUR", "root"); define("MOT_DE_PASSE", "MotDePasse"); define("BASE_DE_DONNEES", "biblephp"); define("DUREE_VIE_SESSION", get_cfg_var("session.gc_maxlifetime")); $connexionSession = ""; function ouvrirSession($cheminSession, $nomSession) { global $connexionSession; $connexionSession = mysql_pconnect(HOTE, UTILISATEUR, MOT_DE_PASSE) or die("Impossible de se connecter la base de donnes"); mysql_select_db(BASE_DE_DONNEES, $connexionSession) or die("Base de donnes introuvable"); return TRUE; } function fermerSession() { return TRUE; } function ecrireSession($idSession, $valeur) { global $connexionSession; if (mysql_query("INSERT INTO sessions VALUES ($idSession, ".(time()+DUREE_VIE_SESSION).", $valeur)", $connexionSession)) { return TRUE; } else { return mysql_query("UPDATE sessions SET expiration = ".(time()+DUREE_VIE_SESSION).", valeur = $valeur WHERE idSession = $idSession", $connexionSession); } } function lireSession($idSession) { global $connexionSession; $requete = mysql_query("SELECT valeur FROM sessions WHERE idsession=$idSession AND expiration > " . time(),

4. Les en-ttes HTTP 280

Sessions

$connexionSession); if (list($valeur) = mysql_fetch_row($requete)) { return $valeur; } else { return FALSE; } } function detruireSession($idSession) { global $connexionSession; return mysql_query("DELETE FROM sessions WHERE idsession=$idSession", $connexionSession); } function nettoyerSession($dureeVie) { global $connexionSession; return mysql_query("DELETE FROM sessions WHERE expiration < " . time(), $connexionSession); } session_set_save_handler("ouvrirSession", "fermerSession", "lireSession", "ecrireSession", "detruireSession", "nettoyerSession"); ?>

4. Les en-ttes HTTP

Adapter le script votre environnement Les quatre constantes HOTE, UTILISATEUR, MOT_DE_PASSE et BASE_DE_DONNEES doivent tre renseignes selon votre configuration.
Compte tenu des remarques prcdentes, il nest pas difficile dcrire soi-mme ce type de script. La dure de vie dune session est rcupre depuis le fichier de configuration grce la fonction get_cfg_var(). Cette valeur nous servira dterminer la date dexpiration des sessions.

test.php
Ceci est un fichier permettant de tester la gestion des sessions telle quon vient de la dfinir.

Listing 4.10 : test.php


<?php include("session_mysql.php");

281

Chapitre 4

Les en-ttes HTTP

session_start(); if (!isset($_GET["valeur"])) { $_GET["valeur"] = 0; } if ( (!isset($_GET["action"])) ||(!isset($_SESSION["variableSession"]))) { $_GET["action"] = "initialiser"; } switch($_GET["action"]) { case "detruire": session_destroy(); break; case "gc": nettoyerSession(get_cfg_var("session.gc_maxlifetime")); break; case "incrementer": $_SESSION["variableSession"]++; break; case "initialiser": $_SESSION["variableSession"] = 0; break; } ?> <html> <head><title>Test</title></head> <body> <p> Valeur courante:<?php echo $_SESSION["variableSession"]?> <br /> <a href="test.php?action=incrementer"> Incrmenter la variable de session</a> <a href="test.php?action=detruire">Destruction de la session</a> <a href="test.php?action=gc">Forcer le gc</a> </p> </body>

4. Les en-ttes HTTP

Ce script trs simple se contente dafficher la valeur dune variable de session, et de proposer trois liens : un pour lincrmenter, un pour dtruire la session et un pour forcer lappel au garbage collector charg de supprimer les sessions primes.
Figure 4.7 : Interface de test

282

Sessions

Clore une session


Il nest gnralement pas possible de dterminer quand mettre fin une session. En effet, pour cela, il faudrait savoir quand le visiteur a quitt le site. Cest pourquoi il faut gnralement attendre la fin du dlai dexpiration pour voir les sessions disparatre. Toutefois, si vous proposez sur votre site un lien Dconnexion, il vous sera possible de faire proprement appel la fonction session_destroy() (Ce qui vitera en plus quun autre utilisateur partageant le mme poste de travail puisse accder au compte du prcdent).

session_destroy()
Dtruit les variables de la session en cours. Syntaxe retour boolean session_destroy(void)

4. Les en-ttes HTTP

TRUE en cas de succs, FALSE sinon.

Il est souhaitable de vider au pralable le contenu des variables de sessions. Ainsi le script de dconnexion pourra ressembler :
<?php session_start(); $_SESSION = array(); session_destroy(); echo "Au revoir, et bientt"; ?>

Les autres fonctions


Comme cela a t prcis, les variables composant une session sont srialises avant dtre stockes (par dfaut, dans un fichier), et dsrialises aprs avoir t rcupres. Pour raliser manuellement cette opration, vous devez faire appel aux fonctions session_code() et session_decode().

session_encode()
Srialise la session (convertit lensemble des variables de sessions en une chane de caractres unique). Syntaxe retour string session_encode(void) Chane encode avec le contenu de la session.

283

Chapitre 4

Les en-ttes HTTP

session_decode()
Dsrialise une chane de caractres contenant des variables de sessions (recrant ainsi lensemble des variables de la session). Syntaxe $variable retour boolean session_decode(string $variable) Chane de caractres dsrialiser. TRUE en cas de succs, FALSE sinon.

Dautres fonctions, moins souvent utilises, sont disponibles pour la gestion des sessions. Il est par exemple possible de remplacer lutilisation des paramtres habituellement dfinis dans le fichier php.ini par des paramtres fixs par le script.

4. Les en-ttes HTTP

session_module_name()
Permet de dfinir ou de connatre le gestionnaire de sessions utilis (habituellement dfini par le paramtre session.save_handler de php.ini). Syntaxe $gestionnaire string session_module_name([string $gestionnaire]) Indiquer (cf. session_set_save_handler()) : "files" si les donnes de session doivent tre stockes "simplement" dans des fichiers temporaires. user si elles doivent tre stockes en utilisant les fonctions personnalises. retour Le gestionnaire de sessions utilis savoir files" ou "user".

session_save_path()
Permet de dfinir ou de connatre lemplacement o seront sauves les sessions (habituellement dfini par le paramtre session.save_path de php.ini). Syntaxe $chemin retour string session_save_path([string $chemin]) Chemin que lon souhaite dfinir en tant que rpertoire pour stocker les sessions. Nom du rpertoire o sont stocks les fichiers temporaires de session.

284

Sessions

session_name()
Permet de dfinir ou de connatre le nom du paramtre de lURL contenant lidentifiant de session (habituellement dfini par le paramtre session.name de php.ini). Syntaxe $nomIdSession retour string session_name([string $nomIdSession]) Nouveau nom du paramtre didentifiant de session. Nom de lidentifiant de session (par dfaut PHPSESSID).

session_id()
Permet de dfinir ou de connatre lidentifiant de session attribu au visiteur. Syntaxe $idSession retour string session_id([string $idSession]) Nouvel identifiant de session utiliser. Identifiant de session utilis.

4. Les en-ttes HTTP

session_regenerate_id()
Permet de rgnrer un nouvel identifiant pour une mme session. Cette fonction a t introduite avec PHP 4.3.2. Syntaxe : retour boolean session_regenerate_id(void) TRUE si un nouvel identifiant a t rgnr, FALSE sinon.

Il est galement possible de connatre ou de fixer les paramtres du cookie charg de sauvegarder lidentifiant de session sur la machine du visiteur (sans tenir compte des paramtres dfinis dans le fichier php.ini).

session_get_cookie_params()
Permet de rcuprer les informations du cookie de session. Syntaxe retour array session_get_cookie_params(void) Tableau associatif contenant les informations du cookie. On y retrouve : "lifetime", la dure de vie du cookie. "path" le chemin o est stock le cookie. "domain" le domaine sur lequel le cookie est valable. "secure" un boolen indiquant si le cookie ne doit tre envoy que par une connexion scurise.

285

Chapitre 4

Les en-ttes HTTP

session_set_cookie_params()
Permet de dfinir les paramtres du cookie de session. Syntaxe $dureeVie $chemin $domaine void session_set_cookie_params(int $dureeVie [, string $chemin [, string $domaine]]) Nouvelle dure de vie en secondes (habituellement dfinie par le paramtre session.cookie_lifetime du fichier php.ini). Chemin o le cookie est valide (habituellement dfini par le paramtre session.cookie_path du fichier php.ini). Domaine de validit du cookie (habituellement dfini par le paramtre session.cookie_domain du fichier php.ini).

4. Les en-ttes HTTP

Les pages utilisant des variables de sessions prsentent gnralement un aspect diffrent dun appel lautre, sans que leur URL ne soit modifie. Pour que le visiteur puisse profiter des modifications apportes la page, il faut absolument interdire lutilisation du cache par le navigateur. Cest pour cela que, par dfaut, les pages faisant appel aux sessions demandent galement linterdiction de la mise en cache. Mais ces paramtres peuvent tre modifis avec la fonction suivante :

session_cache_limiter()
Permet de dfinir ou de connatre la restriction du cache applique (habituellement dfinie par le paramtre session.cache_limiter de php.ini). Syntaxe string session_cache_limiter([string $restriction_cache])

$restriction_cache Ce paramtre peut prendre les valeurs : "nocache" si lon souhaite que le client ne mette pas la page dans le cache. "public" (ou "private" qui est lgrement plus restrictif) pour autoriser la mise en cache. "private_no_expire" (depuis la version PHP 4.2.0) permet de ne pas envoyer len-tte Expire qui causait des problmes avec la restriction du cache. retour Retourne la restriction du cache en cours.

session_cache_expire()
Permet de dfinir ou de connatre la dure avant expiration du cache (habituellement dfinie par le paramtre session.cache_expire de php.ini). Cette fonction a t introduite partir de la version 4.2.0.

286

Mise en cache avant mission des donnes

Syntaxe $expirationCache retour

int session_cache_expire([int $expirationCache]) Nouvelle valeur (en secondes) dexpiration du cache. Retourne la valeur actuelle dexpiration du cache.

Vous disposez aussi de :

session_write_close()
Termine la session et enregistre les variables de sessions, ce qui est automatiquement fait la fin des scripts. Attention, dans ce cas, aucune rcriture dURL ne sera effectue. Syntaxe void session_write_close(void)

4. Les en-ttes HTTP

Les fonctions historiques


Les fonctions suivantes ne doivent plus tre utilises (pas avec le tableau $_SESSION, ni mme dailleurs avec $HTTP_SESSION_VARS) :
session_register() permettait de dfinir une variable globale comme tant une variable de session. Ainsi, register("maVariable"); faisait de $maVariable une variable de session. Avec lutilisation de $_SESSION["maVariable"], aucun doute nest possible. session_unregister() mettait simplement un terme lassociation entre la variable et une variable de session. Avec $_SESSION, il ny a videmment pas besoin dquivalent. session_is_registered() permettait de tester si une variable tait une variable de session. L encore, avec $_SESSION, il ny a pas besoin dquivalent. session_unset() permettait de librer le contenu des variables de sessions. Avec $_SESSION, il suffit de faire $_SESSION = array().

4.5.

Mise en cache avant mission des donnes

Les fonctions de base


Une srie de fonctions de contrle de sortie permet de grer soi-mme lmission des donnes. Habituellement, le fait de gnrer le document (avec les commandes echo ou print par exemple), et donc denvoyer len-tte HTTP avant de faire appel une fonction modifiant len-tte, aboutit inexorablement au message derreur suivant : "Cannot add header information - headers already sent". Il est possible dviter ceci en demandant de ne pas envoyer les lments du document au moment o ils sont gnrs, mais de le faire une fois tous les lments de len-tte dfinis. Pour cela, nous disposons des fonctions ob_start() et ob_end_flush().

287

Chapitre 4

Les en-ttes HTTP

ob_start()
Demande la mise en cache de ce qui va sur la sortie standard (ce qui est destin au client). Syntaxe $fonction void ob_start([function $fonction]) Fonction appliquer sur le contenu du cache (cf. compression des donnes).

ob_end_ush()
Met fin la mise en mmoire de la sortie et met le contenu du cache vers le navigateur.

4. Les en-ttes HTTP

Syntaxe

void ob_end_flush(void)

Ainsi, lexemple suivant ne gnrera pas derreur malgr lappel setCookie() aprs un echo.
<?php ob_start(); echo "Jenvoie du texte sur la sortie avant de definir un cookie"; setCookie("cookie", "je defini un cookie apres avoir ecrit du texte"); ob_end_flush(); ?>

Le fichier de configuration de PHP permet dactiver systmatiquement le systme de cache, grce au paramtre output_buffering. Cela revient alors placer ob_start() au dbut de chaque script, et ob_end_flush(), qui a pour effet dafficher le contenu du cache la fin.

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini. Ne pas cder la facilit Mme si lutilisation du systme de cache permet de mlanger allgrement gnration du document et gnration de len-tte HTTP, il est fortement conseill (pour des raisons de performance) de se passer de lutilisation de ces fonctions (dans ce cadre-l). Dautant quil est gnralement facile de saffranchir de la difficult que cela pourrait engendrer. Il est de toute faon de bon usage de commencer un script par toutes les oprations de traitement avant les oprations de mise en page.

288

Mise en cache avant mission des donnes

Compression des donnes


La plupart des navigateurs, dont Internet Explorer et Netscape, permettent la dcompression transparente des donnes (les types de compression supports sont prciss dans la variable externe $_SERVER["HTTP_ACCEPT_ENCODING"]). Si le serveur dtecte que le navigateur du client supporte la compression Gzip (par exemple), il peut dcider denvoyer des donnes compresses celui-ci, qui les dcompressera avant de les afficher. Cette procdure sera totalement transparente pour lutilisateur qui ne verra quun gain en terme de temps de tlchargement des pages. Bien entendu, cette procdure demandera un petit peu plus de travail au serveur, mais si celui-ci est suffisamment puissant, son utilisation est avantageuse question rapidit. Pour cela, il suffit de spcifier le paramtre "fonction de compression" de la fonction ob_start(). Cette fonction qui peut tre une fonction personnalise doit accepter un paramtre de type chane de caractres, et simplement en retourner la version compresse. Voici un morceau de script mettre en dbut de chacun de vos scripts pour utiliser la compression Gzip.
<?php function compression($sortie) { // Cette fonction ne fait que retourner la compression de la chane // de caractres prcise en paramtre. return gzencode($sortie); } // Vrification du support de gzip par le client if (strstr($_SERVER[HTTP_ACCEPT_ENCODING], gzip)) { // Dbut de mise en mmoire en fournissant comme paramtre // la fonction appliquer sur la sortie ob_start("compression"); // Prvient le navigateur que les donnes sont compresses. header("Content-Encoding: gzip"); } ?>

4. Les en-ttes HTTP

Gzip Vous devrez avoir compil PHP avec loption --with-zlib pour pouvoir effectivement profiter de la compression Gzip.
La fonction compression() passe en paramtre ob_start() est appele juste avant lenvoi du rsultat. Bien videmment, ici, nous aurions pu nous passer de la fonction compression() et crire directement ob_start("gzencode"). Qui plus est, depuis la version 4.0.4, PHP propose une fonction appele ob_gzhandler() permettant de compresser les donnes en fonction du navigateur, en utilisant soit Deflate soit Gzip (voire ne compressant pas). Tout le script prcdent peut donc se rduire :
<?php ob_start("ob_gzhandler"); ?>

289

Chapitre 4

Les en-ttes HTTP

Si vous souhaitez utiliser systmatiquement la fonction ob_gzhandler(), vous pouvez alors vous dispenser dajouter cette ligne au dbut de tous les scripts, simplement en modifiant le fichier de configuration php.ini pour avoir la ligne suivante :
output_handler = ob_gzhandler

Mais jusquo peut-on aller dans la simplification ? ce stade, on ne peut plus faire grand chose... Lexemple du premier script reste cependant utile dans certains cas, que vous pouvez imaginer vous-mme. Il est en effet facultatif dutiliser une fonction de compression, alors pourquoi ne pas, par exemple, appliquer une fonction qui rendra plus lisible le code HTML retourn pour dboguer vos scripts ? Il est galement envisageable de ne produire que du XML et dappliquer une feuille de styles au moment du rendu.

Optimisation des temps de rponse


4. Les en-ttes HTTP
Il est tout moment possible de faire appel au contenu du cache, ce qui peut se rvler vraiment trs intressant. Lutilisation la plus intressante apparat lorsque vous proposez un site contenant des pages dont le contenu peut prendre un certain temps tre gnr (parce quil fait appel une base de donnes, que le traitement des donnes est relativement long, etc.), mais qui varie peu dans le temps (dont le mme rsultat pourra tre propos diffrents visiteurs sur une priode donne). Dans ce cas, plutt que de renouveler les oprations de traitement (et daccs la base de donnes) chaque appel, il est prfrable de gnrer le document (pour le premier visiteur) et de le stocker sous sa forme HTML (ou image, ou autre) afin de restituer le fichier tout prt pour les visiteurs suivants. Il faudra simplement prendre soin de recrer ce document intervalles rguliers concidant avec la frquence de mise jour des donnes. Voyons maintenant comme procder. La fonction permettant de rcuprer le contenu du cache sappelle ob_get_content().

ob_get_contents()
Rcupre le contenu actuel du cache. Syntaxe retour string ob_get_contents(void) Contenu du cache, ou FALSE si la gestion du cache nest pas active.

Ainsi, afin de stocker le contenu dun document dans un fichier, il suffit dappeler le script suivant :

Listing 4.11 : cache_01.php


<?php ob_start();

290

Mise en cache avant mission des donnes

// Insrez ici, le code du script tel quil serait // sans lutilisation de cache // Exemple echo "Jai t mis en cache ".strftime("%d/%m/%y %H:%M:%S"); echo "Jai t mis en cache ".strftime("%d/%m/%y %H:%M:%S"); $contenuCache = ob_get_contents(); ob_end_flush(); $fd = fopen("cache.html", "w"); if (!$fd) die("Impossible douvrir le fichier de cache"); fwrite($fd, $contenuCache); fclose($fd); ?>

En plus dtre affich, le contenu sera alors galement stock dans un fichier cache.html. Pour que cela soit utile, reste dterminer quand le fichier doit tre recr et quand il doit tre affich tel quel. Pour connatre la date de dernire mise jour du fichier, nous pourrons faire appel la fonction filemtime(). Il suffira alors de voir sil date de plus de tant de temps (disons, titre dexemple, 2 mn).

4. Les en-ttes HTTP

Listing 4.12 : cache_01.php


<?php $fichierCache = "cache.html"; if (@filemtime($fichierCache)<time()-2*60) { // Oul... a commence dater ob_start(); // Insrez ici, le code du script tel quil serait // sans lutilisation de cache // Exemple echo "Jai t mis en cache ". // strftime("%d/%m/%y %H:%M:%S"); echo "Jai t mis en cache ".strftime("%d/%m/%y %H:%M:%S"); $contenuCache = ob_get_contents(); ob_end_flush(); $fd = fopen($fichierCache, "w"); if ($fd) { fwrite($fd, $contenuCache); fclose($fd); } } else { include($fichierCache); } ?>

291

Chapitre 4

Les en-ttes HTTP

Vous pouvez vous reporter aux sections "Dates" et "Fichiers" pour plus de dtails sur les fonctions strftime(), time(), filemtime(), fopen(), fwrite() et fclose().
Notez que, cette fois-ci, nous passons sous silence les cas o le fichier cache na pu tre cr. En effet, il vaut mieux ce moment-l ne pas polluer le document retourn (tant pis, nous ne profiterons tout simplement pas de leffet de cache). Notez galement quen labsence du fichier de cache (ou si celui-ci nest pas lisible), la fonction filemtime() retournera un message derreur que nous masquons par un @. La valeur retour de filemtime() sera alors FALSE qui, converti en entier, vaut 0 et sera donc infrieur la date limite ; le fichier cache sera donc bien recr. Il est galement envisageable dutiliser le cache juste pour rcuprer ce quune fonction met sur la sortie standard, sans que lon veuille pour autant que cela apparaisse dans le document. Pour cela, vous devrez utiliser la fonction ob_end_clean().

4. Les en-ttes HTTP

Gestion du cache interne


Par dfaut, les lments des documents mettre vers un client sont mis dans un cache interne avant dtre envoys au navigateur (ceci afin doptimiser les transferts de donnes). Ce qui fait que les donnes ne seront pas mises disposition du client ds quelles seront prtes, mais ds que le cache sera plein (ou que lexcution du script sera termine). En de rares circonstances, cela peut tre frustrant. Imaginez que vous utilisez un script PHP pour effectuer un long travail de traitement. Vous aurez certainement envie de suivre son volution en affichant rgulire "tant de % raliss". Malheureusement, il sagit l dune chane de caractres bien trop courte pour esprer voir le cache se remplir rapidement et tre inform de lavance du traitement avant la fin du script. Pour pallier cet inconvnient, il suffit de demander lenvoi du contenu de cache interne, mme si celui-ci nest pas plein. Ceci se ralise par un appel la fonction flush() que vous appellerez chaque fois que vous voulez envoyer le contenu du cache. Il est galement possible de demander que lappel flush() se fasse systmatiquement (ds quune nouvelle ligne est ajoute au document). Pour cela, vous utiliserez la fonction ob_implicit_flush().

ob_implicit_ush()
Active ou dsactive lenvoi implicite. Quand lenvoi implicite est activ, les donnes sont envoyes ds que possible. Syntaxe $active ob_implicit_flush([boolean $active]) TRUE (valeur par dfaut) pour activer, FALSE pour dsactiver.

292

Mise en cache avant mission des donnes

Syntaxe retour

boolean headers_sent(void) TRUE si len-tte a dj t mis, FALSE sinon.

Partie de cache-cache Lutilisation des fonctions flush() et ob_implicit_flush() nimplique pas la disponibilit immdiate des donnes au niveau de laffichage du navigateur. En effet, aprs PHP, le serveur et le navigateur peuvent, eux aussi, dcider de mettre les donnes dans un cache.
Quoi quil en soit, dans un environnement de travail de type "Linux + Apache + Mozilla" le script suivant,

Listing 4.13 : flush_02.php


<?php set_time_limit(0); ob_implicit_flush(); for ($i=0; $i<=100; $i++) { echo "$i%<br />"; sleep(1); } ?>

4. Les en-ttes HTTP

affiche 1 %, 2 %, etc. intervalles rguliers dune seconde, alors que la variante de ce script (flush_01.php) ne faisant pas appel ob_implicit_flush() naffiche rien pendant une longue priode (probablement 100 secondes) avant dafficher toutes les lignes dun bloc. Nous avons d, ici, faire appel set_time_limit() pour autoriser lexcution dun script de plus de 30 secondes.

Les autres fonctions


Ces fonctions sont galement disponibles, mais nont pas t vues prcdemment.

ob_get_length()
Retourne le nombre de caractres contenus dans le cache. Syntaxe return string ob_get_length(void) Longueur du contenu du cache, ou FALSE si la gestion nest pas active.

293

Chapitre 4

Les en-ttes HTTP

ob_ush()
Permet denvoyer le contenu du cache au navigateur, puis de vider le cache sans pour autant mettre fin la mise en cache. Cette fonction a t introduite dans la version 4.2.0 de PHP. Syntaxe void ob_flush(void)

ob_clean()
Vide le contenu du cache sans pour autant mettre fin la mise en cache. Cette fonction a t introduite dans la version 4.2.0 de PHP. Syntaxe void ob_clean(void)

4. Les en-ttes HTTP

ob_get_level()
Retourne le degr dimbrication des mises en cache (i.e. nombre dappels ob_start()). Cette fonction a t introduite dans la version 4.2.0 de PHP. Syntaxe retour int ob_get_level(void) Le degr dimbrication des mises en cache.

294

Chapitre 5

Les techniques de programmation


5.1 5.2 Rgles de codage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Sparation du code et de la mise en page . . . . . . . . . . . . . . . . . . . . . . . . . 307

Rgles de codage

5.1.

Rgles de codage

Contrairement ce que lon peut trouver avec le langage Java, les auteurs de PHP ne suggrent pas vritablement de rgles de codage. Cependant, en marge du dveloppement du moteur PHP, les auteurs de PHP group contribuent galement la ralisation dune bibliothque de scripts PHP baptise PEAR. Et, dans le cadre de ce projet, quelques rgles de codage ont t dictes. Ce sont principalement ces recommandations que nous allons prsenter ici, tout en les compltant et les amliorant (souvent en gardant lesprit Java). Ces rgles de codage, souvent issues du simple bon sens, sont destines faciliter la lecture du code (notamment par un dveloppeur autre que lauteur principal du script), mais aussi rduire les risques derreur de programmation.

Prsentation du code
Il est ainsi suggr :
j j j

Dcrire des lignes de code ne dpassant pas 80 caractres (et idalement ne dpassant pas 70 caractres) pour en faciliter la lecture lcran et sur papier. Dindenter le code avec quatre espaces (sans tabulations) afin de conserver la mme mise en page quelle que soit la configuration de lditeur.

5. Les techniques de programmation

De mettre une espace de part et dautre dun signe gal dune affectation de valeur une variable (voire plusieurs dans le cas dune srie daffectations pour un alignement plus lisible). Ce quil faut faire :
$var1 = fonction(); $variable2 = 21

Ce quil ne faut pas faire :


$variable2=21;

Dinsrer une espace entre les lments des structures de contrle et les parenthses ouvrantes, afin de les diffrencier dun appel de fonction. Ce quil faut faire :
if (condition) { code1; }

Ce quil ne faut pas faire :


if(condition) { code1; }

Ce quil faut faire :


if ((cond1) && (cond2) ) { code1; }

297

Chapitre 5

Les techniques de programmation

Ce quil ne faut pas faire :


if ((cond1)&&(cond2)) { code1; }

Dutiliser des accolades mme pour les structures de contrle ne contenant quune seule ligne. Ceci afin dviter tout oubli le jour o une ligne devra tre ajoute. Ce quil faut faire :
if (condition1) { code1; }

Ce quil ne faut pas faire :


if (condition1) code1;

De ne pas mettre despace entre le nom de la fonction et la parenthse ouvrante prcdant les paramtres. Ce quil faut faire :
maFonction($param1)

5. Les techniques de programmation

Ce quil ne faut pas faire :


maFonction ($param1)

De sparer chaque paramtre dune fonction par une virgule suivie dune espace (mais pas despace entre la parenthse ouvrante et le premier paramtre). Ce quil faut faire :
maFonction($param1, $param2)

Ce quil ne faut pas faire :


maFonction ($param1,$param2)

De positionner laccolade ouvrante de dclaration dune fonction juste au dessous du "f" de


function et de commencer le corps de la fonction aprs avoir indent.

Ce quil faut faire :


function maFonction() { return "blabla"; }

Ce quil ne faut pas faire :


function maFonction() { return "blabla"; }

298

Rgles de codage

Programmation
j j

Toujours utiliser les balises <?php ?> (et non <? ?> ou toute autre alternative). Les paramtres optionnels (avec des valeurs par dfaut) des fonctions doivent tre les derniers paramtres de la fonction (du moins couramment omis au plus couramment omis). Ce quil faut faire :
function maFonc($p1, $p2 = "bla") { return $p1.$p2; }

Ce quil ne faut pas faire :


function maFonc($p1 = "bla", $p2) { return $p1.$p2; }

Les fonctions doivent toujours retourner une valeur cohrente (i.e. en cas dchec retourner clairement FALSE plutt que de ne pas retourner explicitement de valeur. En cas dappel une fonction ne retournant pas spcifiquement de valeur, retourner TRUE en cas de succs, et FALSE sinon). Utiliser de prfrence include_once() (plutt que include()) pour les fichiers inclure, mais dont on peut ventuellement se passer, et require_once() (plutt que require()) pour les fichiers ncessaires au bon fonctionnement du script. Se tenir inform des problmes de scurit lis lutilisation de certaines fonctions (cf. include et upload de fichiers).

5. Les techniques de programmation

Noms de classes, fonctions, variables et constantes


Les rgles de nommage de la bibliothque PEAR ne sont pas tout fait claires (du moins en ce qui concerne les classes et les variables). Mais une bonne pratique consiste respecter peu prs les mmes rgles que pour Java (mme si cela nest pas le cas pour les fonctions natives de PHP et si, dans certains cas, on peut tre amen sen carter).

Les classes
Les noms de classes commencent par quelques lettres en majuscules indiquant le projet auquel elles appartiennent (ex. : SPP pour "Super Projet PHP") suivies dun underscore et du nom dcrivant le rle de la classe. Ce nom ne comporte pas dunderscore et est essentiellement crit en minuscules. Seules les premires lettres des mots composant le nom sont en majuscules. La lettre suivant lunderscore est, elle, une minuscule. Un nom de classe doit toujours commencer par une majuscule (ce qui est assur ici par labrviation du nom du projet). Ce qui donne, par exemple :
class SPP_maClasse() { }

299

Chapitre 5

Les techniques de programmation

Les mthodes
Les noms de mthodes ne doivent pas commencer par une majuscule. Elles sont essentiellement crites en minuscules. Seules les premires lettres des mots composant le nom sont en majuscules. Il est conseill de distinguer les mthodes internes (uniquement utilises par la classe) des mthodes externes (pouvant tre appeles par le dveloppeur) en faisant prcder les noms de mthodes internes par un underscore.
class SPP_superClasse { function _fonctionInterne() { // commence par un underscore } function superFonction() { // pas de prfixe dans ce cas } }

5. Les techniques de programmation

Les fonctions
Nous appliquerons aux fonctions (autres que les mthodes) les mmes rgles de nommage que celles appliques aux classes.
function MA_superFonction() { }

Les variables
Les noms de variables suivent les mmes rgles que celles des noms de mthodes.
$maSuperVariable $_maVariablePrivee

En revanche, pour les variables globales, les rgles de nommage PEAR suggrent de respecter les mmes rgles que pour les noms de classes, mais en les faisant prcder dun underscore. ($_PEAR_destructor_object_list est cit en exemple, alors quil serait prfrable dutiliser le nom $_PEAR_destructorObjectList.)

Les constantes
Les noms des constantes sont en majuscules, et, dans ce cas, chaque mot est spar par un underscore. L encore, les noms doivent tre prcds du nom, abrg et en majuscules, de la bibliothque.
define("SPP_SUPER_CONSTANTE", 20);

300

Rgles de codage

Commentaires
Ah ! les commentaires... Il faut distinguer deux types de commentaires. Il y a les commentaires destins aux personnes qui vont devoir utiliser les classes et fonctions. Il sagit dans ce cas de dcrire lobjectif de la classe ou fonction ainsi que son interface (description des paramtres dentre et sortie). Puis il y a les commentaires destins aux personnes qui seront charges de la maintenance du code. Dans ce cas, il sagit plutt de dcrire les algorithmes et les diverses subtilits qui ont t mis en place pour que la fonction fasse ce que lon attend delle. Dans le premier cas, les dveloppeurs de PEAR suggrent dinclure dans les scripts des commentaires respectant la convention PHPDoc (fortement inspire de JavaDoc). Dans le second cas, il est suggr dutiliser soit la convention /* */, soit // (au choix du programmeur, mais pas #).

PHPDoc(umentor)
Installation
PHPDoc est plus ou moins un standard dcriture repris du monde Java. Dans PEAR, on retrouve deux implmentations, une appele PHPDoc et lautre PHPDocumentor. PHPDocumentor est le gnrateur de documentation recommand pour diverses raisons telles que la gnration de fichier PDF, labsence dutilisation de base de donnes, possibilit de dfinir ses propres balises En outre PHPDoc nest plus en dveloppement. Pour installer PHPDocumentor une fois PEAR install il suffit de taper pear install phpdocumentor.

5. Les techniques de programmation

PHP4/5 Pour utiliser PHPDocumentor avec PHP5 il vous faudra utiliser au minimum la version 1.3.0 autrement toute version est utilisable pour PHP4.

Syntaxe des commentaires


Tout comme pour JavaDoc, les lignes de commentaire doivent prcder les dclarations de classes, fonctions, etc. selon le schma suivant :
/** * Description succincte * * Description dtaille * * @param <type du parametre> */

description

Ces commentaires doivent apparatre avant les instructions class (dclaration dune classe), function (dclaration dune fonction), var (dclaration dune variable), define (dclaration dune constante), include, include_once, require, require_once (inclusion de fichiers).

301

Chapitre 5

Les techniques de programmation

Les mots-cls valides sont :


j j
@access suivi de "private" ou "public" pour indiquer si une classe, une fonction ou une variable est prive ou publique (par dfaut, elles seront considres comme prives). @author suivi du nom de lauteur et ventuellement de le-mail mis entre < et > (ne peut pas tre utilis pour include, include_once, require et require_once). Le champ e-mail est cens tre optionnel. En pratique, sil nest pas mis, le nom de lauteur napparat pas. @const suivi du nom de la constante et ventuellement de la description (valable uniquement pour define). @deprecated suivi dun commentaire prcisant depuis quand (date ou version) llment comment est dprci (ne peut tre utilis pour include, include_once, require et require_once). @global, pour prciser le rle dune variable globale utilise dans une fonction, suivi du type de la variable (pour les objets, prcisez "object " suivi du nom de lobjet), lui-mme suivi du nom de la variable, enfin ventuellement suivi de la description (valable uniquement pour function). @package, pour prciser quelle bibliothque appartient une classe, suivi du nom de la bibliothque (valable uniquement pour class). @param, pour prciser le rle dun argument dune fonction, suivi du type de la variable (pour les objets prcisez "object " suivi du nom de lobjet), suivi du nom de la variable, ventuellement suivi de la description (valable uniquement pour function). @return, pour prciser le contenu de la valeur retourne par une fonction, suivi du type de la variable (pour les objets prcisez "object " suivi du nom de lobjet), ventuellement suivi de la description (valable uniquement pour function). @see, pour faire rfrence une autre fonction, une autre mthode de la classe ou une variable, suivi du nom de llment point. Le nom de la fonction doit inclure les parenthses ouvrante puis fermante. Cela insre alors un lien hypertexte dans la documentation (ne peut tre utilis pour include, include_once, require et require_once). @since, pour indiquer la date/version dintroduction de llment, suivi de la date ou de lidentifiant de version (ne peut tre utilis pour include, include_once, require et require_once). @static, pour indiquer quune mthode peut tre considre comme statique (appel MonObjet::maMethode() possible). Valable uniquement pour function. @throws, pour indiquer quelles erreurs peuvent tre leves. @var, pour indiquer le rle dune variable, suivi du type de la variable (pour les objets prcisez "object" suivi du nom de lobjet), suivi du nom de la variable, ventuellement suivi de la description (valable uniquement pour var). @version, pour indiquer le numro de version, suivi dune chane de caractres totalement libre indiquant le numro de version.

j j

j j

5. Les techniques de programmation

j j j

302

Rgles de codage

Un seul ou plusieurs fichiers Contrairement PHPDoc, avec PHPDocumentor il est possible de dfinir plusieurs classes dans un mme fichier mais cela reste tout de mme dconseill pour des raisons de lisibilit (sauf cas particuliers).

Listing 5.1 : sources/phpdoc_demo01.php


<?php /** * @const SPP_maConstante Une bien belle constante */ define("SPP_MA_CONSTANTE", 20); $_SPP_maVariableGlobale = "SPP"; /** * Classe super pratique * * L, je pourrais dcrire ce que fait cette * classe mais comme je nen ai aucune ide * je mabstiendrais. * * @author Damien HEUTE <damien@toutestfacile.com> * @package SuperProjetPHP * @access public * @version 2.0 * @since 2002-07-01 */ class SPP_maClasse { /** * @var string monParametre Paramtre de sauvegarde */ var $monParametre;

5. Les techniques de programmation

/** * @param monObjet object SPP_autreClasse Object a sauvegarder * @return boolean TRUE si OK, FALSE sinon * @see vieilleFonction() */ function sauve($monObjet) { /** * @global string Une variable globale. */ global $_SPP_maVariableGlobale;

303

Chapitre 5

Les techniques de programmation

return $mon0bjet->sauve($_SPP_mavariableGlobale. $this->monParametre); } /** * @static * @param texte string Texte a afficher */ function affiche($texte) { echo $texte; } /** * @deprecated 2.3 */ function vieilleFonction() { // ne plus utiliser depuis version 2.3 } }

5. Les techniques de programmation

/** * maFonction * * @param parametre1 string blabla */ function maFonction($parametre1) { } ?>

Listing 5.2 : sources/phpdoc_demo02.php


<?php /** * Une classe vraiment bidon * * @package SuperProjetPHP */ class SPP_autreClasse { } ?>

304

Rgles de codage

En-tte de fichier Dans le cadre du projet PEAR, un en-tte de fichier est suggr. Cela tant fortement dpendant du projet, nous naborderons pas ce point ici.

Gnration de la documentation
La gnration de la documentation est trs simple, elle peut se faire "en ligne" ou "hors ligne" cest--dire avec les fichiers sources sur le serveur ou dans tout autre rpertoire. Il y a deux possibilits pour gnrer la documentation, soit en ligne de commande soit par une interface web. Linconvnient de linterface web est quil faut linstaller sur le serveur et quelle ne permet de gnrer de la documentation que sur les fichiers prsents sur le serveur. Nous allons donc voir uniquement le mode en ligne de commande. Entrons tout de suite dans le vif du sujet avec un exemple ou dans le rpertoire courant il y a le rpertoire sources qui contient vos fichiers sources (dans notre exemple nous reprenons les fichiers dcrit prcdemment) et que lon veuille gnrer une documentation HTML dans un nouveau rpertoire appel documentation:
phpdoc d sources t documentation

5. Les techniques de programmation

Voila, le tour est jou, voici le contenu du rpertoire documentation:

Figure 5.1 : Contenu du rpertoire documentation

Et un aperu de la documentation gnre (voir fig. 5.2) : Comme nous lavons dj prciser, PHPDocumentor permet de gnrer des fichiers PDF, ici nous navons rien prciser et donc le rendu obtenu est par dfaut HTML avec la mise en page de PHPDocumentor.

305

Chapitre 5

Les techniques de programmation

5. Les techniques de programmation

Figure 5.2 : Aperu de la documentation

Voyons diffrentes options disponibles pour loutil phpdoc:


j j j j j j j j
-f ou --filename: nom du ou des fichiers spars par une virgule analyser. (vous pouvez utiliser * ou ?) -d ou --directory: nom du ou des rpertoires spars par une virgule analyser. -t ou --target: rpertoire o crer la documentation. (il sera cre sil nexiste pas dj) -i ou --ignore: liste de fichiers ignorer. -q ou --quiet: naffiche pas dinformations lors de lanalyse. -ti ou --title: titre de la documentation (Generated Documentation par dfaut) -h ou --help: permet dobtenir une aide sur phpdoc. -o ou --output: dfini le mode de gnration. Cest cette option qui vous permet de gnrer de lHTML, du PDF, du DocBook Pour choisir il suffit daller dans le rpertoire

306

Sparation du code et de la mise en page

Converters de PHPDocumentor et de dfinir le chemin vers le convertisseur que vous

voulez. ce jour il y a le choix entre: CHM:default, HTML:frames, HTML:Smarty, PDF:default, XML:DocBook. Il est galement possible de crer votre propre mode.

Autres options Il existe dautres options mais moins souvent utilises.

5.2.

Sparation du code et de la mise en page

Pour des raisons de maintenance, ou tout simplement parce que les bons dveloppeurs ne font pas ncessairement de bons designers (et rciproquement), il est gnralement souhaitable de sparer le code de la mise en page. Ce principe gnral doit galement sappliquer au code PHP. Toutefois, sil est vident que lon ne va pas intgrer un gros bloc de traitement au milieu dun script daffichage, la mise en pratique de cette rgle est souvent bien illusoire. En effet, comme tout langage de programmation de pages web, PHP se situe la frontire entre le code et la mise en page. Par consquent, il nest pas rare que les instructions daffichage ne se bornent pas afficher une image par-ci et le contenu dune variable par-l. Plus frquemment, les informations afficher sont une liste dinformations (peut-tre issues dune base de donnes), chaque information pouvant avoir des attributs qui vont influencer la faon dont elle doit tre affiche (par exemple, sil sagit dune liste de noms de personnes, on pourra peut-tre vouloir afficher une petite icne indiquant sil sagit dun homme ou dune femme). Dans ce cas, invitablement, le script charg de laffichage devra contenir des instructions de boucle ainsi que des tests (pour avoir un affichage conditionnel selon les attributs). moins, videmment, que ce ne soit le script charg du traitement de linformation qui retourne du code HTML (et gre donc les problmes de mise en page). mon sens, la meilleure solution pour distinguer autant que possible le code de la mise en page consiste faire judicieusement appel des objets et fonctions stocks dans des scripts "bibliothques". Nous ne pouvons toutefois pas taire les autres solutions ( base de modles ou templates) proposes notamment au travers des bibliothques PHPLib et PEAR.

5. Les techniques de programmation

Utilisation des objets et de linstruction include


Le principe est simple : il suffit davoir un ou plusieurs scripts PHP ne contenant que des objets ou fonctions proposant des interfaces simples, et qui retourneront des donnes aisment manipulables par le ou les scripts chargs de la mise en page. On pourra ainsi imaginer avoir des mthodes comme :

MaBD->rechercheVisiteurs()
Exemple de fonction qui rechercherait une liste de visiteurs dans une base de donnes partir dun critre quelconque, et retournerait $nb valeurs partir de la $debut-ime.

307

Chapitre 5

Les techniques de programmation

Syntaxe retour

array rechercheVisiteurs(string $critere, int $debut, $nb) Tableau dobjet Visiteur, ou FALSE en cas dchec.

Le script charg de laffichage pourrait alors avoir lallure suivante :


<?php // Inclusion de toutes les bibliothques ncessaires require_once("bibliotheque1_inc.php"); // Initialisation de toutes les variables ncessaires $liste = MaBD::rechercheVisiteurs($critere, $debut, 10); ?> <html> <body> <table> <?php if ($liste) for ($i=0; $i<count($liste); $i++) { ?> <tr> <td> <?php if ($liste[$i]->sexe=="M") { echo "<img src=\"homme.gif\">"; } else { echo "<img src=\"femme.gif\">"; } ?> </td> <td><?php echo $liste[$i]->prenom; ?></td> <td><?php echo $liste[$i]->nom; ?></td> </tr> <?php } ?> </table> </body> </html>

5. Les techniques de programmation

Comme vous le voyez, nous sommes loin dun script quasiment exempt de code. Mais il ny a pas de miracle esprer ! Il est galement possible de faire appel aux possibilits offertes par les instructions include() et require() pour scinder une page complexe en plusieurs lments (fichiers) ddis un sous-ensemble de la page. Ainsi, de nombreux scripts sont conus selon le modle :
<?php include("entete_inc.php"); // Corps de la page include("pieddepage_inc.php"); ?>

308

Sparation du code et de la mise en page

dans lequel le fichier entete_inc.php (plus couramment appel header.php) contient gnralement le titre du site, le logo, et, ventuellement, des barres de menu horizontale et latrale gauche (chacun de ces lments pouvant aussi tre dans des fichiers distincts). Le fichier pieddepage_inc.php (plus couramment appel footer.php) contient, quant lui, lindication de copyright et, ventuellement, une barre de menu latrale droite. Lutilisation de ces techniques offre de nombreux avantages :
j j j

Elles sont trs simples mettre en uvre. Elles facilitent la rutilisation du code. Elles sont relativement satisfaisantes en terme de sparation des rles.

Utilisation des modles (templates)


Avec la bibliothque PHPLib
Installation
Vous devrez, dans un premier temps, vous procurer la bibliothque PHPLib sur le site Internet http://sourceforge.net/projects/phplib (elle se trouve galement sur le CD-ROM fourni). Il sagit simplement dun fichier phplib-7.4-pre1.tar.gz dcompresser dans le rpertoire de votre choix. Ce fichier contient juste une srie de scripts PHP (inutile donc de recompiler PHP). Pour utiliser cette bibliothque en toute libert, il suffit dajouter le rpertoire contenant la bibliothque au chemin de recherche spcifi par le paramtre include_path du fichier php.ini. Cela peut galement se faire en utilisant la fonction set_ini() (utilise comme suit : set_ini("include_path", $nouvelleValeurIncludePath);) au dbut de chaque script faisant appel la bibliothque PHPLib. Pour utiliser les modles, il suffira alors dinclure le script template.inc disponible dans le rpertoire php. Si vous navez pas modifi le contenu dinclude_path, peu importe, vous naurez qu prciser le chemin complet vers ce fichier lors de linclude.

5. Les techniques de programmation

Introduction
La sparation code/mise en page avec PHPLib prend un tout autre aspect. Le designer pourra crer des fichiers semblables des fichiers HTML classiques, dans lesquels il aura, en plus, intgr des mots-cls (entre accolades) ou dfini des blocs (par des commentaires HTML). Ces fichiers HTML seront alors traits par un script crit par le dveloppeur faisant appel la bibliothque PHPLib, afin de remplacer les mots-cls et les blocs par leurs valeurs. Exemple de fichier modle (cr par le designer) :

Listing 5.3 : modeles/phplib_01.tpl


<html> <head> <title>{TITRE}</title> </head>

309

Chapitre 5

Les techniques de programmation

<body> <h3>{TITRE}</h3> <table border="1"> <!-- BEGIN blocLigne --> <tr> <td>{SEXE}</td> <td>{PRENOM}</td> <td>{NOM}</td> </tr> <!-- END blocLigne --> </table> <center>{COPYRIGHT}</center> </body> </html>

Exemple de fichier de substitution mot-cl/code (cr par le dveloppeur) :

Listing 5.4 : phplib_01.php


<?php require_once("../phplib-7.4-pre1/php/template.inc");

5. Les techniques de programmation

// Instanciation dun objet Template // en prcisant que : // * les fichiers de modele // sont stocks dans le rpertoire modeles // * les mots cls non reconnus // seront conservs $modele = new Template("modeles", "keep"); // Associe un identifiant au fichier modle $modele->set_file("idModele", "phplib_01.tpl"); // Dfinit les valeurs associes aux mots cls $modele->set_var(array("TITRE" => "Modles avec PHPLib", "COPYRIGHT" => "Copyright 2002")); // Extrait du fichier identifi par "idModele" // le block nomm "blocLigne" et le remplace par // le mot cl "lignes" $modele->set_block("idModele", "blocLigne", "lignes"); // A titre dexemple // remplace les mots cls du bloc ligne // par diffrentes valeurs $modele->set_var(array("SEXE" => "<img src=\"homme.gif\">", "PRENOM" => "Pierre", "NOM" => "Dupond")); $modele->parse("lignes", "blocLigne", true); $modele->set_var(array("SEXE" => "<img src=\"femme.gif\">",

310

Sparation du code et de la mise en page

"PRENOM" => "Anne", "NOM" => "Durand")); $modele->parse("lignes", "blocLigne", true); $modele->set_var(array("SEXE" => "<img src=\"homme.gif\">", "PRENOM" => "Jean", "NOM" => "Bon")); $modele->parse("lignes", "blocLigne", true); // procde aux substitutions // et stocke le rsultat dans une variable // "resultat" $modele->parse("resultat", "idModele"); // affiche le rsultat $modele->p("resultat");

?>

Ceci affichera alors :


Figure 5.3 : Exemple dutilisation de modles avec PHPLib

5. Les techniques de programmation

Comme vous pouvez le constater, le designer na absolument pas besoin de connatre le langage PHP. En revanche, la tche du dveloppeur est sensiblement plus complexe (comme celle du serveur). Ce dernier doit apprendre un "nouveau langage", celui de la manipulation des modles.

La base
Lutilisation des modles PHPLib commence par linstanciation dun objet Template selon la syntaxe suivante :

Template
Objet modle de PHPLib. Syntaxe Template Template(string $repertoireModeles, string $modeErreur) Chane de caractres indiquant quel doit tre le comportement lorsque des mots-cls inconnus sont rencontrs. Cet argument doit prendre une des valeurs suivantes :

$repertoireModeles Rpertoire o sont situs les fichiers de modles. $modeErreur

311

Chapitre 5

Les techniques de programmation

"keep" si le mot-cl doit tre restitu dans le flux de sortie. "comment" si le mot-cl doit tre mis en commentaire dans le flux de sortie. "remove" (valeur par dfaut) si le mot-cl doit tre ignor (et ne pas paratre dans le flux de sortie). Toutes les manipulations venir sappuient sur des mots-cls (les chanes de caractres intgres au code HTML du modle, y compris les noms de blocs) et des noms de variables (ni plus ni moins des chanes de caractres reprsentant des portions du modle). Il nest pas rare que ces deux notions se confondent. Mme si, dans une utilisation "normale", cette mthode nest appele qu la fin du traitement, voici la mthode permettant dafficher le contenu dune variable. Dans notre cas, elle sera galement utilise pour dmontrer les proprits des diffrentes mthodes de lobjet Template.

Template->p()
Affiche le contenu de la variable indique. Cette fonction est gnralement utilise pour afficher le rsultat final.

5. Les techniques de programmation

Syntaxe $variable

void p(string $variable) Nom de la variable dont on veut afficher le contenu.

Lutilisation la plus "primitive" des modles consiste remplacer des mots-cls (en absence de blocs) par des valeurs. Cette opration seffectue en deux tapes : 1. 2. Dfinition des valeurs par lesquelles les mots-cls doivent tre remplacs. Remplacement proprement dit.

Template->set_var()
Donne une valeur un ou plusieurs mots-cls. Syntaxe Syntaxe $motCle $valeur void set_var(string $motCle, string valeur) void set_var(array $tableauAssociatif) Mot-cl auquel vous souhaitez donner une valeur. Valeur associe au mot-cl.

$tableauAssociatif Tableau associatif contenant autant de couples ($motCle => $valeur) que de valeurs dfinir.

312

Sparation du code et de la mise en page

Ainsi, la succession dappels :


$modele->set_var("TITRE", "Mon TITRE"); $modele->set_var("COPYRIGHT", "Copyright 2002");

sera avantageusement remplace par :


$modele->set_var(array("TITRE" => "Mon Titre", "COPYRIGHT" => "Copyright 2002"));

La substitution proprement dite des mots-cls par les valeurs seffectue via un appel la mthode parse().

Template->parse()
Remplace les mots-cls contenus dans une variable par leurs valeurs, et associe ou ajoute le rsultat un mot-cl. Syntaxe $motCle $variable $modeAjout void parse(string $motCle, $string $variable, boolean $modeAjout)

5. Les techniques de programmation

Mot-cl remplacer ou complter. Variable pour laquelle les mots-cls doivent tre remplacs par leurs valeurs. Mettre TRUE si le mot-cl doit tre complt, FALSE sil doit tre remplac.

Dans le premier cas que nous tudions, la variable devra reprsenter le fichier modle lui-mme (cest bien dans cet ensemble que les mots-cls doivent tre remplacs par des valeurs). Il faut donc associer, au pralable, un nom de variable au fichier modle. Pour cela, vous devez faire appel la mthode set_file().

Template->set_le()
Associe des noms de variables (raccourcis) des noms de fichiers. Syntaxe $variable $nomFichier void set_file(string $variable, string $nomFichier) Variable associe au nom de fichier. Nom du fichier.

La mthode set_file() propose galement linterface suivante :

313

Chapitre 5

Les techniques de programmation

Template->set_le()
Associe des noms de variables (raccourcis) des noms de fichiers. Syntaxe void set_file(array $tableauAssociatif) $tableauAssociatif Tableau associatif contenant autant de couples ($variable => $nomFichier) que didentifiants crer. Ce qui nous permet de raliser notre premier script de transformation de modles ; script que nous appliquerons au modle que nous avons vu prcdemment.

Listing 5.5 : phplib_02.php


<?php require_once("../phplib-7.4-pre1/php/template.inc"); // Instanciation dun objet Template // en prcisant que : // * les fichiers de modele // sont stocks dans le rpertoire modeles // * les mots cls non reconnus // seront conservs $modele = new Template("modeles", "keep");

5. Les techniques de programmation

// Dfinit les valeurs associes aux mots cls $modele->set_var(array("TITRE" => "Modles avec PHPLib", "COPYRIGHT" => "Copyright 2002")); // Associe un identifiant au fichier modle $modele->set_file("idModele", "phplib_01.tpl"); // Remplace les mots cls par leurs valeurs // et stocke le rsultat dans une variable // "resultat" $modele->parse("resultat", "idModele"); // affiche le rsultat ?> $modele->p("resultat");

Dans ce cas, nous aurons alors comme rsultat (au niveau du code HTML gnr) :

314

Sparation du code et de la mise en page

Figure 5.4 : Code HTML issu de lutilisation de modles avec PHPLib

Vous pouvez constater que les mots-cls ont bien t remplacs par leurs valeurs, sauf videmment ceux qui nont pas t traits par ce premier script, et qui appartiennent des blocs dont nous allons, ds maintenant, dtailler le fonctionnement.

Utilisation des blocs


Comme cela a t suggr en introduction de ce chapitre (dans lexemple), il est possible de dfinir des blocs de donnes. Les blocs sont dclars par des commentaires HTML contenant les instructions BEGIN et END.
<!-- BEGIN nomBloc --> <!-- END nomBloc -->

5. Les techniques de programmation

La premire opration lie la manipulation de ces blocs consiste, gnralement, appeler linstruction set_block().

Template->set_block()
Remplace, dans une variable (reprsentant gnralement un bloc), un bloc par un mot-cl et associe ce bloc la variable de mme nom. Syntaxe $variable $nomBloc $motCl void set_block(string $variable, string $nomBloc [, string $motCle]) Nom de la variable dans laquelle est recherch le bloc. Nom du bloc (i.e. mot-cl prcis dans le commentaire dfinissant le bloc). Mot-cl venant en remplacement du bloc. Si ce paramtre est omis, il prendra la mme valeur que $nomBloc.

Cest gnralement dans le cadre de lutilisation de blocs que le mode "ajout" de la mthode parse() prend tout son sens. Il est en effet alors possible de remplacer un (unique) mot-cl par une liste de valeurs. Voir le script phplib_01.php prsent en introduction de ce chapitre.

315

Chapitre 5

Les techniques de programmation

Diverses mthodes

Template->set_root()
Permet de modifier le chemin de recherche des modles. Syntaxe void set_root(string $repertoireModele) $repertoireModele Nouveau chemin de recherche des modles.

Template->set_unknowns()
Permet de modifier le comportement lorsque des variables inconnues sont rencontres. Syntaxe $modeErreur void set_unknowns(string $modeErreur) Chane de caractres indiquant le comportement tenir lorsque des mots-cls inconnus sont rencontrs. Cet argument doit prendre une des valeurs suivantes : "keep" si le mot-cl doit tre restitu dans le flux de sortie. "comment" si le mot-cl doit tre mis en commentaire dans le flux de sortie. "remove" (valeur par dfaut) si le mot-cl doit tre ignor (et ne pas paratre dans le flux de sortie).

5. Les techniques de programmation

Template->subst()
Retourne la variable indique pour laquelle les mots-cls connus ont t remplacs par leurs valeurs. Les mots-cls inconnus seront laisss inchangs (quel que soit le mode derreur slectionn). Syntaxe $variable string subst(string $variable) Nom de la variable retourner.

Template->psubst()
Affiche le rsultat que retourne subst().

316

Sparation du code et de la mise en page

Syntaxe $variable

string psubst(string $variable) Nom de la variable afficher.

Template->nish()
Retourne la variable indique pour laquelle les mots-cls connus ont t remplacs par leurs valeurs. Les mots-cls inconnus sont traits selon le mode derreur slectionn. Syntaxe $variable string finish(string $variable) Nom de la variable retourner.

Template->get_vars()
Retourne un tableau associatif des variables dfinies, les cls tant les noms des variables. Syntaxe retour array get_vars()

5. Les techniques de programmation

Le tableau association "nom de variable" => "valeur".

Template->get_undened()
Retourne un tableau (associatif) des mots-cls rencontrs nayant pas de valeurs associes. Syntaxe retour array get_undefined() Le tableau associatif "nom de variable" => "nom de variable".

haltMsg()
Il sagit cette fois dune fonction et non dune mthode appele accompagne dun message en cas derreur. Cette fonction peut tre rcrite par vos soins. Syntaxe $messageErreur void haltMsg(string $messageErreur) Message derreur.

317

Chapitre 5

Les techniques de programmation

Avec la bibliothque PEAR


Installation
Linstallation de la bibliothque PEAR ne ncessite quasiment aucun effort. En effet, celle-ci tant livre avec PHP, il suffit dajouter le rpertoire contenant la bibliothque (ex. : /usr/local/ lib/php par dfaut sous Linux) au chemin de recherche spcifi par le paramtre include_path du fichier php.ini. Cela peut galement se faire en utilisant la fonction set_ini() (utilise comme suit : set_ini("include_path", $nouvelleValeurIncludePath);) au dbut de chaque script faisant appel la bibliothque PEAR. Nous supposerons par la suite que vous avez intgr PEAR au chemin de recherche spcifi dans php.ini. Pour utiliser les modles, il suffira alors dinclure le script IT.php disponible dans le rpertoire HTML.

Utilisation
La bibliothque PEAR (livre avec PHP) propose quant elle une solution fort similaire celle propose par PHPLib. Lune delle, base sur la classe IntegratedTemplate ncessite toutefois moins de manipulations de variables, ce qui simplifie, entre autres, lutilisation des blocs.

5. Les techniques de programmation

Lexemple prsent en introduction de la bibliothque PHPLib devient alors : exemple de fichier modle (cr par le designer) :

Listing 5.6 : modeles/pear_01.tpl


<html> <head> <title>{TITRE}</title> </head> <body> <h3>{TITRE}</h3> <table border="1"> <!-- BEGIN blocLigne --> <tr> <td>{SEXE}</td> <td>{PRENOM}</td> <td>{NOM}</td> </tr> <!-- END blocLigne --> </table> </body> </html>

Exemple de fichier de substitution mot-cl/code (cr par le dveloppeur) :

318

Sparation du code et de la mise en page

Listing 5.7 : pear_01.php


<?php require_once("HTML/IT.php"); // Instanciation dun objet IntegratedTemplate // en prcisant que : // * les fichiers de modele // sont stocks dans le rpertoire "modeles" $modele = new IntegratedTemplate("modeles"); // Charge le fichier modele $modele->loadTemplateFile("pear_01.tpl"); // Defini les valeurs associes au mot cl $modele->setVariable("TITRE","Modles avec PEAR"); // Selectionne le bloc "blocLigne" // pour les prochaines manipulations $modele->setCurrentBlock("blocLigne"); // A titre dexemple // remplace les mots cls du bloc ligne // par diffrentes valeurs $modele->setVariable(array("SEXE" => "<img src=\"homme.gif\">", "PRENOM" => "Pierre", "NOM" => "Dupond")); $modele->parseCurrentBlock("blocLigne"); $modele->setVariable(array("SEXE" => "<img src=\"femme.gif\">", "PRENOM" => "Anne", "NOM" => "Durand")); $modele->parseCurrentBlock("blocLigne"); $modele->setVariable(array("SEXE" => "<img src=\"homme.gif\">", "PRENOM" => "Jean", "NOM" => "Bon")); $modele->parseCurrentBlock("blocLigne"); // affiche le rsultat $modele->show();

5. Les techniques de programmation

?>

La base
Lutilisation des modles PEAR/IntegratedTemplate commence par linstanciation dun objet IntegratedTemplate selon la syntaxe suivante :

319

Chapitre 5

Les techniques de programmation

IntegratedTemplate
Objet modle de PEAR/IntegratedTemplate. Syntaxe IntegratedTemplate IntegratedTemplate([string $repertoireModeles])

$repertoireModeles Rpertoire o sont situs les fichiers de modles. Toutes les manipulations venir sappuient sur des mots-cls ou noms de blocs intgrs au code HTML du modle, que lon pourra appeler "variable". Mme si, dans une utilisation normale, cette mthode nest appele qu la fin du traitement, voici la mthode permettant dafficher le contenu dune variable. Dans notre cas, elle sera galement utilise pour dmontrer les proprits des diffrentes mthodes de lobjet IntegratedTemplate.

IntegratedTemplate->show()
5. Les techniques de programmation
Affiche le contenu dune variable (bloc ou mot-cl) indique. Cette fonction est gnralement utilise sans paramtre pour afficher le rsultat final. Syntaxe $variable void show([string $variable]) Nom de la variable (bloc ou mot-cl) dont on veut afficher le contenu.

Le chargement dun modle se fait via la mthode setTemplate() ou plus probablement loadTemplateFile().

IntegratedTemplate->setTemplate
Charge un modle bas sur une simple chane de caractres. Syntaxe $modele boolean setTemplate(string $modele [, boolean $supprimeVariablesInconnues [, boolean $supprimeBlocsVides]])) Le modle.

$supprimeVariables Inconnues TRUE (par dfaut) si vous souhaitez que les variables (mot-cls) non dfinis soient supprims (en sortie), FALSE sinon. $supprimeBlocsVides TRUE (par dfaut) si vous souhaitez que les blocs vides soient supprims (en sortie), FALSE sinon. retour TRUE en cas de succs, FALSE sinon.

320

Sparation du code et de la mise en page

IntegratedTemplate->loadTemplateFile()
Charge un modle stock dans un fichier. Syntaxe $nomFichier boolean loadTemplateFile(string $nomFichier [, boolean $supprimeVariablesInconnues [, boolean $supprimeBlocsVides]]) Nom du fichier modle.

$supprime VariablesInconnues TRUE (par dfaut) si vous souhaitez que les variables (mots-cls) non dfinies soient supprimes (en sortie), FALSE sinon. $supprimeBlocsVides TRUE (par dfaut) si vous souhaitez que les blocs vides soient supprims (en sortie), FALSE sinon. retour TRUE en cas de succs, FALSE sinon.

Lutilisation la plus "primitive" des modles consiste remplacer des mots-cls (ventuellement contenus dans un bloc) par des valeurs. Cette opration seffectue en trois tapes : 1. 2. 3. Slection du bloc ;

5. Les techniques de programmation

Dfinition des valeurs par lesquelles les mots-cls doivent tre remplacs ; Remplacement proprement dit.

La slection du bloc se fait naturellement par un appel la mthode setCurrentBloc().

IntegratedTemplate->setCurrentBloc()
Slectionne un bloc pour les manipulations venir. Syntaxe $bloc void setCurrentBloc([string $bloc]) Nom du bloc. Si ce paramtre est omis, cest alors le modle complet qui devient le bloc courant.

IntegratedTemplate->setVariable()
Donne une valeur un ou plusieurs mots-cls. Syntaxe Syntaxe $motCle $valeur void setVariable(string $motCle, string valeur) void setVariable(array $tableauAssociatif) Mot-cl auquel vous souhaitez donner une valeur. Valeur associe au mot-cl.

321

Chapitre 5

Les techniques de programmation

$tableauAssociatif Tableau associatif contenant autant de couples ($motCle => $valeur) que de valeurs dfinir. Ainsi, la succession dappels :
$modele->setVariable("TITRE", "Mon TITRE"); $modele->setVariable("COPYRIGHT", "Copyright 2002");

sera avantageusement remplace par :


$modele->setVariable(array("TITRE" => "Mon Titre", "COPYRIGHT" => "Copyright 2002"));

La substitution proprement dite des mots-cls par leurs valeurs seffectue via un appel la mthode parseCurrentBlock().

IntegratedTemplate->parseCurrentBlock()
Remplace les mots-cls contenus dans le bloc courant par leurs valeurs.

5. Les techniques de programmation

Syntaxe retour

boolean parseCurrentBlock(void) TRUE en cas de succs, FALSE sinon.

Diverses mthodes

IntegratedTemplate->setRoot()
Permet de modifier le chemin de recherche des modles. Syntaxe void setRoot(string $repertoireModele) $repertoireModele Nouveau chemin de recherche des modles.

IntegratedTemplate->parse()
Remplace les mots-cls contenus dans une variable par leurs valeurs. Syntaxe $variable $modeRecursif retour boolean parse([string $variable] [, boolean $modeRecursif]) Variable contenant les mots-cls remplacer. Par dfaut, le modle complet. ignorer, au moins pour linstant. TRUE en cas de succs, FALSE sinon.

322

Sparation du code et de la mise en page

IntegratedTemplate->get()
Retourne le contenu dune variable pour laquelle les mots-cls ont t remplacs par leurs valeurs. Syntaxe $variable retour string get([string $variable]) Variable dont on veut retourner le contenu. Si ce paramtre est omis, cest tout le modle qui est retourn. Contenu de la variable (ou bloc).

IntegratedTemplate->touchBlock()
Empche la suppression dun bloc vide, mme si loption a t positionne. Syntaxe $bloc boolean touchBlock(string $bloc) Bloc conserver.

5. Les techniques de programmation 323

Chapitre 6

Les fonctions mathmatiques


6.1 6.2 Les fonctions mathmatiques et les constantes . . . . . . . . . . . . . . . . . . . . . . 327 Calculs de prcision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348

Les fonctions mathmatiques et les constantes

C
6.1.

ette partie traite du calcul mathmatique. Mme si vous serez souvent amen utiliser ces fonctions pour des oprations lmentaires, sachez quil est galement possible deffectuer des calculs de prcision.

Les fonctions mathmatiques et les constantes

La bibliothque mathmatique fournit des constantes et des fonctions qui vous serviront si vous souhaitez faire du calcul. Attention cependant : pour la gestion des grands nombres ou des nombres devant comporter de nombreuses dcimales, vrifiez que les valeurs que vous manipulez peuvent tre gres soit par les entiers (integer entre -2147483648 et 2147483647) soit par les rels (double ; et respectivement long et double en C). Dans le cas contraire, vous devrez faire appel aux calculs de prcision qui feront lobjet du chapitre suivant.

Constantes
La bibliothque mathmatique met disposition dix-sept constantes utiles pour les calculs mathmatiques.

Tableau 6.1 : Les constantes


Constante M_SQRT2 M_SQRT3 M_SQRT1_2 Trigonomtrie M_PI M_PI_2 M_PI_4 M_1_PI M_2_PI M_SQRTPI M_2_SQRTPI Logarithme M_E M_LOG2E M_LOG10E M_LN2 M_LN10 M_LNPI 2.7182818284590452354 1.4426950408889634074 0.43429448190325182765 0.69314718055994530942 2.30258509299404568402 1.14472988584940017414 E Logarithme binaire de e Logarithme dcimal de e Logarithme nprien de 2 Logarithme nprien de 10 Logarithme nprien de Pi (PHP4.0.2 et +) 3.14159265358979323846 1.57079632679489661923 0.78539816339744830962 0.31830988618379067154 0.63661977236758134308 1.77245385090551602729 1.12837916709551257390 Pi Pi/2 Pi/4 1/Pi 2/Pi Racine carre de Pi (PHP4.0.2 et +) 2 sur racine carre de Pi (PHP4.0.2 et +) Valeur 1.41421356237309504880 1.73205080756887729352 0.70710678118654752440 Description Racine carre de 2 (PHP4.0.2 et +) Racine carre de 3 (PHP4.0.2 et +) 1 sur racine carre de 2 ou encore racine carre de 2 sur 2 (PHP4.0.2 et +)

6. Les fonctions mathmatiques 327

Chapitre 6

Les fonctions mathmatiques

Constante Autre M_EULER

Valeur 0.57721566490153286061

Description Constante dEuler (PHP4.0.2 et +)

Fonctions
Test de validit
PHP propose quelques fonctions permettant de dterminer si une valeur (retourne par une fonction) est finie, infinie (cas dune division par 0) ou indfinie (cas dune racine carr de -1). Vous disposez ainsi de :

is_nite()
Indique si une valeur est finie ou non. Syntaxe $valeur retour boolean is_finite(double $valeur) Valeur tester. TRUE si la valeur est finie, FALSE sinon.

6. Les fonctions mathmatiques

is_innite()
Teste si une valeur est infinie. Syntaxe $valeur retour boolean is_infinite($valeur) Valeur tester. TRUE si la valeur est infinie, FALSE sinon.

is_nan()
Teste si une valeur est indfinie. Syntaxe $valeur retour boolean is_nan($valeur) Valeur tester. TRUE si la valeur est indfinie, FALSE sinon.

328

Les fonctions mathmatiques et les constantes

Listing 6.1 : is_xxx.php


<?php if (is_finite(3)) echo "3 est fini<br />"; else echo "3 nest pas fini<br />"; if (is_finite(pow(0,-1))) echo "1/0 est fini<br />"; else echo "1/0 nest pas fini<br />"; if (is_finite(sqrt(-1))) echo "racine carre de -1 est fini<br />"; else echo "racine carre de -1 nest pas fini<br />"; if (is_infinite(3)) echo "3 est infini<br />"; else echo "3 nest pas infini<br />"; if (is_infinite(pow(0,-1))) echo "1/0 est infini<br />"; else echo "1/0 nest pas infini<br />"; if (is_infinite(sqrt(-1))) echo "racine carre de -1 est infini<br />"; else echo "racine carre de -1 nest pas infini<br />"; if (is_nan(3)) echo "3 est indfini<br />"; else echo "3 nest pas indfini<br />"; if (is_nan(pow(0,-1))) echo "1/0 est indfini<br />"; else echo "1/0 nest pas indfini<br />"; if (is_nan(sqrt(-1))) echo "racine carre de -1 est indfini<br />"; else echo "racine carre de -1 nest pas indfini<br />"; ?>

Cela retournera :
3 est fini 1/0 nest pas fini racine carre de -1 nest pas fini 3 nest pas infini 1/0 est infini racine carre de -1 nest pas infini 3 nest pas indfini 1/0 nest pas indfini racine carre de -1 est indfini

6. Les fonctions mathmatiques

Avec les oprateurs Dans les versions actuelles de PHP, cela ne sapplique quaux valeurs retournes par les fonctions et non par les oprateurs. Ainsi 1/0 retournera FALSE accompagn dun message derreur, or FALSE converti en entier donne 0, qui est fini. Vous aurez donc la surprise de constater que is_finite(1/0) retourne TRUE et non FALSE comme attendu.

329

Chapitre 6

Les fonctions mathmatiques

Trigonomtriques

pi()
Cette fonction retourne une valeur approximative de Pi. 3.1415926535898 (revient utiliser M_PI). Syntaxe retour double pi(void) Valeur approximative de Pi.

cos()
Retourne la valeur du cosinus de langle exprim en radians. Syntaxe $angle retour double cos(double $angle) Angle exprim en radians. Cosinus de langle.

acos()
6. Les fonctions mathmatiques
Retourne larc cosinus de la valeur donne (larc cosinus tant langle pour lequel le cosinus vaut $cos). Syntaxe $cos retour double acos(double $cos) Valeur sans unit. Angle en radians.

Voici un exemple de script utilisant les fonctions cos(), acos() et pi(), ainsi que les constantes M_PI et M_SQRT1_2 :
<?php echo echo echo echo echo echo echo echo echo echo ?> "cos(M_PI):".cos(M_PI)."<br />"; "cos(pi()):".cos(pi())."<br />"; "cos(M_PI/2):".cos(M_PI/2)."<br />"; "cos(3*M_PI/2):".cos(3*M_PI/2)."<br />"; "cos(M_PI/4):".cos(M_PI/4)."<br />"; "cos(3*M_PI/4):".cos(3*M_PI/4)."<br />"; "cos(-M_PI/4):".cos(-M_PI/4)."<br />"; "cos(-3*M_PI/4):".cos(-3*M_PI/4)."<br />"; "acos(M_SQRT1_2):".acos(M_SQRT1_2)."<br />"; "acos(-M_SQRT1_2):".(-M_SQRT1_2)."<br />";

330

Les fonctions mathmatiques et les constantes

Voici le rsultat obtenu :


cos(M_PI):-1 cos(pi()):-1 cos(M_PI/2):6.1230317691119E-017 cos(3*M_PI/2):-1.8369095307336E-016 cos(M_PI/4):0.70710678118655 cos(3*M_PI/4):-0.70710678118655 cos(-M_PI/4):0.70710678118655 cos(-3*M_PI/4):-0.70710678118655 acos(M_SQRT1_2):0.78539816339745 acos(-M_SQRT1_2):-0.78539816339745
M_PI et pi() retournent tous les deux la mme valeur. Les valeurs de cos(Pi/2) et cos(3*Pi/ 2) retournent un rsultat proche de 0, mais pas 0. En effet, la valeur de Pi tant approximative,

celle du cosinus est affecte.


Cos(Pi/4) et cos(Pi/4) retournent la moiti de la racine carre de 2. Cos(3*Pi/4) et cos(-3*Pi/4) sont opposs comme prvu. acos(racine carre de 2 sur 2) retourne Pi/4 et acos(-racine carre de 2 sur 2) retourne Pi/4.

sin()
Retourne la valeur du sinus de langle exprim en radians. Syntaxe $angle retour double sin(double $angle) Angle en radians. Sinus de langle.

6. Les fonctions mathmatiques

asin()
Retourne larc sinus de la valeur donne (larc cosinus tant langle pour lequel le sinus vaut $sin). Syntaxe $sin retour double asin(double $sin) Valeur sans unit. Angle en radians.

tan()
Retourne la valeur de la tangente de langle exprime en radians. Syntaxe $angle retour double tan(double $angle) Angle en radians. Tangente de langle.

331

Chapitre 6

Les fonctions mathmatiques

atan()
Retourne larc tangente de la valeur donne (larc tangente tant langle pour lequel la tangente vaut $tan). Syntaxe $tan retour double atan(double $tan) Valeur sans unit. Angle en radians compris entre PI/2 et PI/2.

atan2()
Retourne larc tangente de $sin/$cos en tenant compte de leurs signes afin de dterminer de faon plus prcise langle. Syntaxe $sin $cos retour double atan2(double $sin, double $cos) Valeur sans unit. Valeur sans unit. Angle en radians compris entre PI et PI inclus. [PI;PI].

6. Les fonctions mathmatiques

deg2rad()
Retourne en radians un angle exprim en degrs. Syntaxe $angle retour double deg2rad(double $angle) Angle en degrs. Angle en radians.

rad2deg()
Retourne en degrs un angle exprim en radians. Syntaxe $angle retour double rad2deg(double $angle) Angle en radians. Angle en degrs.

332

Les fonctions mathmatiques et les constantes

Logarithmiques

exp()
Retourne lexponentiel de la valeur donne. Syntaxe $reel retour double exp(double $reel) Valeur relle. Exponentiel $reel.

log()
Retourne le logarithme nprien de la valeur donne. Syntaxe $reel retour double log(double $reel) Valeur relle dont on veut connatre le logarithme nprien. Valeur relle du logarithme nprien de $reel.

log10()
Retourne le logarithme dcimal. Syntaxe $reel retour double log10(double $reel) Valeur relle dont on veut connatre le logarithme dcimal. Logarithme dcimal de $reel.

6. Les fonctions mathmatiques

cosh()
Retourne la valeur du cosinus hyperbolique de langle, autrement dit (exp($angle) + exp($angle))/2. Syntaxe $angle retour double cosh(double $angle) Angle hyperbolique. Cosinus hyperbolique de langle.

333

Chapitre 6

Les fonctions mathmatiques

acosh()
Retourne larc cosinus hyperbolique de la valeur donne (larc cosinus hyperbolique tant langle pour lequel le cosinus hyperbolique vaut $cosh). Syntaxe $cosh retour double acosh(double $cosh) Valeur sans unit. Angle hyperbolique.

sinh()
Retourne la valeur du sinus hyperbolique de langle, autrement dit (exp($angle) exp($angle))/2. Syntaxe $angle retour double sinh(double $angle) Angle hyperbolique. Sinus hyperbolique de langle.

asinh()
6. Les fonctions mathmatiques
Retourne larc sinus hyperbolique de la valeur donne (larc sinus hyperbolique tant langle hyperbolique pour lequel le sinus hyperbolique vaut $sinh). Syntaxe $sinh retour double asinh(double $sinh) Valeur sans unit. Angle hyperbolique.

tanh()
Retourne la valeur de la tangente hyperbolique de langle. Syntaxe $angle retour double tanh(double $angle) Angle hyperbolique. Tangente hyperbolique de langle.

334

Les fonctions mathmatiques et les constantes

atanh() (non disponible sous Windows)


Retourne larc tangente hyperbolique de langle donn (larc tangente hyperbolique tant langle hyperbolique pour lequel la tangente hyperbolique vaut $tanh). Syntaxe $tanh retour double atanh(double $tanh) Valeur sans unit. Angle hyperbolique.

Puissance

pow()
Cette fonction retourne $base la puissance $exposant. Syntaxe $base $exposant retour numeric pow(numeric $base, numeric $exposant) Nombre lever. Puissance. Entier si possible, sinon rel pouvant valoir NAN si la puissance ne peut tre calcule (ex. : racine carre dun nombre ngatif).

Voici un exemple dutilisation de la fonction pow() :

6. Les fonctions mathmatiques

Listing 6.2 : pow.php


<?php // exemple simple: 2^3 echo pow(2, 3); echo "<br />"; // exemple simple: (-1)^10 echo pow(-1, 10); echo "<br />"; // exemple derreur: racine de -4 echo pow(-4, 0.5); ?>

(-4)^0.5

En sortie, on obtiendra :
8 1 NAN

335

Chapitre 6

Les fonctions mathmatiques

sqrt()
Cette fonction retourne la racine carre de la valeur entre en paramtre. Syntaxe $reel retour double sqrt(double $reel) Valeur dont on veut connatre la racine carre. Racine carre de $reel.

Voici un exemple dutilisation de la fonction sqrt() :

Listing 6.3 : sqrt.php


<?php echo echo echo echo ?> sqrt(4)."<br />"; sqrt(9)."<br />"; sqrt(5)."<br />"; sqrt(-3)."<br />";

En sortie, on obtiendra :
2 3 2.2360679774998 NAN

6. Les fonctions mathmatiques

Distance entre deux points Pour calculer la distance entre le point A de coordonnes (x1,y1) et B de coordonnes (x2,y2), il suffit de faire sqrt(pow(x2x1,2)+pow(y2y1,2)).

Arrondi

ceil()
Arrondit lentier suprieur. Cette fonction retourne lentier directement suprieur. Lentier retourn est malgr tout considr de type double, car ce type permet de traiter des nombres plus grands que les int. Syntaxe $reel retour double ceil(double $reel) Valeur arrondir. Valeur arrondie mais de type rel.

336

Les fonctions mathmatiques et les constantes

Voici un exemple dutilisation de la fonction ceil() :

Listing 6.4 : ceil.php


<?php echo echo echo echo echo echo echo echo echo echo ?> ceil(3.0)."<br ceil(3.1)."<br ceil(3.2)."<br ceil(3.3)."<br ceil(3.4)."<br ceil(3.5)."<br ceil(3.6)."<br ceil(3.7)."<br ceil(3.8)."<br ceil(3.9)."<br />"; />"; />"; />"; />"; />"; />"; />"; />"; />";

En sortie, on obtiendra :
3 4 4 4 4 4 4 4 4 4

6. Les fonctions mathmatiques

oor()
Arrondit lentier infrieur. Cette fonction retourne lentier directement infrieur. Lentier retourn est malgr tout considr de type double, car ce type permet de traiter des nombres plus grands que les int. Syntaxe $reel retour double floor(double $reel) Valeur arrondir. Valeur arrondie mais de type rel.

Voici un exemple dutilisation de la fonction floor() :

Listing 6.5 : floor.php


<?php echo floor (3.0)."<br />"; echo floor (3.1)."<br />"; echo floor (3.2)."<br />";

337

Chapitre 6

Les fonctions mathmatiques

echo echo echo echo echo echo echo ?>

floor floor floor floor floor floor floor

(3.3)."<br (3.4)."<br (3.5)."<br (3.6)."<br (3.7)."<br (3.8)."<br (3.9)."<br

/>"; />"; />"; />"; />"; />"; />";

En sortie, on obtiendra :
3 3 3 3 3 3 3 3 3 3

round()
Arrondit selon les rgles dusage en mathmatiques.

6. Les fonctions mathmatiques

Sil ny a quun argument, cette fonction retourne lentier le plus proche. Sil y a deux arguments elle retourne la valeur arrondie selon la prcision donne en second argument. Syntaxe $reel $precision retour double round(double $reel [, int $precision]) Valeur arrondir. Prcision souhaite (nombre de chiffres aprs la virgule). Nombre arrondi selon la prcision dsire.

Voici un exemple dutilisation de la fonction round() :

Listing 6.6 : round.php


<?php echo echo echo echo echo echo echo echo echo echo round round round round round round round round round round (3.0)."<br (3.1)."<br (3.2)."<br (3.3)."<br (3.4)."<br (3.5)."<br (3.6)."<br (3.7)."<br (3.8)."<br (3.9)."<br />"; />"; />"; />"; />"; />"; />"; />"; />"; />";

338

Les fonctions mathmatiques et les constantes

echo echo echo echo echo echo echo echo echo ?>

round round round round round round round round round

(3.123456789,1)."<br (3.123456789,2)."<br (3.123456789,3)."<br (3.123456789,4)."<br (3.123456789,5)."<br (3.123456789,6)."<br (3.123456789,7)."<br (3.123456789,8)."<br (3.123456789,9)."<br

/>"; />"; />"; />"; />"; />"; />"; />"; />";

En sortie, on obtiendra :
3 3 3 3 3 4 4 4 4 4 3.1 3.12 3.123 3.1235 3.12346 3.123457 3.1234568 3.12345679 3.123456789

6. Les fonctions mathmatiques

En effet, quand le chiffre de rang infrieur est suprieur ou gal cinq, la rgle est darrondir au chiffre suprieur.

Hasard
Nombre pseudo-alatoire Lordinateur ne connat pas le hasard. Mais, comme il est parfois utile de gnrer un nombre alatoirement, il a fallu trouver une astuce pour faire comme si lordinateur en tait capable. Pour arriver ce rsultat, il a fallu gnrer une suite (la plus longue possible) de nombres rpondant des critres statistiques prcis. Lorsque lon a besoin dun nombre alatoire, le systme va piocher un nombre dans cette liste (le suivant dans la liste). Mais, si lon ny prend garde, aprs chaque redmarrage du logiciel, le nombre retourn risque dtre toujours le premier lment de la liste. Pour pallier ce problme, il faudrait donc choisir alatoirement (on se mord la queue) lendroit o commencer dans la liste. Pour choisir de faon plus ou moins alatoire

339

Chapitre 6

Les fonctions mathmatiques

cet endroit, il est gnralement fait appel lheure (les microsecondes). Comme tout ceci nest pas proprement parler du hasard, il est plus rigoureux de parler de nombre pseudo-alatoire que de nombre alatoire.
PHP propose deux types de fonctions : les classiques et les fonctions prfixes par mt_ (utilisant un autre algorithme).

Fonctions "classiques"

srand()
Initialise les gnrateurs de nombres alatoires. Attention de ne pas utiliser cette fonction avant tous les appels dans une boucle par exemple. Il est prfrable de ne lutiliser quune fois avant la gnration de plusieurs valeurs alatoires. Syntaxe $seed void srand([int $seed]) Une valeur quelconque qui doit changer dune fois sur lautre. On a pour habitude de prendre le nombre de microsecondes depuis la dernire seconde entire. srand((double)microtime()*1000000).

rand()
6. Les fonctions mathmatiques
Gnrateur de nombres alatoires. Sans arguments, elle renvoie un nombre entre 0 et la valeur maximale que peut retourner la fonction (i.e. getRandMax()). Sinon, elle renvoie un nombre compris entre les deux valeurs (incluses) fournies. Depuis PHP 4.2.0, il nest plus ncessaire de faire appel au pralable srand(), puisque cet appel est effectu automatiquement sil na pas dj eu lieu. Syntaxe $min $max retour int rand([int $min, int $max]) Plus petite valeur que doit retourner la fonction. Plus grande valeur que doit retourner la fonction. Un entier entre minimum et maximum inclus.

getRandMax()
Retourne la plus grande valeur pouvant tre atteinte par la fonction rand(). Syntaxe retour int getRandMax(void) Plus grande valeur que peut retourner la fonction rand().

340

Les fonctions mathmatiques et les constantes

Voici un exemple utilisant les fonctions getRandMax(), srand() et rand().

Listing 6.7 : rand.php


<?php echo "getRandMax()=".getRandMax()."<br />"; srand((double)microtime()*1000000); echo rand()."<br />"; echo rand()."<br />"; echo rand()."<br />"; echo rand()."<br />"; echo rand(0, 2)."<br />"; echo rand(0, 2)."<br />"; echo rand(0, 2)."<br />"; echo rand(0, 2)."<br />"; echo rand(0, 2)."<br />"; echo rand(0, 2)."<br />"; echo rand(0, 2)."<br />"; echo rand(0, 2)."<br />"; ?>

Le rsultat obtenu est le suivant (bien entendu, part la premire ligne, il varie dune excution lautre) :
getRandMax()=32767 1282 31943 31613 7866 0 1 2 0 2 1 0 2

6. Les fonctions mathmatiques

Fonctions "mt"

mt_srand()
Initialise le gnrateur de nombres alatoires. Attention de ne pas utiliser cette fonction avant tous les appels dans une boucle par exemple. Il est prfrable de ne lutiliser quune fois avant la gnration de plusieurs valeurs alatoires. Syntaxe $seed void mt_srand([int $seed]) Valeur quelconque qui doit changer dune fois sur lautre. On a pour habitude de prendre le nombre de microsecondes depuis la dernire seconde entire. mt_srand((double)microtime()*1000000).

341

Chapitre 6

Les fonctions mathmatiques

mt_rand()
Gnrateur de nombres alatoires.
mt_rand est une alternative la fonction rand. Elle est bien plus rapide (environ quatre fois)

et utilise la mthode de Mersenne Twister. Sans arguments, elle renvoie un nombre entre 0 et la valeur maximale que peut retourner la fonction (i.e. mt_getRandMax()). Sinon, elle renvoie un nombre compris entre les deux valeurs fournies incluses. Depuis PHP 4.2.0, il nest plus ncessaire de faire appel au pralable mt_srand(), puisque cet appel est effectu automatiquement sil na pas dj eu lieu. Syntaxe $min $max retour int mt_rand([int $min, int $max]) Plus petite valeur que doit retourner la fonction. Plus grande valeur que doit retourner la fonction. Entier entre minimum et maximum inclus.

mt_getRandMax()
Retourne la plus grande valeur pouvant tre atteinte par la fonction mt_rand(). Syntaxe int mt_getRandMax(void) Plus grande valeur que peut retourner mt_rand(). retour

6. Les fonctions mathmatiques

Voici un exemple utilisant les fonctions mt_getRandMax(), mt_srand() et mt_rand() :

Listing 6.8 : mt_rand.php


<?php echo "mt_getRandMax()=".mt_getRandMax()."<br />"; mt_srand((double)microtime()*1000000); echo mt_rand()."<br />"; echo mt_rand()."<br />"; echo mt_rand()."<br />"; echo mt_rand()."<br />"; echo mt_rand(0,2)."<br />"; echo mt_rand(0,2)."<br />"; echo mt_rand(0,2)."<br />"; echo mt_rand(0,2)."<br />"; echo mt_rand(0,2)."<br />"; echo mt_rand(0,2)."<br />"; echo mt_rand(0,2)."<br />"; echo mt_rand(0,2)."<br />"; ?>

342

Les fonctions mathmatiques et les constantes

Le rsultat obtenu est le suivant (bien entendu, part la premire ligne, il varie dune excution lautre).
mt_getRandMax()=2147483647 617390894 505571108 175954693 741777589 2 0 1 1 2 0 2 0

Autres

lcg_value()
Gnrateur de congruence combine linaire. Cette fonction retourne un nombre pseudo-alatoire compris entre 0 et 1. Elle combine deux nombres de priode 2^31-85 et 2^31-249. La priode de cette fonction est gale au produit de ces deux nombres premiers soit (2^31-85)*(2^31-249). Syntaxe retour double lcg_value() Rel pseudo-alatoire compris entre 0 et 1.

6. Les fonctions mathmatiques

Voici un exemple utilisant la fonction lcg_value() :

Listing 6.9 : lcg.php


<?php echo(lcg_value()."<br />"); echo(lcg_value()."<br />"); echo(lcg_value()."<br />"); echo(lcg_value()."<br />"); echo(lcg_value()."<br />"); echo(lcg_value()."<br />"); $a = 3; $b = 7; // Voici une formule pour obtenir un nombre echo(floor($a + lcg_value()*($b-$a+1))."<br echo(floor($a + lcg_value()*($b-$a+1))."<br echo(floor($a + lcg_value()*($b-$a+1))."<br echo(floor($a + lcg_value()*($b-$a+1))."<br ?>

entre $a et $b inclus />"); />"); />"); />");

343

Chapitre 6

Les fonctions mathmatiques

Voici le rsultat retourn :


0.30513436806404 0.068577150355096 0.57782412638032 0.9158474922213 0.0046724566600712 0.1675198682609 7 3 4 6

Conversion de bases

base_convert()
Retourne un nombre converti dune base dans une autre. Syntaxe $nombre $depuisBase $versBase retour string base_convert(string $nombre, int $depuisBase, int $versBase) Nombre convertir crit en base $depuisBase. Base dorigine entre 2 et 36. Base darrive entre 2 et 36. Nombre en base $versBase.

6. Les fonctions mathmatiques

binDec()
Retourne la conversion dun nombre binaire infrieur 2147483647 (31 bits 1) en nombre de base 10 (dcimal). Syntaxe $binaire retour int binDec(string $binaire) Nombre binaire de moins de 32 bits. Nombre en base 10.

decBin()
Retourne la conversion dun nombre dcimal (i.e. base 10) infrieur 2147483647 (31 bits 1) en nombre de base 2 (binaire). Syntaxe $decimal retour string decBin(int $decimal) Nombre dcimal (i.e. base 10) infrieur 2147483647. Nombre en base 2.

344

Les fonctions mathmatiques et les constantes

decHex()
Retourne la conversion dun nombre dcimal (i.e. base 10) infrieur 2147483647 (31 bits 1 ou encore 7FFFFFFF en hexadcimal) en nombre de base 16. Syntaxe $decimal retour string decHex(int $decimal) Nombre dcimal (i.e. base 10) infrieur 2147483647. Nombre en base 16.

hexDec()
Retourne la conversion dun nombre hexadcimal infrieur 7FFFFFFF (31 bits 1 ou encore 2147483647 en dcimal) en nombre dcimal (i.e. base 10). Syntaxe $hexadecimal retour int hexDec(string $hexadecimal) Nombre dcimal infrieur 7FFFFFFF. Nombre dcimal (i.e. base 10).

decOct()
6. Les fonctions mathmatiques
Retourne la conversion dun nombre dcimal (i.e. base 10) infrieur 2147483647 (31 bits 1 ou encore 17777777777 en octal) en nombre de base 8. Syntaxe $decimal retour string decOct(int $decimal) Nombre dcimal (i.e. base 10) infrieur 2147483647. Nombre en base 8.

octDec()
Retourne la conversion dun nombre octal infrieur 17777777777 (31 bits 1 ou encore 2147483647 en dcimal) en nombre dcimal (i.e. base 10). Syntaxe $octal retour int octDec(string $octal) Nombre octal infrieur 17777777777. Nombre dcimal (i.e. base 10).

345

Chapitre 6

Les fonctions mathmatiques

Voici un exemple utilisant toutes ces fonctions de conversion de bases.

Listing 6.10 : bases.php


<?php echo echo echo echo echo echo echo echo echo ?> base_convert("28", 10, 2)."<br />"; // 11100 base_convert("28", 10, 8)."<br />"; // 34 base_convert("28", 10, 16)."<br />"; // 1c decBin(28)."<br />"; // 11100 binDec("11100")."<br />"; // 28 decOct(28)."<br />"; // 34 octDec("34")."<br />"; // 28 decHex(28)."<br />"; // 1c hexDec("1c")."<br />"; // 28

Et le rsultat retourn est :


11100 34 1c 11100 28 34 28 1c 28

6. Les fonctions mathmatiques

Autres

abs()
Cette fonction retourne la valeur absolue de largument. Si largument est un rel, la valeur retourne est un rel ; sinon, cest un entier. Syntaxe $nombre retour mixed abs(mixed $nombre) Valeur relle ou entire. Valeur absolue du nombre.

max()
Retourne le plus grand lment. Syntaxe $arg1 mixed max(mixed $arg1 [, mixed $arg2, ...[, mixed $argn]]) Un tableau, une chane de caractres, un rel ou un entier.

346

Les fonctions mathmatiques et les constantes

$arg2 $argn retour

Une chane de caractres, un rel ou un entier si $arg1 nest pas un tableau. Une chane de caractres, un rel ou un entier si $arg1 nest pas un tableau. Le plus grand lment du tableau si largument est un tableau. Si tous les arguments sont de type string, la valeur retourne est la dernire valeur par rapport lordre alphabtique. Si tous les arguments numriques sont de type int, cest un entier qui est retourn ; sinon cest un rel.

min()
Retourne le plus petit lment. Syntaxe $arg1 $arg2 $argn retour mixed min(mixed $arg1 [, mixed $arg2, ... [, mixed $argn]) Un tableau, une chane de caractres, un rel ou un entier. Une chane de caractres, un rel ou un entier si $arg1 nest pas un tableau. Une chane de caractres, un rel ou un entier si $arg1 nest pas un tableau. Le plus petit lment du tableau si largument est un tableau. Si tous les arguments sont de type string, la valeur retourne est la premire valeur par rapport lordre alphabtique. Si tous les arguments numriques sont de type int, cest un entier qui est retourn ; sinon cest un rel.

6. Les fonctions mathmatiques

number_format()
Formate un nombre. Cette fonction prend un, deux ou quatre paramtres. Sil ny a quun paramtre, il sera format sans dcimal et avec une virgule sparant les milliers. Sil y a deux paramtres, le deuxime argument est le nombre de dcimales afficher. Elles sont alors spares par une virgule. Sil y a quatre paramtres, les deux premiers sont les mmes que dans le cas de deux paramtres, les suivants sont les sparateurs de dcimales et de milliers. Syntaxe $nombre $decimales $delimiteur $milliers retour string number_format(double $nombre [, int $decimales [, string $delimiteur , string $milliers]]) Nombre formater. Nombre de dcimales afficher. Sparateur de dcimales (, en franais, . en anglais). Sparateur de milliers ( en franais, , en anglais). Chane de caractres du nombre format.

347

Chapitre 6

Les fonctions mathmatiques

Voici un exemple dutilisation de la fonction number_format() :

Listing 6.11 : numberf.php


<?php $number = 123456789.12345; // exemple avec un seul argument echo number_format($number); echo "<br />"; // exemple avec deux arguments echo number_format($number, 3); echo "<br />"; // exemple de notation anglaise avec 4 arguments echo number_format($number, 3, ., ,); echo "<br />"; // exemple de notation franaise avec 4 arguments echo number_format($number, 3, ,, ); ?>

En sortie, on obtiendra :
123,456,789 123,456,789.123 123,456,789.123 123 456 789,123

6.2.
6. Les fonctions mathmatiques

Calculs de prcision

Les calculs de prcision utilisent la bibliothque BCMath.

Installation
Sous Windows
La version distribue par PHP inclut le support de la bibliothque BCMath (cest galement vrai pour le kit EasyPHP). Vous naurez donc rien faire de particulier pour en profiter.

Sous Linux
Assurez-vous davoir compil PHP avec loption enablebcmath.

Vous pouvez vous reporter au chapitre "Installation" pour plus de dtails sur la compilation de PHP.

348

Calculs de prcision

Vrication
Vous pouvez vous assurer que la bibliothque BCMath est bien disponible par un simple script contenant <?php phpinfo(); ?> et qui doit laisser apparatre :
Figure 6.1 :

phpinfo()

Utilisation
Avec la bibliothque BCMath, les nombres sont reprsents par des chanes de caractres. Ils ne sont donc pas a priori limits en taille et, par consquent, nont pas de limite thorique en prcision.

bcscale()
Dfinit la prcision par dfaut (remplace le paramtre bcmath.scale du fichier php.ini). Syntaxe $precision retour boolean bcscale(int $precision) Entier exprimant le nombre de dcimales par dfaut. TRUE.

bcadd()
Ajoute deux nombres. Syntaxe $operande1 $operande2 $precision retour string bcadd(string $operande1, string $operande2 [, int $precision]) Chane de caractres reprsentant un nombre. Chane de caractres reprsentant un nombre. Nombre de dcimales. Chane de caractres reprsentant $operande1+$operande2.

6. Les fonctions mathmatiques

bcsub()
Soustrait deux nombres. Syntaxe $operande1 $operande2 $precision retour string bcsub(string $operande1, string $operande2 [, int $precision]) Chane de caractres reprsentant un nombre. Chane de caractres reprsentant un nombre. Nombre de dcimales. Chane de caractres reprsentant $operande1$operande2.

349

Chapitre 6

Les fonctions mathmatiques

bcmul()
Multiplie deux nombres. Syntaxe $operande1 $operande2 $precision retour string bcmul(string $operande1, string $operande2 [, int $precision]) Chane de caractres reprsentant un nombre. Chane de caractres reprsentant un nombre. Nombre de dcimales. Chane de caractres reprsentant $operande1*$operande2.

bcdiv()
Divise deux nombres. Syntaxe $operande1 $operande2 $precision retour string bcdiv(string $operande1, string $operande2 [, int $precision]) Chane de caractres reprsentant un nombre. Chane de caractres reprsentant un nombre. Nombre de dcimales. Chane de caractres reprsentant $operande1/$operande2.

6. Les fonctions mathmatiques

bcmod()
Retourne le reste dune division. Syntaxe $operande1 $operande2 retour string bcmod(string $operande1, string $operande2) Chane de caractres reprsentant un nombre. Chane de caractres reprsentant un nombre. Chane de caractres reprsentant $operande1 % $operande2.

bcpow()
lve un nombre une puissance. Syntaxe $operande1 $operande2 string bcpow(string $operande1, string $operande2 [, int $precision]) Chane de caractres reprsentant un nombre. Chane de caractres reprsentant un nombre.

350

Calculs de prcision

$precision retour

Nombre de dcimales. Chane de caractres reprsentant $operande la puissance $operande2.

bcsqrt()
Retourne la racine carre dun nombre. Syntaxe $operande $precision retour string bcsqrt(string $operande [, int $precision]) Chane de caractres reprsentant un nombre. Nombre de dcimales. Chane de caractres reprsentant la racine carre de loprande.

bccomp()
Compare deux nombres. Syntaxe $operande1 $operande2 $precision retour int bccomp(string $operande1, string $operande2 [, int $precision]) Chane de caractres reprsentant un nombre. Chane de caractres reprsentant un nombre.

6. Les fonctions mathmatiques

Nombre de dcimales. 0 si les deux nombres sont identiques, 1 si $operande1 est plus grand que $operande2, sinon 1.

Voici un exemple de calcul utilisant la bibliothque BCMath.

Listing 6.12 : precision.php


<?php bcscale(10); $a = "12345678901234567890"; $b = "12345678"; echo "Addition:<br />"; echo ($a + $b)."<br />"; echo bcadd($a, $b)."<br />"; echo "Soustraction:<br />"; echo ($a - $b)."<br />"; echo bcsub($a, $b)."<br />"; echo "Multiplication:<br />"; echo ($a * $b)."<br />"; echo bcmul($a , $b)."<br />"; echo "Division:<br />";

351

Chapitre 6

Les fonctions mathmatiques

echo echo echo echo echo echo echo echo echo echo echo ?>

($a / $b)."<br />"; bcdiv($a, $b)."<br />"; "Restant de la division:<br />"; ($a % $b)."<br />"; bcmod($a, $b)."<br />"; "Exposant:<br />"; pow($a, 2)."<br />"; bcpow($a, 2)."<br />"; "Racine carre:<br />"; sqrt($a)."<br />"; bcsqrt($a)."<br />";

Et le rsultat retourn est le suivant : Addition: 1.23456789012E+19 12345678901246913568.0000000000 Soustraction: 1.23456789012E+19 12345678901222222212.0000000000 Multiplication: 1.52415776406E+26 152415776406035777639079420 Division: 1000000073E+12 1000000073000.0059850904 Restant de la division: 11681353 73890 Exposant: Warning: Invalid argument(s) passed to pow() in precision.php on line 21 152415787532388367501905199875019052100 Racine carre: 3513641828.82 3513641828.8201442530 On peut remarquer lerreur conscutive un calcul du reste de la division sans prendre garde aux limites de prcision de PHP ; qui plus est, PHP refuse de calculer la puissance si lon ne passe pas par BCMath.

6. Les fonctions mathmatiques

Affichage des nombres Pour une valeur donne, le nombre de chiffres affichs dpend de la configuration de PHP et, en particulier, du paramtre precision du fichier php.ini. Cette remarque ne sapplique videmment pas aux valeurs retournes par BCMath, qui sont, de toute faon, des chanes de caractres.

352

Chapitre 7

La manipulation des chanes de caractres


7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 Gnralits . . . . . . . . . . . . . . . . . . . . . . Fonctions de gestion des chanes de caractres Comparaison de chanes de caractres . . . . . Gestion des caractres spciaux . . . . . . . . . Manipulation des balises HTML . . . . . . . . . Insertion de motifs . . . . . . . . . . . . . . . . . Fusion et dcoupe . . . . . . . . . . . . . . . . . . Expressions rgulires . . . . . . . . . . . . . . . Adapter le texte la langue du visiteur . . . . . .. . .. .. .. .. .. .. .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 363 376 385 395 401 402 409 431

Gnralits

7.1.

Gnralits

Ce chapitre est peut-tre le plus important, lutilisation des chanes de caractres tant en effet invitable pour produire le code HTML dsir. Les chanes de caractres peuvent tre encadres soit par des apostrophes () soit par des guillemets ("). Lorsque vous utilisez des guillemets, vous pouvez intgrer directement des noms de variables au sein de la chane de caractres, et celles-ci seront subtitues par leurs valeurs. Ce nest pas le cas si vous utilisez les apostrophes. Ainsi,
<?php $monNom = "Emma"; echo "Bonjour $monNom <br />"; echo Bonjour $monNom <br />; ?>

affichera :
Bonjour Emma Bonjour $monNom

Dans le cas de lutilisation des guillemets, nous aurons donc besoin de faire appel aux squences dchappement afin de pouvoir afficher le signe $. Mais ceci concerne galement les caractres suivants :

Tableau 7.1 : Squences dchappement


Notation \n \r \t \\ \$ \" Description Changement de ligne. Retour chariot.

7. La manipulation des chanes de caractres

Tabulation. Pour afficher \ (et viter la confusion avec le caractre dchappement). Pour afficher $ (et viter la confusion avec linterprtation dune variable). Pour afficher " (et viter la confusion avec la fin de la chane de caractres).

La seule squence dchappement disponible lors de lutilisation des apostrophes et la suivante : \. Elle met fin la confusion quil pourrait y avoir avec la dclaration de fin de chane. Si lon veut utiliser des guillemets lintrieur dautres guillemets, il est vident que cela pose problme, comme dans lexemple suivant :
"Coluche a dit "Plus on est de fous moins ya de riz", pas faux..."

Lanalyseur syntaxique de PHP va reconnatre une premire chane "Coluche a dit " puis des lettres quil ne saura pas interprter Plus on est de fous moins ya de riz, et, enfin, une chane de caractres ", pas faux...".

355

Chapitre 7

La manipulation des chanes de caractres

Cest pourquoi il faut prciser que le caractre " est un caractre afficher. Pour cela, il a t dcid dy ajouter \. La phrase dexemple scrit donc :
"Coluche a dit \"Plus on est de fous moins ya de riz\", pas faux..."

Et, pour afficher \, il faut donc prciser que ce nest pas le caractre dchappement en le doublant : \\.

Chemins de fichiers Windows \\ est notamment utiliser pour les chemins windows. "C:\monRepertoire\monFichier.php" scrit "C:\\monRepertoire\\monFichier.php".

\\ Pour crire \\, il suffit de doubler chacun des caractres. On obtient donc \\\\ et ainsi de suite Cette mthode permet de garder la libert dutiliser tous les caractres.
Le script suivant nous montre comment utiliser les squences dchappement :

Listing 7.1 : cc01.php


<?php echo "1 - Facile"; echo "\n"; echo 2 - Facile; echo "\n"; echo "3 - Cest plus dur"; echo "\n"; echo 4 - C\est plus dur; echo "\n"; $variable="valeur"; echo "5 - $variable"; echo "\n"; echo 6 - $variable; echo "\n"; echo "7 - \$variable"; echo "\n"; echo "8 - citation \"PHP est facile\""; echo "\n"; echo 9 - citation "PHP est facile"; echo "\n"; // pour afficher \" avec les guillemets: echo "10 - \\\""; ?>

7. La manipulation des chanes de caractres

Voici le rsultat obtenu dans le code source gnr :

356

Gnralits

1 - Facile 2 - Facile 3 - Cest plus dur 4 - Cest plus dur 5 - valeur 6 - $variable 7 - $variable 8 - citation "PHP est facile" 9 - citation "PHP est facile" 10 - \"

Pour accder des lments dune base de donnes, il faut particulirement faire attention lutilisation des apostrophes. Par exemple :
"SELECT * FROM matable WHERE monchamp=$valeur"

posera problme si $valeur contient une apostrophe. Heureusement, la fonction addSlashes() ajoute le caractre dchappement devant les caractres problmatiques. Il faut donc crire :
"SELECT * FROM matable WHERE monchamp=".addSlashes($valeur).""

Le mme genre de problme se retrouve lorsque lon veut, par exemple, donner une valeur par dfaut dans un champ HTML. Une fonction spcifique existe, qui sappelle htmlSpecialChars().
echo "<input type=\"hidden\" name=\"variable\" value=\"".htmlSpecialChars($maVariable)."\" />"

Par dfaut, PHP est configur avec loption magic_quotes_gpc active. Ainsi, les valeurs passes par les mthodes GET, POST et les cookies voient leurs apostrophes automatiquement prcdes dun anti-slash (il nest alors plus ncessaire de faire appel addSlashes() pour les utiliser dans des requtes SQL). Il est possible de faire de mme pour les fichiers et les bases de donnes, en utilisant le paramtre similaire magic_quotes_runtime.

7. La manipulation des chanes de caractres

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur la configuration de PHP.
Rappelons que loprateur de concatnation est le point . et que loprateur .= est galement valide. Ainsi "Langage "."PHP" vaut "Langage PHP".

Afficher du texte
Il existe plusieurs faons dafficher une chane de caractres. La manire la plus simple est lutilisation de echo. Lcriture sur plusieurs lignes peut se faire au moyen de <<< suivis dun identifiant de fin de texte, qui ne sera pas dans le texte crire. Lidentifiant plac la fin du texte doit obligatoirement commencer sur la premire colonne du fichier.

357

Chapitre 7

La manipulation des chanes de caractres

Voici diffrents cas dutilisation de echo :


<?php $variable = "valeur\n"; echo $variable; echo "$variable"; echo "variable"," ",$variable; echo "On peut aussi crire sur plusieurs lignes\n"; echo <<<END On peut aussi crire sur plusieurs lignes de cette faon\n END; echo <<<TEXTE On peut aussi crire sur plusieurs lignes de cette faon TEXTE; ?>

Et voici le rsultat de sortie :


valeur valeur variable valeur On peut aussi crire sur plusieurs lignes On peut aussi crire sur plusieurs lignes de cette faon On peut aussi crire sur plusieurs lignes de cette faon

7. La manipulation des chanes de caractres 358

Gnralits

Une fonction trs proche de la commande echo sappelle print(). La diffrence est tellement infime que beaucoup se demandent o elle se trouve. print() est une fonction qui retourne un boolen, elle renvoie TRUE quand laffichage sest effectu.
echo est lgrement plus rapide que print(), dans la mesure o cette fonction ne retourne rien. Mais la diffrence reste minime.

Les deux fonctions printf() et sprintf() permettent respectivement dafficher et de retourner une chane de caractres formate.

printf()
Affiche une chane de caractres (ventuellement accompagne de valeurs) selon un format donn. Syntaxe $format $valeurs void printf(string $format [, mixed $valeurs]) Chane dcrivant le format attendu. Les valeurs formater.

sprintf()
Retourne une chane de caractres (ventuellement accompagne de valeurs) selon un format donn. Syntaxe $format $valeurs retour string sprintf(string $format [, mixed $valeurs]) Chane dcrivant le format attendu. Les valeurs formater. La chane formate.

7. La manipulation des chanes de caractres

Les lments formats sont dfinis par le signe % suivi de diffrents caractres (ex. :%03.2f) dont voici une description :
j

Le premier est facultatif. Il sert dterminer le caractre qui complte les caractres manquants ; par dfaut, il vaut le caractre despacement. Pour dfinir ce paramtre, il suffit de le faire prcder dune apostrophe (inutile pour le chiffre 0). (Cela peut, par exemple, permettre dafficher un nombre sur trois chiffres, mme sil est infrieur 100). Le deuxime paramtre est lui aussi optionnel. Il dtermine si le rsultat doit tre align droite ou gauche. Par dfaut, il sera align droite ; pour le faire aligner gauche, il suffit de placer le signe . Le troisime paramtre est lui aussi optionnel. Il dtermine le nombre de caractres minimum retourner.

359

Chapitre 7

La manipulation des chanes de caractres

Le quatrime paramtre est lui aussi optionnel. Il dtermine le nombre de dcimales afficher pour les rels. Ce paramtre na bien sr aucun effet sur les autres types ; il est prcd dun point. Le cinquime paramtre est obligatoire. Il dfinit selon quel type largument doit tre trait puis reprsent. Voici les diffrents types possibles :

Tableau 7.2 : Les diffrents types


Lettre b c d u f o s x X Trait Entier Entier Entier Entier Rel Entier Tel quel Entier Entier Reprsent Binaire Caractre avec sa valeur ASCII Nombre dcimal sign Nombre dcimal non sign Rel Nombre octal Chane de caractres Nombre hexadcimal Nombre hexadcimal en majuscules

criture du caractre % Pour crire le caractre %, il suffit de le doubler afin dviter la confusion. Au moment de laffichage un seul apparatra.
Voici quelques exemples utiles :

7. La manipulation des chanes de caractres

Listing 7.2 : sprintf.php


<?php echo "Date<br /> "; printf("%02d/%02d/%04d", 1, 7, 2002); echo "<br />Pi avec 7 dcimales<br />"; printf("%.7f", M_PI); echo "<br />Ecriture dune chane<br />"; printf(".:%s:.", "Salut !"); echo "<br />Ecriture dune chane avec 20 printf(".:%20s:.", "Salut"); echo "<br />Ecriture dune chane avec 20 " align gauche<br />"; printf(".:%-20s:.", "Salut"); echo "<br />Ecriture dune chane avec 20 " complt par des -<br />"; printf(".:%-20s:.", "Salut"); echo "<br />Ecriture dune chane avec 20

caractres minimum<br />"; caractres minimum,".

caractres minimum,".

caractres minimum,".

360

Gnralits

" align gauche, complt par des -<br />"; printf(".:%--20s:.", "Salut"); echo "<br />Ecriture de %<br />"; printf("%%"); ?>

Et voici le rsultat obtenu :


Date 01/07/2002 Pi avec 7 dcimales 3.1415927 Ecriture dune chane .:Salut !:. Ecriture dune chane avec .: Salut:. Ecriture dune chane avec .:Salut :. Ecriture dune chane avec .:---------------Salut:. Ecriture dune chane avec des .:Salut---------------:. Ecriture de % %

20 caractres minimum 20 caractres minimum, align gauche 20 caractres minimum, complt par des 20 caractres minimum, align gauche, complt par

La fonction vPrintf() permet dafficher un tableau. Elle fonctionne de la mme manire que printf().

vPrintf()
7. La manipulation des chanes de caractres
Affiche une chane de caractres formate et construite partir de donnes stockes dans un tableau. Syntaxe $format $tableau retour Voici un exemple :
<?php $tableau=array("Element 1", "Element 2", "Element 3"); vPrintf("%2\$s|%1\$s|%3\$s", $tableau); ?>

boolean vPrintf(string $format, array $tableau) Voir description de printf(). Tableau afficher. Un boolen.

dont le rsultat obtenu est le suivant :


Element 2|Element 1|Element 3

361

Chapitre 7

La manipulation des chanes de caractres

vSPrintf()
Retourne une chane de caractres formate et construite partir de donnes stockes dans un tableau. Syntaxe $format $tableau retour string vSPrintf(string $format, array $tableau) Voir description de vPrintf(). Tableau afficher. La chane de caractres.

sscanf()
Permet de faire lanalyse lexicale dune chane de caractres (i.e. de rcuprer les informations qui la composent). Syntaxe $chaine $format $variableSortieN retour mixed sscanf(string $chaine, string $format[, string &$variableSortie1 [, string &$variableSortie2[, ]]] Chane de caractres dont on veut rcuprer des lments. Format de la chane analyser. Variables dans lesquelles vous souhaitez stocker les diffrents lments extraits de la chane de caractres. Tableau avec les diffrentes parties reconnues de la chane de caractres, ou le nombre de sous-chanes reconnues si des des variables sont passes par rfrence.

7. La manipulation des chanes de caractres

Un exemple dutilisation de sscanf() :


<?php $phrase = "Jai 25 ans et je suis Franais"; $tableau = sscanf($phrase, "Jai %d ans et je suis %s"); echo $tableau[0]."<br />\n"; echo $tableau[1]."<br />\n"; list($age, $nationalite) = sscanf($phrase, "Jai %d ans et je suis %s"); echo $age."<br />\n"; echo $nationalite."<br />\n"; $refage=0; $refnat=""; echo sscanf($phrase, "Jai %d ans et je suis %s", &$refage, &$refnat) ." lments<br />\n"; echo $refage."<br />\n"; echo $refnat."<br />\n";

?>

362

Fonctions de gestion des chanes de caractres

Et le rsultat obtenu :
25 Franais 25 Franais 2 lments 25 Franais

Manipuler les caractres

chr()
Retourne le caractre dun code ASCII. Syntaxe $codeAscii retour string chr(int $codeAscii) Code ASCII du caractre afficher. Caractre correspondant au code ASCII pass en paramtre.

ord()
Retourne le code ASCII du premier caractre dune chane. Syntaxe $chaine retour int ord(string $chaine) Chane dont on veut le caractre ASCII du premier caractre. Code ASCII du premier caractre.

7. La manipulation des chanes de caractres

7.2.

Fonctions de gestion des chanes de caractres

Extraction et substitution
Extraction

substr()
Retourne une partie dune chane de caractres. Syntaxe $chaine string substr(string $chaine, int $debut [,int $nbCaracteres]) Chane de caractres de laquelle vous souhaitez extraire une partie.

363

Chapitre 7

La manipulation des chanes de caractres

$debut

Indice du caractre de dpart. (Le premier caractre ayant lindice 0, si la valeur est ngative, le compte se fait depuis la droite, le dernier caractre ayant lindice -1). La sous-chane demande.

retour

Listing 7.3 : substr.php


<?php echo substr("abcdefghij", echo "<br />"; echo substr("abcdefghij", echo "<br />"; echo substr("abcdefghij", echo "<br />"; echo substr("abcdefghij", echo "<br />"; echo substr("abcdefghij", ?> 2); 0, 3); 1, 4); 5, 20); -3, 2);

Et le rsultat obtenu est le suivant :


cdefghij abc bcde fghij hi

Parfois, nous ne sommes pas en mesure de connatre par avance la position recherche dans une chane de caractres. Les fonctions suivantes ne ncessitent pas de connatre dindex. La fonction strstr() permet de retrouver la premire occurrence dun caractre ou dune chane de caractres dans une autre chane de caractres.

7. La manipulation des chanes de caractres

strstr()
Permet de rcuprer la partie dune chane de caractres situe partir de la premire occurrence dune sous-chane. Syntaxe $chaine $souschaine retour string strstr(string $chaine, string $souschaine) Chane de caractres do vous souhaitez extraire une partie. Chane de caractres dfinissant le dbut. Une sous-chane de $chaine comprenant $souschaine et la fin de $chaine.

Listing 7.4 : strstr.php


<?php echo "strstr:".strstr("Voici un exemple stupide dexemple", "exemple");

364

Fonctions de gestion des chanes de caractres

echo "\n"; echo "strstr:".strstr("thomas@toutestfacile.com", "@"); ?>

En sortie, nous obtiendrons :


strstr:exemple stupide dexemple strstr:@toutestfacile.com

strchr()
strchr() est un alias de strstr(), cest--dire que ces deux fonctions sont en tous points identiques.
strstr() est une fonction sensible aux majuscules/minuscules. Pour ne pas prendre en compte la casse, il faut utiliser stristr(), qui fonctionne de la mme faon.

Listing 7.5 : stristr.php


<?php echo "strstr:".strstr("Voici un exemple stupide dexemple", "Exemple"); echo "\n"; echo "stristr:".stristr("Voici un exemple stupide dexemple", "Exemple"); ?>

En sortie, nous obtiendrons :


strstr: stristr:exemple stupide dexemple

Dans le cas o nous avons utilis strstr(), la sous-chane de caractres "Exemple" na pas t trouve cause de la majuscule.

7. La manipulation des chanes de caractres

Dans le cas o la sous-chane est prsente plusieurs fois, il est possible de rcuprer la partie situe aprs la dernire occurrence laide de strrchr().

strrchr()
Permet de rcuprer la partie dune chane de caractres situe partir de la dernire occurrence dune autre chane. Syntaxe $chaine $souschaine retour
<?php

string strrchr(string $chaine, string $souschaine) Chane de caractres do vous souhaitez extraire une partie. Chane de caractres dfinissant le dbut. Une sous-chane de $chaine comprenant $souschaine et la fin de $chaine.

365

Chapitre 7

La manipulation des chanes de caractres

echo strrchr("Voici un exemple stupide dexemple", "exemple"); echo "\n"; echo strrchr("article 1,article 2, article 3", ","); ?>

Et voici le rsultat obtenu :


e , article 3

Substitution

substr_replace()
Retourne une chane de caractres issue dune chane dans laquelle une partie a t remplace par une autre. Permet galement dinsrer du texte. Syntaxe $chaine $substitution $debut string substr_replace(string $chaine, string $substitution, int $debut [, int $nbCaracteres]) Chane de caractres dans laquelle vous souhaitez remplacer du texte. Chane de caractres que vous souhaitez crire la place. Indice du caractre de dpart. (Le premier caractre ayant lindice 0, si la valeur est ngative, le compte se fait depuis la droite, le dernier caractre ayant lindice -1). Nombre de caractres remplacer. La chane de caractres modifie.

$nbCaracteres retour

7. La manipulation des chanes de caractres

Listing 7.6 : substrreplace.php


<?php echo substr_replace("abCDEF", "AB", 0, 2); echo "<br />"; echo substr_replace("100000 Euros", ",", -9, 0); ?> ABCDEF 100,000 Euros

Il est possible dutiliser cette fonction afin de rduire des chanes de caractres. Par exemple, pour modifier "cette trop longue phrase" en "cette trop longue ph", il suffit dcrire :
substr_replace("cette trop longue phrase", "...", 20)

Il est assez rare que nous connaissions par avance la position des caractres dans la chane. Bien plus souvent, il sagit dun mot ou dune expression que nous souhaitons remplacer par un(e) autre. Il est, par exemple, possible dimaginer que lon souhaite remplacer les mots vulgaires dun forum par (censur). La fonction qui va nous le permettre sappelle str_replace().

366

Fonctions de gestion des chanes de caractres

str_replace()
Cette fonction permet de remplacer des occurrences par dautres. Syntaxe $motif $remplacement $chaine mixed str_replace(mixed $motif, mixed $remplacement, mixed $chaine [, int &$nombreRemplacements]) Une chane de caractres ou un tableau de chanes de caractres dsignant le ou les lments rechercher. Une chane de caractres ou un tableau de chanes de caractres dsignant le ou les lments qui remplaceront les lments de $motif. Une chane de caractres ou un tableau de chanes de caractres dsignant le ou les lments modifier.

$nombreRemplacements Cette fonction ecrira dans la variable $nombre_remplacements, le nombre de remplacements effectus dans la chane de caractres. (Cette option nexiste que depuis la version 5.0.0 de PHP) retour La chane de caractres ou le tableau de chanes de caractres modifi.

Lutilisation la plus simple consiste remplacer une sous-chane par une autre dans une chane de caractres. Voici un code source dexemple :

Listing 7.7 : strreplace1.php


<?php $phrase = "Jessicasse-croutes dans mon panier"; echo $phrase."<br />"; $phrase = str_replace("Jessica", "Jai 6 ca", $phrase); echo $phrase."<br />"; ?>

7. La manipulation des chanes de caractres

Et le rsultat :
Jessicasse-croutes dans mon panier Jai 6 casse-croutes dans mon panier

Si $chaine est un tableau, le remplacement seffectue sur tous les lments du tableau. En retour, nous obtenons alors un tableau des chanes de caractres modifies. Voici un code source dexemple :

Listing 7.8 : strreplace2.php


<?php $phrases = array("Jessicasse-croutes dans mon panier", "Jessicanapes dans mon salon", "Jessicadeaux sous mon sapin"); echo $phrases[0]."<br />"; echo $phrases[1]."<br />"; echo $phrases[2]."<br />";

367

Chapitre 7

La manipulation des chanes de caractres

$phrases = str_replace("Jessica", "Jai 6 ca", $phrases); echo $phrases[0]."<br />"; echo $phrases[1]."<br />"; echo $phrases[2]."<br />"; ?>

Et le rsultat :
Jessicasse-croutes dans mon panier Jessicanapes dans mon salon Jessicadeaux sous mon sapin Jai 6 casse-croutes dans mon panier Jai 6 canapes dans mon salon Jai 6 cadeaux sous mon sapin

Il est galement possible de tirer partie de cette fonction pour effectuer plusieurs modifications dun seul coup, en utilisant des tableaux pour les variables $motif et $remplacement. Voici un code source dexemple :

Listing 7.9 : strreplace3.php


<?php $phrases = array ("Jessicasse-croutes dans mon panier et Jean ai dautres dans mon placard", "Jessicanapes dans mon salon et Jean ai un dans la chambre"); echo $phrases[0]."<br />"; echo $phrases[1]."<br />"; $phrases = str_replace(array("Jessica","Jean"), array("Jai 6 ca", "jen"), $phrases); echo $phrases[0]."<br />"; echo $phrases[1]."<br />"; ?>

7. La manipulation des chanes de caractres

Et le rsultat :
Jessicasse-croutes dans mon panier et Jean ai dautres dans mon placard Jessicanapes dans mon salon et Jean ai un dans la chambre Jai 6 casse-croutes dans mon panier et jen ai dautres dans mon placard Jai 6 canapes dans mon salon et jen ai un dans la chambre

Pour ne remplacer que des caractres, comme par exemple pour retirer les accents, on pourrait utiliser str_replace(), mais on peut galement utiliser la fonction strtr().

Remplacement insensible la casse Si vous possedez la version 5.0.0 ou suprieure de PHP, vous pouvez utiliser la fonction str_ireplace() qui se comporte comme str_replace hormis quelle est remplacera galement les chanes de caractres ayant une casse diffrente. (minuscules/majuscules)

368

Fonctions de gestion des chanes de caractres

strtr() (syntaxe 1)
Retourne une chane de caractres dans laquelle certains caractres ont t remplacs par dautres. Syntaxe $chaine $depuis $vers retour string strtr(string $chaine, string $depuis, string $vers) Chane de caractres o les modifications doivent tre effectues. Chane de caractres indiquant tous les caractres modifier. Chane de caractres indiquant les caractres qui devront remplacer ceux de $depuis. La chane modifie.

Voici un exemple qui permet de supprimer les accents dans une phrase.

Listing 7.10 : strtr1.php


<?php $phrase = "Les accents sur , , , , , vont tre supprims"; echo $phrase."<br />"; $phrase = strtr($phrase, "", "aeiouaeiouaeiou"); echo $phrase; ?>

Voici le rsultat obtenu :


Les accents sur , , , , , vont tre supprims Les accents sur a, e, e, u, e, o vont etre supprimes

Une autre syntaxe existe, qui consiste dclarer un tableau associatif. Cela permet de remplacer des chanes de caractres par dautres.

7. La manipulation des chanes de caractres

strtr() (syntaxe 2)
Retourne une chane de caractres dans laquelle certains caractres ont t remplacs par dautres. Syntaxe $chaine $remplacement retour string strtr(string $chaine, array $remplacement) Chane de caractres o les modifications doivent tre effectues. Tableau associatif ayant pour cls les chanes de caractres remplacer, et pour valeurs les chanes de substitution correspondantes. La chane modifie.

Voici un exemple utilisant cette syntaxe :

369

Chapitre 7

La manipulation des chanes de caractres

Listing 7.11 : strtr2.php


<?php $phrase = "Les accents sur , , , , , vont tre supprims"; echo $phrase."<br />"; $remplacements = array( => a, => e, => e, => u, => e, => o, vont tre => ont ts ); $phrase=strtr($phrase , $remplacements); echo $phrase; ?>

Et voici le rsultat obtenu :


Les accents sur , , , , , vont tre supprims Les accents sur a, e, e, u, e, o ont t supprims

Fonctions statistiques (longueur et nombre doccurrences)

strlen()
Retourne la longueur dune chane de caractres. Syntaxe $chaine int strlen(string $chaine) Chane de caractres dont vous souhaitez connatre le nombre de caractres. Nombre de caractres de la chane.

7. La manipulation des chanes de caractres

retour

<?php echo strlen("Texte de 22 caracteres"); ?>

Et le rsultat est :
22

substr_count()
Cette fonction compte le nombre doccurrences dune sous-chane dans une autre.

370

Fonctions de gestion des chanes de caractres

Syntaxe $chaine $motif retour

int substr_count(string $chaine, string $motif) Chane de caractres o retrouver le motif. Motif rechercher. Le nombre de fois o le motif apparat.

Listing 7.12 : c06-substrcount.php


<?php echo substr_count("toto","toto"); echo "<br />"; echo substr_count("toto","to"); echo "<br />"; echo substr_count("Je me demande combien il y a de e dans cette phrase","e"); echo "<br />"; ?>

Et voici le rsultat obtenu :


1 2 10

count_chars()
Permet de compter les occurrences des caractres dans une chane de caractres. Syntaxe $chaine $mode mixed count_chars(string $chaine [, int $mode]) Chane dont vous souhaitez compter le nombre doccurrences des caractres. Au choix : 0 (par dfaut) renvoie le nombre doccurrences de tous les caractres ayant un code ASCII compris entre 0 et 255. 1 ne renvoie que les caractres prsents dans la chane. 2 ne renvoie que les caractres absents de la chane. 3 renvoie une chane de caractres des caractres utiliss. 4 renvoie une chane de caractres des caractres inutiliss. Un tableau associatif o les cls sont les codes ASCII des caractres, ou une chane de caractres selon le mode choisi.

7. La manipulation des chanes de caractres

retour

Voici un exemple de script pour commenter cette fonction :


<?php $phrase="Cette phrase contient plusieurs e, t, c et p"; echo "*** Code=0:\n"; print_r(count_chars($phrase));

371

Chapitre 7

La manipulation des chanes de caractres

echo "*** Code=1:\n"; print_r(count_chars($phrase,1)); echo "*** Code=2:\n"; print_r(count_chars($phrase,2)); echo "*** Code=3:\n"; echo count_chars($phrase,3)."\n"; ?>

Dont le rsultat attendu est :


*** Code=0: Array ( [0] => 0 [5] => 0 [10] => 0 [15] => 0 [20] => 0 [25] => 0 [30] => 0 [35] => 0 [40] => 0 [45] => 0 [50] => 0 [55] => 0 [60] => 0 [65] => 0 [70] => 0 [75] => 0 [80] => 0 [85] => 0 [90] => 0 [95] => 0 [100] => 0 [105] => 2 [110] => 2 [115] => 3 [120] => 0 [125] => 0 [130] => 0 [135] => 0 [140] => 0 [145] => 0 [150] => 0 [155] => 0 [160] => 0 [165] => 0 [170] => 0 [175] => 0 [180] => 0 [185] => 0 [190] => 0

[1] => 0 [6] => 0 [11] => 0 [16] => 0 [21] => 0 [26] => 0 [31] => 0 [36] => 0 [41] => 0 [46] => 0 [51] => 0 [56] => 0 [61] => 0 [66] => 0 [71] => 0 [76] => 0 [81] => 0 [86] => 0 [91] => 0 [96] => 0 [101] => [106] => [111] => [116] => [121] => [126] => [131] => [136] => [141] => [146] => [151] => [156] => [161] => [166] => [171] => [176] => [181] => [186] => [191] =>

[2] => 0 [7] => 0 [12] => [17] => [22] => [27] => [32] => [37] => [42] => [47] => [52] => [57] => [62] => [67] => [72] => [77] => [82] => [87] => [92] => [97] => 7 [102] 0 [107] 1 [112] 6 [117] 0 [122] 0 [127] 0 [132] 0 [137] 0 [142] 0 [147] 0 [152] 0 [157] 0 [162] 0 [167] 0 [172] 0 [177] 0 [182] 0 [187] 0 [192]

[3] => 0 [4] => 0 [8] => 0 [9] => 0 0 [13] => 0 [14] => 0 0 [18] => 0 [19] => 0 0 [23] => 0 [24] => 0 0 [28] => 0 [29] => 0 8 [33] => 0 [34] => 0 0 [38] => 0 [39] => 0 0 [43] => 0 [44] => 2 0 [48] => 0 [49] => 0 0 [53] => 0 [54] => 0 0 [58] => 0 [59] => 0 0 [63] => 0 [64] => 0 1 [68] => 0 [69] => 0 0 [73] => 0 [74] => 0 0 [78] => 0 [79] => 0 0 [83] => 0 [84] => 0 0 [88] => 0 [89] => 0 0 [93] => 0 [94] => 0 1 [98] => 0 [99] => 2 => 0 [103] => 0 [104] => 0 [108] => 1 [109] => 3 [113] => 0 [114] => 2 [118] => 0 [119] => 0 [123] => 0 [124] => 0 [128] => 0 [129] => 0 [133] => 0 [134] => 0 [138] => 0 [139] => 0 [143] => 0 [144] => 0 [148] => 0 [149] => 0 [153] => 0 [154] => 0 [158] => 0 [159] => 0 [163] => 0 [164] => 0 [168] => 0 [169] => 0 [173] => 0 [174] => 0 [178] => 0 [179] => 0 [183] => 0 [184] => 0 [188] => 0 [189] => 0 [193] => 0 [194]

=> => => => => => => => => => => => => => => => => => =>

1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

7. La manipulation des chanes de caractres 372

Fonctions de gestion des chanes de caractres

[195] [200] [205] [210] [215] [220] [225] [230] [235] [240] [245] [250] [255]

=> => => => => => => => => => => => =>

0 0 0 0 0 0 0 0 0 0 0 0 0

[196] [201] [206] [211] [216] [221] [226] [231] [236] [241] [246] [251]

=> => => => => => => => => => => =>

0 0 0 0 0 0 0 0 0 0 0 0

[197] [202] [207] [212] [217] [222] [227] [232] [237] [242] [247] [252]

=> => => => => => => => => => => =>

0 0 0 0 0 0 0 0 0 0 0 0

[198] [203] [208] [213] [218] [223] [228] [233] [238] [243] [248] [253]

=> => => => => => => => => => => =>

0 0 0 0 0 0 0 0 0 0 0 0

[199] [204] [209] [214] [219] [224] [229] [234] [239] [244] [249] [254]

=> => => => => => => => => => => =>

0 0 0 0 0 0 0 0 0 0 0 0

) *** Code=1: Array ( [32] => 8 [101] => 7 [111] => 1 [117] => 2 ) *** Code=2: Array ( [0] => 0 [5] => 0 [10] => 0 [15] => 0 [20] => 0 [25] => 0 [30] => 0 [36] => 0 [41] => 0 [47] => 0 [52] => 0 [57] => 0 [62] => 0 [68] => 0 [73] => 0 [78] => 0 [83] => 0 [88] => 0 [93] => 0 [100] => 0 [109] => 0 [121] => 0 [126] => 0 [131] => 0 [136] => 0 [141] => 0 [146] => 0

[44] => 2 [104] => 1 [112] => 3

[67] => 1 [97] => 1 [99] => 2 [105] => 2 [108] => 1 [110] => 2 [114] => 2 [115] => 3 [116] => 6

[1] => 0 [6] => 0 [11] => 0 [16] => 0 [21] => 0 [26] => 0 [31] => 0 [37] => 0 [42] => 0 [48] => 0 [53] => 0 [58] => 0 [63] => 0 [69] => 0 [74] => 0 [79] => 0 [84] => 0 [89] => 0 [94] => 0 [102] => [113] => [122] => [127] => [132] => [137] => [142] => [147] =>

[2] => 0 [7] => 0 [12] => [17] => [22] => [27] => [33] => [38] => [43] => [49] => [54] => [59] => [64] => [70] => [75] => [80] => [85] => [90] => [95] => 0 [103] 0 [118] 0 [123] 0 [128] 0 [133] 0 [138] 0 [143] 0 [148]

[3] => 0 [4] => 0 [8] => 0 [9] => 0 0 [13] => 0 [14] => 0 0 [18] => 0 [19] => 0 0 [23] => 0 [24] => 0 0 [28] => 0 [29] => 0 0 [34] => 0 [35] => 0 0 [39] => 0 [40] => 0 0 [45] => 0 [46] => 0 0 [50] => 0 [51] => 0 0 [55] => 0 [56] => 0 0 [60] => 0 [61] => 0 0 [65] => 0 [66] => 0 0 [71] => 0 [72] => 0 0 [76] => 0 [77] => 0 0 [81] => 0 [82] => 0 0 [86] => 0 [87] => 0 0 [91] => 0 [92] => 0 0 [96] => 0 [98] => 0 => 0 [106] => 0 [107] => 0 [119] => 0 [120] => 0 [124] => 0 [125] => 0 [129] => 0 [130] => 0 [134] => 0 [135] => 0 [139] => 0 [140] => 0 [144] => 0 [145] => 0 [149] => 0 [150]

7. La manipulation des chanes de caractres

=> => => => => => => =>

0 0 0 0 0 0 0 0

373

Chapitre 7

La manipulation des chanes de caractres

[151] [156] [161] [166] [171] [176] [181] [186] [191] [196] [201] [206] [211] [216] [221] [226] [231] [236] [241] [246] [251]

=> => => => => => => => => => => => => => => => => => => => =>

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

[152] [157] [162] [167] [172] [177] [182] [187] [192] [197] [202] [207] [212] [217] [222] [227] [232] [237] [242] [247] [252]

=> => => => => => => => => => => => => => => => => => => => =>

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

[153] [158] [163] [168] [173] [178] [183] [188] [193] [198] [203] [208] [213] [218] [223] [228] [233] [238] [243] [248] [253]

=> => => => => => => => => => => => => => => => => => => => =>

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

[154] [159] [164] [169] [174] [179] [184] [189] [194] [199] [204] [209] [214] [219] [224] [229] [234] [239] [244] [249] [254]

=> => => => => => => => => => => => => => => => => => => => =>

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

[155] [160] [165] [170] [175] [180] [185] [190] [195] [200] [205] [210] [215] [220] [225] [230] [235] [240] [245] [250] [255]

=> => => => => => => => => => => => => => => => => => => => =>

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

) *** Code=3: ,Cacehilnoprstu

strspn()
Cette fonction retourne le nombre de caractres du dbut de la chane passe en premier paramtre, dont tous les caractres sont compris dans la chane fournie en second paramtre.

7. La manipulation des chanes de caractres

Syntaxe $chaine $caracteres $debut $nbCaracteres retour Un exemple :

int strspn(string $chaine, string $caracteres [, int $debut [, int $nbCaracteres]]) Chane tudier. Ensemble de caractres. Indice du premier caractre de $chaine a tudier. Nombre de caractres a partir de $debut sur lesquels faire le compte. Le nombre de caractres du dbut de la chane, dont tous les caractres appartiennent $caracteres.

<?php echo strspn("7490875253 Voila 10 chiffres", "1234567890"); ?>

dont le rsultat est :


10

374

Fonctions de gestion des chanes de caractres

strcspn()
Cette fonction retourne le nombre de caractres du dbut de la chane passe en premier paramtre, dont aucun caractre nest compris dans la chane fournie en second paramtre. Syntaxe $chaine $caracteres $debut $nbCaracteres retour int strcspn(string $chaine, string $caracteres [ int $debut [, int $nbCaracteres]]) Chane tudier. Ensemble de caractres. Indice du premier caractre de $chaine a tudier. Nombre de caractres a partir de $debut sur lesquels faire le compte. Le nombre de caractres du dbut de la chane, dont aucun caractre nappartient $caracteres.

Un exemple :
<?php echo strcspn("22 caracteres avant le: ou ! ou ?", ":!?"); ?>

avec comme rsultat :


22

Fonctions de position
Il est galement utile de pouvoir rcuprer lindex dun caractre dans une chane :

7. La manipulation des chanes de caractres

strpos()
Retourne la position du premier caractre de la premire occurrence dune chane dans une autre, partir dun certain index. Syntaxe $chaine $souschaine $index retour int strpos(string $chaine, string $souschaine [int $index]) Chane de caractres dans laquelle rechercher la sous-chane. Chane de caractres rechercher. Index de la chane partir duquel la recherche doit seffectuer. Lindex du premier caractre de la sous-chane. Retourne FALSE si la sous-chane nest pas trouve.

<?php echo strpos("Index du premier caractre dune chane de". " caractres","caractre");

375

Chapitre 7

La manipulation des chanes de caractres

echo "\n"; echo strpos("Index du premier caractre dune chane de". " caractres","caractre",0); echo "\n"; echo strpos("Index du premier caractre dune chaine de". " caractres","caractre",30); ?>

Voici le rsultat obtenu :


17 17 43

Retour de la fonction Il vaut mieux comparer le rsultat FALSE (en utilisant loprateur ===) avant de se servir de la valeur retourne, car la confusion entre le premier caractre (dindice 0) et la valeur FALSE est possible.

strrpos()
Retourne la position de la dernire occurrence dun caractre dans une chane de caractres. Syntaxe $chaine $caractere int strrpos(string $chaine, char $caractere) Chane dans laquelle rechercher le caractre. Caractre dont on veut lindice. La position de la dernire occurrence du caractre dans la chane.

7. La manipulation des chanes de caractres

retour

<?php echo strrpos("Index du premier caractere dune chaine de caracteres",e); ?>

Voici le rsultat obtenu :


51

7.3.

Comparaison de chanes de caractres

Il est possible de comparer deux chanes de caractres en utilisant simplement loprateur ==. Cependant, il peut tre galement intressant de comparer des chanes semblables laide de fonctions permettant dautres moyens de comparaison que la stricte galit de deux chanes.

376

Comparaison de chanes de caractres

galite des valeurs et des types Si vous souhaitez comparer une variable une chane de caractres en utilisant loprateur ==, assurez-vous que la variable est bien de type string. Vous risqueriez, sinon, davoir des surprises.

Comparaison par ordre alphabtique


Il est ainsi possible de comparer deux chanes selon leur ordre alphabtique.

strcmp()
Compare deux chanes de caractres partir de lordre alphabtique. Syntaxe $chaine1 $chaine2 retour int strcmp(string $chaine1, string $chaine2) Chane comparer. Chane comparer. 1 si la chane 1 est place avant la chane 2 dans lordre alphabtique, 1 dans le cas contraire et 0 si les deux chanes sont identiques.

<?php echo strcmp("abc", "bcd")."\n"; echo strcmp("aa", "aaa")."\n"; echo strcmp("_mot", "mot")."\n"; echo strcmp("mot_", "mot")."\n"; echo strcmp("mot", "mot")."\n"; ?>

7. La manipulation des chanes de caractres

Voici le rsultat obtenu :


-1 -1 -1 1 0

Pour ne comparer que les premiers caractres, il suffit dutiliser la fonction suivante :

strncmp()
Compare les premiers caractres de deux chanes de caractres partir de lordre alphabtique.

377

Chapitre 7

La manipulation des chanes de caractres

Syntaxe $chaine1 $chaine2 $nbCaracteres retour

int strncmp(string $chaine1, string $chaine2, int $nbCaracteres) Chane comparer. Chane comparer. Nombre de caractres comparer. 1 si les $nbCaracteres premiers caractre de chane 1 sont placs avant la chane 2 dans lordre alphabtique, 1 dans le cas contraire et 0 si les $nbCaracteres premiers caractres des deux chanes sont identiques.

<?php echo strncmp("aa", "aaa", 2)."\n"; echo strncmp("aa", "aaa", 3)."\n"; echo strncmp("abcdg", "abcef", 3)."\n"; echo strncmp("abcdg", "abcef", 4)."\n"; ?>

Le rsultat obtenu est alors le suivant :


0 -1 0 -1

strcoll()
Compare deux chanes de caractres selon la configuration locale du serveur. Si la configuration courante est C ou POSIX, alors cette fonction est identique strcmp().

7. La manipulation des chanes de caractres

Syntaxe

int strcoll(string $chaine1, string $chaine2)

Les fonctions strcmp() et strncmp() ont leurs quivalents insensibles la casse ; ce sont les fonctions strcasecmp() et strncasecmp().

strcasecmp()
Compare deux chanes de caractres partir de lordre alphabtique sans tenir compte de la casse. Syntaxe $chaine1 $chaine2 retour int strcasecmp(string $chaine1, string $chaine2) Chane comparer. Chane comparer. 1 si la chane 1 est place avant la chane 2 dans lordre alphabtique, 1 dans le cas contraire et 0 si les deux chanes sont identiques.

378

Comparaison de chanes de caractres

strncasecmp()
Compare les premiers caractres de deux chanes de caractres partir de lordre alphabtique sans tenir compte de la casse. Syntaxe $chaine1 $chaine2 $nbCaracteres retour int strncasecmp(string $chaine1, string $chaine2, int $nbCaracteres) Chane comparer. Chane comparer. Nombre de caractres comparer. 1 si les $nbCaracteres premiers caractre de chane 1 sont placs avant la chane 2 dans lordre alphabtique, 1 dans le cas contraire et 0 si les $nbCaracteres premiers caractres des deux chanes sont identiques.

Un algorithme de "comparaison naturelle" est galement disponible. Voici sa description :

strnatcmp()
Compare deux chanes utilisant un algorithme cens ordonner des chanes de caractres comme le ferait un tre humain. Syntaxe $chaine1 $chaine2 retour int strnatcmp(string $chaine1, string $chaine2) Chane comparer. Chane comparer. 1 si la chane 1 est place avant la chane 2 dans lordre "naturel", 1 dans le cas contraire et 0 si les deux chanes sont identiques.

7. La manipulation des chanes de caractres

Pour mettre en avant la diffrence entre strcmp() et strnatcmp(), le script suivant trie un tableau selon les deux mthodes.
<?php $tableau1 = $tableau2 = array (image5.jpg, image4.jpg, image12.jpg, image8.jpg, image1.jpg, image43.jpg, image14.jpg); echo "Ordre standard:\n"; usort($tableau1, "strcmp"); print_r($tableau1); echo "\nOrdre naturel:\n"; usort($tableau2, "strnatcmp"); print_r($tableau2); ?>

379

Chapitre 7

La manipulation des chanes de caractres

Voici le rsultat obtenu :


Ordre standard: Array ( [0] => image1.jpg [1] => image12.jpg [2] => image14.jpg [3] => image4.jpg [4] => image43.jpg [5] => image5.jpg [6] => image8.jpg ) Ordre naturel: Array ( [0] => image1.jpg [1] => image4.jpg [2] => image5.jpg [3] => image8.jpg [4] => image12.jpg [5] => image14.jpg [6] => image43.jpg )

Une fonction quivalente, mais insensible la casse, existe. Elle sappelle strnatcasecmp().

strnatcasecmp()
7. La manipulation des chanes de caractres
Compare deux chanes utilisant un algorithme cens ordonner des chanes de caractres comme le ferait un tre humain. Cette fonction est insensible la casse. Syntaxe $chaine1 $chaine2 retour int strnatcasecmp(string $chaine1, string $chaine2) Chane comparer. Chane comparer. 1 si la chane 1 est place avant la chane 2 dans lordre "naturel", 1 dans le cas contraire et 0 si les deux chanes sont identiques.

<?php $tableau1 = $tableau2

= array (Image5.jpg, image4.jpg, Image12.jpg, image8.jpg, Image1.jpg, image43.jpg, Image14.jpg); echo "Ordre standard:\n";

380

Comparaison de chanes de caractres

usort($tableau1, "strcmp"); print_r($tableau1); echo "\nOrdre naturel:\n"; usort($tableau2, "strnatcasecmp"); print_r($tableau2); ?>

Voici le rsultat obtenu :


Ordre standard: Array ( [0] => Image1.jpg [1] => Image12.jpg [2] => Image14.jpg [3] => image4.jpg [4] => image43.jpg [5] => Image5.jpg [6] => image8.jpg ) Ordre naturel: Array ( [0] => Image1.jpg [1] => image4.jpg [2] => Image5.jpg [3] => image8.jpg [4] => Image12.jpg [5] => Image14.jpg [6] => image43.jpg )

7. La manipulation des chanes de caractres

Vous pouvez galement utiliser les fonctions min() et max(), dcrites dans le chapitre "PHP et les mathmatiques", pour dterminer la chane de caractres ayant la premire ou la dernire position dans un classement alphabtique dune liste de chanes.

Comparaison orthographique

similar_text()
Permet de comparer deux chanes en estimant leurs ressemblances. Cette fonction est sensible la casse.

381

Chapitre 7

La manipulation des chanes de caractres

Syntaxe $chaine1 $chaine2 $pourcentage retour

int similar_text(string $chaine1, string $chaine2, [double &$pourcentage]) Une des deux chanes comparer. La chane avec laquelle on veut comparer la premire. Si une rfrence est passe en paramtre, la valeur en % y sera dclare. Le nombre de caractres en commun.

<?php $chaine1 = "Une des chaines a comparer"; $chaine2 = "Lautre des chaines a comparer"; echo similar_text($chaine1, $chaine2)."\n"; $pourcentage = 0; echo similar_text($chaine1, $chaine2, &$pourcentage)."\n"; echo $pourcentage."\n"; echo similar_text("aaa", "AAA", &$pourcentage)."\n"; echo $pourcentage."\n"; ?>

Voici le rsultat obtenu : 24 24 85.714285714286 0 0

Mthode utilise La mthode utilise est celle de Oliver [1993] qui est dcrite ladresse suivante : http://citeseer.nj.nec.com/oliver93decision.html. 7. La manipulation des chanes de caractres
Il existe une autre mthode permettant de mesurer la distance entre deux chanes de caractres, cest la distance de Levenshtein. Le calcul est ici moins gourmand que le prcdent.

levenshtein()
Calcule la distance de Levenshtein entre deux chanes de caractres. La distance de Levenshtein se dfinit comme tant le plus petit nombre de caractres remplacer dans la premire chane pour obtenir la seconde. Syntaxe $chaine1 $chaine2 $coutInsert int levenshtein(string $chaine1, string $chaine2 [, int $coutInsert, int $coutRemplace, int $coutSupprime]) Chane comparer. Chane comparer. Cot dune insertion.

382

Comparaison de chanes de caractres

$coutRemplace $coutSupprime retour

Cot dun remplacement. Cot dune suppression. Distance de Levenshtein, ou 1 si lune des deux chanes fait plus de 255 caractres.

<?php $chaine1 = "Une des chanes comparer"; $chaine2 = "Lautre des chanes comparer"; echo levenshtein($chaine1, $chaine2)."\n"; echo levenshtein($chaine1, $chaine2, 2, 3, 1)."\n"; echo levenshtein("aaa", "AAA")."\n"; ?>

Voici le rsultat obtenu :


5 11 3

Comparaison phonique
Les fonctions prsentes ici ne permettent pas une comparaison directe, mais permettent de dfinir une valeur base sur la consonance dun mot.

soundex()
Permet de calculer une valeur partir de la prononciation dune chane de caractres. La particularit de cette valeur est que deux mots ayant la mme consonance auront le mme "soundex". Attention, cette fonction est adapte la prononciation anglaise. Syntaxe $chaine retour string soundex(string $chaine) Chane de caractres dont on veut calculer la valeur soundex. Le "soundex".

7. La manipulation des chanes de caractres

Listing 7.13 : soundex.php


<?php echo echo echo echo echo echo echo echo echo soundex("serial killer"); "<br />"; soundex("seriol quilleur"); "<br />"; soundex("Welcome"); "<br />"; soundex("ouelcome"); "<br />"; soundex("elephant");

383

Chapitre 7

La manipulation des chanes de caractres

echo echo echo echo ?>

"<br />"; soundex("elefant"); "<br />"; soundex("elefante");

Le rsultat de ce script est le suivant :


S642 S642 W425 O425 E415 E415 E415

metaphone()
Cette fonction est trs similaire soundex(). Elle a le mme objectif, mais utilise une reprsentation et un algorithme diffrents. Syntaxe $chaine retour string metaphone(string $chaine) Chane de caractres dont vous souhaitez le "metaphone". Une valeur dpendant de la faon de prononcer la chane de caractres.

Listing 7.14 : metaphone.php


<?php echo echo echo echo echo echo echo echo echo echo echo echo echo ?> metaphone("serial killer"); "<br />"; metaphone("seriol quilleur"); "<br />"; metaphone("Welcome"); "<br />"; metaphone("ouelcome"); "<br />"; metaphone("elephant"); "<br />"; metaphone("elefant"); "<br />"; metaphone("elefante");

7. La manipulation des chanes de caractres

Dont le rsultat est :


SRLKLR SRLKLR WLKM

384

Gestion des caractres spciaux

OLKM ELFNT ELFNT ELFNT

7.4.

Gestion des caractres spciaux

Ajout du caractre dchappement


Il est parfois utile dencoder des chanes de caractres. Cest le cas, par exemple, pour chapper certains caractres spciaux.

addSlashes()
Permet lchappement de certains caractres. Concrtement, il sagit des caractres : , ", \ et NUL (\0). Syntaxe $chaine retour string addSlashes(string $chaine) Chane de caractres modifier. La chane avec les caractres spciaux chapps.

<?php $chaine="Cest \ Cool"; echo $chaine; echo "\n"; echo addSlashes($chaine); ?>

7. La manipulation des chanes de caractres

Voici le rsultat obtenu :


Cest \ Cool C\est \\ Cool

magic_quotes_gpc Par dfaut, les magic quotes (apostrophes magiques) sont actives, cest--dire que les apostrophes sont automatiquement prcdes du signe \ lorsque les valeurs sont passes un script par la mthode GET, POST ou par cookie.
Une fonction trs similaire, appele quoteMeta(), permet galement lchappement de certains caractres.

385

Chapitre 7

La manipulation des chanes de caractres

quoteMeta()
Permet dchapper les caractres : ., \, +, ?, ^, $, [, ], (, ). Syntaxe $chaine retour string quoteMeta(string $chaine) Chane transformer. Chane transforme.

addCSlashes()
Retourne une chane de caractres en ajoutant des \ devant les caractres prciss. Les caractres ayant un code ASCII infrieur 32, ou suprieur 126, sont convertis leur valeur octale. Syntaxe $chaine $listeCaracteres retour string addCSlashes(string $chaine, string $listeCaracteres) Chane de caractres transformer. Liste des caractres chapper. Chane transforme.

7. La manipulation des chanes de caractres

<?php $chaine="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; echo $chaine; echo "\n"; echo addcslashes($chaine,"A..z"); echo "\n"; echo addcslashes($chaine,"G..f"); ?>

Et voici le rsultat obtenu :


ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\a\b\c\d\e\f\g\h\i\j\k\l\m\n \o\p\q\r\s\t\u\v\w\x\y\z ABCDEF\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\a\b\c\d\e\fghijklmnopqrstuvwxyz

Caractres spciaux Le fait dajouter un \ peut transformer certaines caractres en caractres spciaux, cest le cas de 0, a, b, f, n, r, t et v.

Suppression du caractre dchappement


Les fonctions inverses existent bien videmment. Elles permettent de supprimer les \.

386

Gestion des caractres spciaux

stripSlashes()
Retire les slashes ajouts par la fonction addSlashes(). Syntaxe $chaine retour string stripSlashes(string $chaine) Chane de caractres pour laquelle vous souhaitez retirer les \. La chane sans les \ dchappement.

<?php $chaine="Cette chaine contient des et des \."; echo $chaine; echo "\n"; echo addSlashes($chaine); echo "\n"; echo stripSlashes(addslashes($chaine)); ?>

Ce qui donne en retour :


Cette chaine contient des et des \. Cette chaine contient des \ et des \\. Cette chaine contient des et des \.

De la mme manire, le rsultat obtenu par addCSlashes() est obtenu par stripCSlashes().

stripCSlashes()
7. La manipulation des chanes de caractres
Fonction inverse de addCSlashes(). Syntaxe $chaine retour string stripCSlashes(string $chaine) Chane dont vous souhaitez retirer les \ dchappement. Chane sans les \ dchappement.

Dans lexemple suivant, nous ne nous sommes pas mfis des caractres spciaux. Observez le rsultat obtenu :
<?php $chaine="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; echo $chaine; echo "\n"; echo addCSlashes($chaine,"G..f"); echo "\n"; echo stripCSlashes(addCSlashes($chaine,"G..f")); ?>

387

Chapitre 7

La manipulation des chanes de caractres

Rsultat obtenu :
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ABCDEF\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\a\b\c\d\e\fghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZhcdehghijklmnopqrstuvwxyz

Conversion des caractres en code HTML


Dans le cas de lcriture de pages HTML, il peut tre utile de transformer certains caractres spciaux en leurs quivalents HTML. Cest le cas des caractres &, ", , < et >, qui peuvent tre remplacs respectivement par &amp;, &quot;, &apos;, &lt; et &gt;.

htmlSpecialChars()
Retourne une chane de caractres pour laquelle les caractres spciaux de lHTML ont t convertis. Cela ne concerne pas les caractres accentus. Syntaxe $chaine $apostrophes string htmlSpecialChars(string $chaine [, int $apostrophes [, string $encodage]]) Chane de caractres transformer. Au choix : ENT_COMPAT (par dfaut), pour que cette fonction ne transforme que les guillemets et laisse les apostrophes telles quelles. ENT_QUOTES, pour transformer les apostrophes et guillemets. ENT_NOQUOTES, pour ne transformer ni les apostrophes ni les guillemets. $encodage Par dfaut il vaut "ISO-8859-1". La chane transforme. retour

7. La manipulation des chanes de caractres

Utilit Cette fonction est notamment utile pour les forums ou livres dor, par exemple. En effet, si un utilisateur utilise lun de ces caractres, il est souhaitable que ceux-ci rapparaissent tels quels par la suite.
Voici un exemple :

Listing 7.15 : htmlspecialchars.php


<html> <head><title>HTMLSpecialChars</title></head> <body> <p> <?php $chaine = "Un message avec du HTML <i> &, , \"

et des </i>";

388

Gestion des caractres spciaux

echo $chaine."<br />\n"; echo htmlspecialchars($chaine); ?> </p> </body> </html>

Voici le code source obtenu :


<html> <head><title>HTMLSpecialChars</title></head> <body> <p> Un message avec du HTML <i> &, , " et des </i><br /> Un message avec du HTML &lt;i&gt; &amp;, , &quot; et des &lt;/i&gt;</p> </body> </html>

Et, donc, le rsultat du navigateur :


Un message avec du HTML &, , " et des Un message avec du HTML <i> &, , " et des </i>

Une autre fonction trs similaire permet de transformer tous les caractres spciaux en leurs quivalents HTML. Elle sappelle htmlEntities().

htmlEntities()
Retourne une chane de caractres pour laquelle tous les caractres spciaux (y compris les caractres accentus) ont t convertis en leurs quivalents HTML.

7. La manipulation des chanes de caractres

Syntaxe $chaine $apostrophes

string htmlEntities(string $chaine[, int $apostrophes [, string $encodage]]) Chane de caractres transformer. Au choix : ENT_COMPAT (par dfaut), pour que cette fonction ne transforme que les guillemets et laisse les apostrophes telles quelles. ENT_QUOTES, pour transformer les apostrophes et les guillemets. ENT_NOQUOTES, pour ne transformer ni les apostrophes ni les guillemets. Par dfaut, il vaut "ISO-8859-1". La chane transforme.

$encodage retour

Voici le script dexemple :

389

Chapitre 7

La manipulation des chanes de caractres

Listing 7.16 : htmlentities.php


<html> <head><title>HTMLEntities</title></head> <body> <p> <?php $chaine = "Un message avec du HTML <i> &, , \" echo $chaine."<br />\n"; echo htmlEntities($chaine); ?> </p> </body> </html>

et des </i>";

Voici le rsultat obtenu lcran :


Un message avec du HTML &, , " et des Un message avec du HTML <i> &, , " et des </i>

et voici le code source correspondant :


<html> <head><title>HTMLEntities</title></head> <body> <p> Un message avec du HTML <i> &, , " et des </i><br /> Un message avec du HTML &lt;i&gt; &amp;, &egrave;, &quot; &lt;/i&gt;</p> </body> </html>

et des

7. La manipulation des chanes de caractres

get_html_translation_table()
Permet de placer, dans un tableau associatif, les tables de conversion des caractres spciaux en leurs quivalents HTML, utilises par les fonctions htmlSpecialChars() et htmlEntities(). Syntaxe $table array get_html_translation_table(int $table [, int $apostrophes]) Table rcuprer, au choix : HTML_ENTITIES, pour la table utilise par htmlEntities(). HTML_SPECIALCHARS, pour la table utilise htmlSpecialChars(). Au choix : ENT_COMPAT (par dfaut), pour que cette fonction ne transforme que les guillemets et laisse les apostrophes telles quelles.

par

$apostrophes

390

Gestion des caractres spciaux

ENT_QUOTES, pour transformer les apostrophes et les guillemets. ENT_NOQUOTES, pour ne transformer ni les apostrophes ni les guillemets. retour Un tableau associatif ayant pour cls les caractres spciaux, et pour valeurs leurs quivalents HTML.

Voici un script dexemple :

Listing 7.17 : get_html_translation_table.php


<?php print_r(get_html_translation_table(HTML_ENTITIES)); print_r(get_html_translation_table(HTML_SPECIALCHARS)); ?>

dont le rsultat est :


Array ( [ ] => &nbsp; [] => &iexcl; [] => &cent; [] => &pound; [] => &curren; [] => &yen; [] => &brvbar; [] => &sect; [] => &uml; [R] => &copy; [] => &ordf; [ ] => &laquo; [w] => &not; [-] => &shy; [T] => &reg; [-] => &macr; [] => &deg; [] => &plusmn; [_] => &sup2; [`] => &sup3; [] => &acute; [] => &micro; [] => &para; [] => &middot; [q] => &cedil; [^] => &sup1; [] => &ordm; [ ] => &raquo; [] => &frac14; [] => &frac12; [] => &frac34; [] => &iquest; [] => &Agrave;

7. La manipulation des chanes de caractres 391

Chapitre 7

La manipulation des chanes de caractres

[] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [v U] [] [] [] ] [Y [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []

=> => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => => =>

&Aacute; &Acirc; &Atilde; &Auml; &Aring; &AElig; &Ccedil; &Egrave; &Eacute; &Ecirc; &Euml; &Igrave; &Iacute; &Icirc; &Iuml; &ETH; &Ntilde; &Ograve; &Oacute; &Ocirc; &Otilde; &Ouml; &times; &Oslash; &Ugrave; &Uacute; &Ucirc; &Uuml; &Yacute; &THORN; &szlig; &agrave; &aacute; &acirc; &atilde; &auml; &aring; &aelig; &ccedil; &egrave; &eacute; &ecirc; &euml; &igrave; &iacute; &icirc; &iuml; &eth; &ntilde; &ograve; &oacute; &ocirc;

7. La manipulation des chanes de caractres 392

Gestion des caractres spciaux

[] [] [] [] [] [] [] [] [y ] [] [&] ["] [<] [>] ) Array ( [&] ["] [<] [>] )

=> => => => => => => => => => => => => =>

&otilde; &ouml; &divide; &oslash; &ugrave; &uacute; &ucirc; &uuml; &yacute; &thorn; &amp; &quot; &lt; &gt;

=> => => =>

&amp; &quot; &lt; &gt;

nl2br()
Retourne une chane de caractres dans laquelle les retours chariot ont t transforms en balises de retours de lignes HTML (<br />). Syntaxe $chaine retour string nl2br(string $chaine) Chane de caractres transformer. La chane transforme.

7. La manipulation des chanes de caractres

Listing 7.18 : nl2br.php


<html> <head><title>nl2br</title></head> <body> <p> <?php $chaine = "Un message avec des retours de ligne"; echo $chaine."<br />\n"; echo nl2br($chaine); ?> </p> </body> </html>

393

Chapitre 7

La manipulation des chanes de caractres

Voici la sortie lcran :


Un message avec des retours de ligne Un message avec des retours de ligne

Et voici le code HTML gnr :


<html> <head><title>nl2br</title></head> <body> <p> Un message avec des retours de ligne<br /> Un message avec <br /> des retours <br /> de ligne</p> </BODY> </HTML>

Modification depuis PHP 4.3.2 Le comportement de cette fonction a lgrement t modifi pour supporter tout types de retours la ligne. Danciens scripts peuvent donc se comporter diffrement sur une version rcente de PHP.

7. La manipulation des chanes de caractres

Conversion dun alphabet un autre

convert_cyr_string()
Retourne une chane convertie dun alphabet cyrillique vers un autre. Syntaxe $chaine $depuis $vers retour string convert_cyr_string(string $chaine, string $depuis, string $vers) Chane transformer. Alphabet cyrillique de dpart. Alphabet cyrillique voulu. La chane de caractres transforme.

Les valeurs de $depart et $vers sont prendre parmi les suivantes :

394

Manipulation des balises HTML

Tableau 7.3 : Codes des alphabets cyrilliques


Code k w i a d m Dsignation koi8-r windows-1251 iso8859-5 x-cp866 x-cp866 x-mac-cyrillic

hebrev()
Retourne un texte converti de lhbreu en texte lisible. Cette fonction naffecte, hormis les caractres de ponctuation, que les caractres dont le code ASCII est compris entre 224 et 251. Syntaxe $chaineHebreu retour string hebrev(string $chaineHebreu [, int $caracteresParLigne]); Chane transformer. La chane transforme.

$caracteresParLigne Nombre de caractres maximum par ligne.

hebrevc()
Cette fonction a le mme effet que hebrev(), mais transforme, en plus, les caractres \n en <br />\n. Syntaxe $chaineHebreu retour string hebrevc(string $chaineHebreu [, int $caractresParLigne]); Chane de caractres transformer. La chane transforme.

7. La manipulation des chanes de caractres

$caracteresParLigne Nombre de caractres maximum par ligne.

7.5.

Manipulation des balises HTML

Une fonction trs utile permet de supprimer les balises PHP et HTML pour, par exemple, retirer les balises ajoutes par des visiteurs dun forum. Elle sappelle strip_tags().

395

Chapitre 7

La manipulation des chanes de caractres

strip_tags()
Retourne une chane de caractres pour laquelle les balises PHP et HTML ont t supprimes. Syntaxe $chaine $balisesPermises retour string strip_tags(string $chaine[, string $balisesPermises]) Chane de caractres transformer. Chane compose de la concatnation des balises HTML ne pas supprimer. La chane transforme.

Voici un petit exemple :


<?php $chaine="Du texte avec <b>du gras</b>, <i>de litalique</i> et du <u>soulign&eacute;</u>"; echo $chaine."\n<br />"; echo strip_tags($chaine)."\n<br />"; echo strip_tags($chaine,"<b>")."\n<br />"; echo strip_tags($chaine,"<b><u>")."\n<br />"; ?>

dont voici le rsultat :


Du texte <br />Du <br />Du <br />Du <br /> avec <b>du texte avec texte avec texte avec gras</b>, <i>de litalique</i> et du <u>soulign&eacute;</u> du gras, de litalique et du soulign&eacute; <b>du gras</b>, de litalique et du soulign&eacute; <b>du gras</b>, de litalique et du <u>soulign&eacute;</u>

7. La manipulation des chanes de caractres

Amlioration depuis PHP 4.3.2 Cette fonction a t amliore et gre mieux les signes < et > qui ne sont pas des balises.

get_meta_tags() (ne fonctionne pas sous Windows)


Permet dextraire les balises dune chane de caractres, et de les mettre dans un tableau. Syntaxe $nomFichier $cheminInclusion retour array get_meta_tags(string $nomFichier [, boolean $cheminInclusion]) Nom du fichier traiter. TRUE si le fichier doit tre recherch dans les chemins standard dinclusion. Tableau associatif ayant pour cls les noms des balises "meta" et, pour valeurs, les contenus des attributs "content" de ces mmes balises.

396

Manipulation des balises HTML

Voici un script dexemple suivi du fichier de test :

Listing 7.19 : get_meta_tags.php


<?php $tableau = get_meta_tags("test.html"); print_r($tableau); ?>

Le fichier de test :

Listing 7.20 : test.html


<head> <meta name="author" content="Damien, Laurent, PEM et Thomas"> <meta name="tags" content="Livre PHP"> </head>

Et le rsultat obtenu :
Array ( [author] => Damien , Laurent, PEM et Thomas [tags] => Livre PHP )

Suppression des espaces


Certaines fonctions permettent deffacer les espaces superflues en dbut et/ou fin de chanes de caractres.

7. La manipulation des chanes de caractres

trim()
Retourne une chane de caractres sans les espaces (ou autres caractres) de dbut et de fin. Syntaxe $chaine $listeCaracteres retour string trim(string $chaine [, string $listeCaracteres]) Chane de caractres transformer. Caractres supprimer (cette option nexiste que depuis la version 4.1.0 de PHP). La chane transforme.

Par dfaut, voici un tableau des caractres supprims :

397

Chapitre 7

La manipulation des chanes de caractres

Tableau 7.4 : Caractres supprims par dfaut


Caractre \0 \t \n \x0B \r (espace) Code ASCII (en dcimal puis hexadcimal) 0 (0x00) 9 (0x09) 10 (0x0A) 11 (0x0B) 13 (0x0D) 32 (0x20) Description Caractre NUL. Tabulation horizontale. Nouvelle ligne. Tabulation verticale. Retour chariot. Caractre despacement.

Voici un script dexemple :

Listing 7.21 : trim.php


<?php $chaine="\t\t \t Le texte important \t\t"; echo "Chane de dpart:\n"; echo $chaine."\n"; echo "Chane aprs avoir utilis la fonction trim() sans paramtre:\n"; echo trim($chaine)."\n"; echo "Chane aprs avoir utilis la fonction trim() avec paramtre:\n"; echo trim($chaine,"\t")."\n"; ?>

7. La manipulation des chanes de caractres

Et voici le rsultat obtenu (pour quil soit lisible, nous avons remplac manuellement les tabulations par \t :
Chane de dpart: \t\t \t Le texte important \t\t Chane aprs avoir utilis la fonction trim() sans paramtre: Le texte important Chane aprs avoir utilis la fonction trim() avec paramtre: \t Le texte important

398

Manipulation des balises HTML

ltrim()
Retourne une chane de caractres dans laquelle toutes les espaces (ou autres caractres) de dbut de chane ont t supprimes. Syntaxe $chaine $listeCaracteres retour string ltrim(string $chaine [, string $listeCaracteres]) Chane de caractres transformer. Caractres supprimer (cette option nexiste que depuis la version 4.1.0 de PHP). La chane transforme.

rtrim()
Retourne une chane de caractres dans laquelle toutes les espaces de fin de chane ont t supprimes. Syntaxe $chaine $listeCaracteres retour string ltrim(string $chaine[, string $listeCaracteres]) Chane de caractres transformer. Caractres supprimer (cette option nexiste que depuis la version 4.1.0 de PHP). La chane transforme.

rtrim() possde un alias appel chop().

Modication de casse
Pour changer la casse des caractres, il existe quatre fonctions strToUpper(), strToLower(), ucFirst() et enfin ucWords(). Un script regroupant ces quatre fonctions sera prsent aprs le dtail de celles-ci.

7. La manipulation des chanes de caractres

strToUpper()
Retourne une chane dans laquelle tous les caractres ont t mis en majuscules. Syntaxe $chaine retour string strToUpper(string $chaine) Chane de caractres transformer. La chane transforme en majuscules.

399

Chapitre 7

La manipulation des chanes de caractres

strToLower()
Retourne une chane dans laquelle tous les caractres ont t mis en minuscules. Syntaxe $chaine retour string strToLower(string $chaine) Chane de caractres transformer. La chane transforme en minuscules.

ucFirst()
Retourne une chane de caractres dans laquelle le premier caractre de la chane a t mis en majuscule (sans que les autres ne soient changs). Syntaxe $chaine retour string ucFirst(string $chaine) Chane de caractres transformer. La chane transforme.

ucWords()
Retourne une chane de caractres dans laquelle le premier caractre de chacun des mots a t mis en majuscule (sans que les autres ne soient changs). Syntaxe $chaine retour string ucWords(string $chaine) Chane de caractres transformer. La chane transforme.

7. La manipulation des chanes de caractres

Voici quelques lignes de code prsentant ces fonctions :

Listing 7.22 : majuscules.php


<?php $chaine="cette ChaiNe serA transFormee."; echo strtolower($chaine)."<br />\n"; echo strtoupper($chaine)."<br />\n"; echo ucfirst($chaine)."<br />\n"; echo ucwords($chaine)."<br />\n"; ?>

Et voici le rsultat obtenu :


cette CETTE Cette Cette chaine CHAINE ChaiNe ChaiNe sera SERA serA SerA transformee. TRANSFORMEE. transFormee. TransFormee.

400

Insertion de motifs

7.6.

Insertion de motifs

chunk_split()
Retourne une chane de caractres dans laquelle un motif (par dfaut, un retour la ligne) a t insr espaces rguliers. Syntaxe $chaine $pas $separateur retour string chunck_split(string $chaine [, int $pas [, string $separateur]]) Chane de caractres transformer. Nombre de caractres aprs lesquels insrer le sparateur. (par dfaut 73). Caractres utiliss pour sparer deux blocs. La chane transforme.

Voici un script dexemple (trs simple) :

Listing 7.23 : chunk_split


<?php echo chunk_split("abcdefghijklmnopqrstuvwxyz0123456789",6,"<br />\n"); echo chunk_split("a1b2233e34",2,":"); ?>

Et le rsultat obtenu :
abcdef ghijkl mnopqr stuvwx yz0123 456789 a1:b2:23:3e:34:

7. La manipulation des chanes de caractres

wordWrap()
Permet dinsrer des coupures rgulirement. Syntaxe $chaine $largeur $cassure $coupure retour string wordWrap(string $chaine [, int $largeur [, string $cassure [, bool $coupure]]]) Chane de caractres transformer. Nombre de caractres aprs lesquels insrer les caractres de cassure (73 par dfaut). Chane de caractres servant la cassure (\n par dfaut). Indique si un mot doit tre ou non coup. La chane de caractres transforme.

401

Chapitre 7

La manipulation des chanes de caractres

str_pad()
Permet de complter une chane de caractres par un motif. Syntaxe $chaine $longueurFinale $motif $alignement string str_pad(string $chaine, int $longueurFinale [, string $motif [, int $alignement]]) Chane de caractres transformer. Longueur que fera la chane de caractres aprs transformation. Motif pour le remplissage (caractre despacement par dfaut). Au choix : STR_PAD_RIGHT (par dfaut), si le motif doit tre rpt droite de la chane. STR_PAD_LEFT, si le motif doit tre rpt gauche de la chane. STR_PAD_BOTH, si le motif doit tre rpt de part et dautre de la chane. retour La chane de caractres transforme.

Voici un script dexemple trs simple :

Listing 7.24 : str_pad.php


<?php echo echo echo echo ?> "[".str_pad("Cool", "[".str_pad("Cool", "[".str_pad("Cool", "[".str_pad("Cool", 10)."]\n"; 10, " ", STR_PAD_LEFT)."]\n"; 10, " ", STR_PAD_BOTH)."]\n"; 10, "-=", STR_PAD_BOTH)."]\n";

Et le rsultat obtenu :

7. La manipulation des chanes de caractres

[Cool ] [ Cool] [ Cool ] [-=-Cool-=-]

7.7.

Fusion et dcoupe

implode()
Permet, partir dun tableau, de reconstituer une chane de caractres.

402

Fusion et dcoupe

Syntaxe $entreElements $tableau retour

string implode([string $entreElements,] array $tableau) Chane de caractres placer entre deux lments du tableau. Chane vide par dfaut depuis PHP 4.3.0. Tableau de chanes de caractres. La chane de caractres reconstitue.

Listing 7.25 : explode.php


<?php print_r(explode("\n","Ceci\nest\nune\nphrase en plusieurs\nlignes")); print(implode(" ", explode("\n","Ceci\nest\nune\nphrase en plusieurs\nlignes"))); ?>

Voici le rsultat de ce script :


Array ( [0] => Ceci [1] => est [2] => une [3] => phrase en plusieurs [4] => lignes ) Ceci est une phrase en plusieurs lignes

explode()
Permet de retourner un tableau contenant les morceaux de chanes spars par un dlimiteur dfini par le programmeur. Syntaxe $separateur $chaine $limite retour array explode(string $separateur, string $chaine [, int $limite]) Chane de caractres sparant les diffrents blocs. Chane de caractres transformer. Nombre maximal de blocs, le restant tant mis dans le dernier bloc. Le tableau index en question.

7. La manipulation des chanes de caractres

strtok()
Permet de parcourir une chane morceau par morceau, par appels successifs la fonction.

403

Chapitre 7

La manipulation des chanes de caractres

Syntaxe $chaine $separateur

string strtok(string $chaine, string $separateur) Chane de caractres parcourir. Dfinit les caractres sparant deux morceaux ; nimporte lequel des caractres de sparation est considr comme une coupure entre deux sous-chanes. Un des morceaux.

retour

Voici quelques exemples :

Listing 7.26 : strtok.php


<?php //exemple 1 $sousChaine=strtok("Element 1|Element 2|Element 3","|"); while ($sousChaine) { echo $sousChaine."<br />\n"; $sousChaine=strtok("|"); } //exemple 2 $sousChaine=strtok("Element 1|Element 2|Element 3"," |"); while ($sousChaine) { echo $sousChaine."<br />\n"; $sousChaine=strtok(" |"); } //exemple 3 echo strtok("Element 1|Element 2|Element 3","|")."<br />\n"; echo strtok(" ")."<br />\n"; echo strtok("n")."<br />\n"; ?>

Et voici le rsultat :

7. La manipulation des chanes de caractres

Element Element Element Element 1 Element 2 Element 3 Element Element 2|Eleme

1 2 3

404

Fusion et dcoupe

Autres...

str_repeat()
Permet de rpter une chane. Syntaxe $chaine $nb retour string str_repeat(string $chaine, int $nb) Chane de caractres rpter. Nombre de fois o la chane doit tre rpte. La chane de caractres rpte.

Voici un code dexemple :

Listing 7.27 : str_repeat.php


<?php echo str_repeat(":-",20); echo str_repeat(":-) ",10); ?>

Et le rsultat correspondant :
:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-::-) :-) :-) :-) :-) :-) :-) :-) :-) :-)

strrev()
Retourne une chane de caractres dans laquelle lordre des caractres a t invers. Syntaxe $chaine retour Voici un exemple :
<?php $chaine="Et se resservir ivresse reste"; echo $chaine."<br />\n"; echo strrev($chaine)."<br />\n"; function estUnPalindrome($chaine) { return ($chaine==strrev($chaine)) ? "$chaine est un palindrome" : "$chaine nest pas un palindrome"; }

7. La manipulation des chanes de caractres

string strrev(string $chaine) Chane retourner. Chane inverse.

405

Chapitre 7

La manipulation des chanes de caractres

echo echo echo echo echo ?>

estUnPalindrome("ici")."<br />\n"; estUnPalindrome("chocolat")."<br />\n"; estUnPalindrome("radar")."<br />\n"; estUnPalindrome("rotor")."<br />\n"; estUnPalindrome("voiture")."<br />\n";

dont voici le rsultat :


Et se resservir ivresse reste etser esservi rivresser es tE ici est un palindrome chocolat nest pas un palindrome radar est un palindrome rotor est un palindrome voiture nest pas un palindrome

str_rot13()
Effectue une permutation circulaire sur les lettres de lalphabet, chacune des lettres tant dcale de treize places ; ainsi a deviendra n. Syntaxe $chaine retour string str_rot13(string $chaine) Chane de caractres transformer. Chane de caractres transforme.

Voici un script dexemple :

7. La manipulation des chanes de caractres

Listing 7.28 : str_rot13.php


<?php echo str_rot13("abcdefghijklmnopqrstuvwxyz")."\n"; echo str_rot13("ABCDEFGHIJKLMNOPQRSTUVWXYZ")."\n"; echo str_rot13(str_rot13("abcdefghijklmnopqrstuvwxyz"))."\n"; ?>

dont le rsultat est :


nopqrstuvwxyzabcdefghijklm NOPQRSTUVWXYZABCDEFGHIJKLM abcdefghijklmnopqrstuvwxyz

Cryptage Mme si cela pourrait ressembler une fonction de cryptage, il nen est rien vu que cette fonction est trs facilement rversible (il suffit de lappliquer elle-mme).

406

Fusion et dcoupe

Somme de contrle et cryptage

crc32()
Calcul dune somme de contrle sur 32 bits de la chane de caractres. Ce calcul est particulirement utile pour vrifier quune chane de caractres na pas t altre (suite une dficience logicielle ou matrielle, ou encore un acte de malveillance). Syntaxe $chaine retour Voici un exemple : int crc32(string $chaine) Chane dont vous souhaitez la "checksum". Checksum sur 32 bits.

Listing 7.29 : crc32.php


<?php echo echo echo echo echo ?> crc32("Chaine de caracteres"); "<br />\n"; crc32("Chaine"); "<br />\n"; crc32("Test");

dont le rsultat serait :


169821353 -1820961062 2018365746

7. La manipulation des chanes de caractres

md5()
Retourne une version crypte dune chane de caractres base sur le calcul du md5 (chane hexadcimale de 32 caractres). Syntaxe $chaine retour string md5(string $chaine) Chane de caractres dont vous souhaitez calculer le md5. md5 de la chane.

Listing 7.30 : md5.php


<?php echo md5("Calcul de md5"); echo "<br />\n"; echo md5("Un autre calcul de md5"); ?>

407

Chapitre 7

La manipulation des chanes de caractres

dont le rsultat est :


15c620ee8e52f6143383138a079bf54b 05c411550c749adc841fa0f2f9a2cc13

crypt()
Retourne une version crypte dune chane de caractres base sur la fonction dencryptage DES. Syntaxe $chaine $sel string crypt(string $chaine [, string $sel]) Chane dont vous souhaitez le cryptage. Chane de deux caractres permettant de calculer la cl (si aucune nest fournie, PHP se charge den crer une alatoirement). Pour comparer une chane une chane crypte, vous devrez utiliser comme valeurs les deux premiers caractres de la chane crypte (ou la chane crypte entire, sachant que seuls les deux premiers caractres seront pris en compte). Cl obtenue partir de la chane de caractres et du sel.

Retour

Listing 7.31 : crypt.php


<?php $motDePasseInitiale = "motDePasse"; $cle = crypt($motDePasseInitiale); echo $cle."<br />\n"; $motDePassePropose = "motDePasse"; if (crypt($motDePassePropose, $cle) == $cle) echo "Le mot de passe est bon"; else echo "Le mot de passe est faux"; ?>

7. La manipulation des chanes de caractres

Le rsultat est :
t.Gvi9zyHUxp2 Le mot de passe est bon

Cryptologie Les fonctions md5() et crypt() sont de vritables fonctions de cryptage. De ce fait, elles ne sont pas rversibles. La comparaison dune chane de caractres avec une autre stocke sous sa forme crypte doit toujours se faire en cryptant la chane fournie, et en comparant le rsultat obtenu avec la version stocke (et non en dcryptant la version stocke et en comparant le rsultat avec la chane fournie). Pour la fonction crypt(), qui ncessite un paramtre supplmentaire, vous devrez utiliser la version crypte, comme cela est fait dans lexemple prcdent.

408

Expressions rgulires

7.8.

Expressions rgulires

Une expression rgulire sert faire lanalyse lexicale (parser) dune chane de caractres. Elle va servir, par exemple, reprer une valeur dans une chane, ou encore reprer des sous-chanes particulires. Pour cela, il va falloir dfinir un motif que lon appelle expression rgulire. Il existe deux normes pour dfinir une expression rgulire, Perl et POSIX. Entre Perl et POSIX, les diffrences sont minimes. Si vous connaissez les expressions rgulires du monde UNIX, alors vous connaissez dj la norme POSIX.

Perl
Gnralits La plus simple
La plus simple des expressions rgulires est une sous-chane de caractres compose de chiffres, de lettres et despaces. Lexpression rgulire "morceau rechercher" pourra servir rechercher la sous-chane "morceau rechercher" dans une chane.

Les mtacaractres
Le point
Un caractre trs utile est le point ".". Dans une expression rgulire, il remplace nimporte quel caractre. Par exemple, "PHP. est la dernire version" est une expression regulire pour "PHP3 est la dernire version" ou "PHP4 est la dernire version", mais ne fonctionnera pas pour "PHP 10 est la dernire version", car 10 est sur deux caractres. (Inversement "PHP.. est la dernire version" fonctionnera pour la version 10, mais pas pour les versions 3 et 4.) Utiliser le point tel quel peut poser problme si lon veut rechercher le caractre point, et uniquement celui-ci. En effet, pour rechercher "3.14", il ne faudra pas crire "3.14", sans quoi les expressions "3F14", "3214", "3:14" seront reconnues par cette expression rgulire. Pour utiliser le caractre point, il faut le faire prcder du caractre dchappement: "\". Pour rechercher "3.14" il faut donc crire "3\.14".

7. La manipulation des chanes de caractres

Le point dinterrogation
Le point dinterrogation permet dindiquer la prsence dau plus une occurrence dun caractre. Le point dinterrogation est mettre aprs le caractre en question. Voici quelques exemples : "chanes? de caractres" reconnatra "chanes de caractres" et "chane de caractres". "points? et interrogations?" permettra de reconnatre "points et interrogations" "points et interrogation", "point et interrogations" et "point et interrogation".

409

Chapitre 7

La manipulation des chanes de caractres

Pour utiliser le caractre ? en tant que simple caractre (et non comme mtacaractre), il faut le faire prcder de \.

Le signe plus
Le signe plus (+) permet dindiquer la prsence dune ou plusieurs occurrences dun caractre. Le signe plus est mettre aprs le caractre en question. Voici quelques exemples : "Whaoo+" reconnatra "Whaoo", "Whaooo", "Whaoooo" mais pas "Whao". "coo+l" servira pour reconnatre "cool", "coool", "cooooooool" mais pas "col". Pour utiliser le caractre + en tant que simple caractre (et non comme mtacaractre), il faut le faire prcder de \.

Le signe multiplier
Le signe multiplier (*)permet dindiquer la prsence daucune, dune ou de plusieurs occurrences dun caractre. Le signe multiplier est mettre aprs le caractre en question. Voici quelques exemples: "Whao*" reconnatra "Wha", "Whao", "Whaoo" "cooo*l" servira pour reconnatre "cool", "coool", "cooooooool" Pour utiliser le caractre * en tant que simple caractre (et non comme mtacaractre), il faut le faire prcder de \.

Combinaison de mtacaractres
Le point peuttre combin avec les signes ?, + ou *. Cela permettra dindiquer, par exemple, la prsence de nimporte quel caractre au moins une fois dans le cas du signe +. Voici quelques exemples :

7. La manipulation des chanes de caractres

"Cest .*bien" servira pour "Cest trs bien", "Cest vraiment bien", "Cest rien bien" et mme "Cest bien".

Exemples
Voici une srie dexemples. Les expressions rgulires peuvent vite devenir complexes lire ; il suffit de procder par tapes pour viter les erreurs :

Tableau 7.5 : Exemples dexpressions rgulires


Expression a.z Dfinition Caractre a suivi dun seul caractre suivi de z Exemples reconnus az abz a_z azz a.z Exemples non reconnus az abcz a_-z abz

a\.z

Caractre a suivi du caractre . suivi de z

410

Expressions rgulires

Expression a.+z

Dfinition Caractre a suivi dau moins un caractre suivi de z Caractre a suivi dau moins un caractre . suivi de z Caractre a suivi dau moins un caractre + suivi de z Caractre a suivi dun ou daucun caractre b puis dun caractre c ou plus, puis dventuellement 1 ou plusieurs d puis dun e

Exemples reconnus abz abcz azzz a.z a..z az a+z a++z a+++z abcde acde abccccccde abce abccccce abcddddde

Exemples non reconnus az

a\.+z

az

a\++

az

ab?c+d*e

bcde abcd abde abbcde

Pour affiner la recherche, il est possible de dfinir certains types de caractres.

Tableau 7.6 : Ensembles de caractres


Notation \d \D \w \W \s \S \b \B \nnn Dfinition Tout caractre numrique (0, 1, 2, 3, 4, 5, 6, 7, 8, 9). Tout caractre non numrique. Tout caractre alphanumrique et le signe soulign _. Tout caractre qui nest pas alphanumrique ni le caractre soulign _. Tous les caractres despacement (espace, tabulation, retour chariot) et tout autre caractre qui nutiliserait pas dencre sur une imprimante. Tous les caractres qui ne sont pas des caractres despacement. Tous les caractres qui entourent un mot (caractres despacement, dbut et fin de ligne, ponctuation). Lensemble des caractres qui ne sont pas dans \b. Permet de dfinir un caractre par son code ASCII en base 8.

7. La manipulation des chanes de caractres

Voici une nouvelle srie dexemples illustrant ce que lon peut dfinir avec ces ensembles de caractres.

411

Chapitre 7

La manipulation des chanes de caractres

Tableau 7.7 : Exemples


Expression \w+@\w+\.com Dfinition Une srie de caractres alphanumriques (ou _) puis le signe @ puis une autre srie de caractres alphanumrique (ou _) suivi de .com. Un nombre cinq chiffres. Exemples reconnus Exemples non reconnus

thomas@toutestfacile thomas@toutestfacile.fr .com thomas@toutestfacile toto.com

\d\d\d\d\d\ \b\d\w\D\w\ d\s\W\d

01234 34534

0123 abcde 0a1b1 -2 0abc1 d2

Le dbut de ligne suivi dun 0abc1 -2 chiffre puis dun caractre 0_aa1 %2 alphanumrique, puis dun caractre qui nest pas un chiffre, puis dun caractre alphanumrique, puis dun chiffre, dun caractre despacement, dun caractre non alphanumrique et enfin dun chiffre.

Il est galement possible de prciser les nombres minimum et maximum doccurrences dun caractre en utilisant une notation entre accolades, les deux valeurs tant spares par une virgule.
ab{2,4}c signifie : un caractre a suivi de deux quatre caractres b puis du caractre c.

Pour permettre une alternative, il suffit dutiliser le caractre |.


ab|ac signifie : soit la chane ab, soit la chane ac et aucune autre.

7. La manipulation des chanes de caractres

Enfin, pour permettre certains caractres ou une certaine plage de caractres, on peut utiliser des crochets.
a[bcde]f permettra de reconnatre abf, acf, adf et aef mais pas abcf par exemple.

Pour dfinir une certaine plage de caractres, il suffit de placer un signe entre les caractres dlimitant la plage.
a[be]f est quivalent lexemple prcdent.

Pour ajouter le signe la liste des caractres possibles, il suffit de le placer juste avant le crochet fermant.
a[be]f permettra de reconnatre abf, acf, adf, aef et af.

Lutilisation des crochets peut galement permettre dexclure certains caractres en utilisant le caractre dexclusion ^.
[^bc]oule permettra de reconnatre foule, roule mais pas boule ni coule.

lintrieur des crochets, les rgles dchappement ne sappliquent pas de la mme manire ; seuls les caractres [, ] et \ doivent tre prcd du signe \.

412

Expressions rgulires

Tableau 7.8 : Dautres exemples


Expression [02468]{3,5} Dfinition Un nombre de trois cinq caractres compos de chiffres pairs. Exemples reconnus 24804 8602 666 a_111 g_753 Exemples non reconnus 135 1222 20 7_765 4_a33

[az]_[09]{3,3} Une lettre minuscule suivie du signe _ puis dexactement trois chiffres. [\[\]\\]+ Une composition de caractres [, ] et \. Un ou plusieurs caractres alphanumriques ou ., _, suivi de @, de un ou plusieurs caractres alphanumriques, dun point puis de deux ou trois lettres.

\[]\][]\][ [\] \\\]][[[

[a]

[azAZ09._] +@[azAZ09]+ \.[azAZ]{2,3}

livrephp@toutestfacile.com @toutestfacile.com manuel@brazil.br toto@_.com thomas.heute@toutestfacile .com

Dbut et n de ligne
En dehors des crochets, le caractre ^ permet de dfinir le dbut dune chane. Le caractre $, lui, dsigne la fin dune chane.
abc reconnatra "abc", "dabc", "dabce". ^abc reconnatra "abc" et "abcd".

7. La manipulation des chanes de caractres

^abc$ reconnatra "abc" (uniquement).

Les options
Les expressions rgulires Perl sont gnralement crites entre deux slashes /. Les caractres avant le premier slash et ceux aprs le dernier permettent de spcifier quelques options. Le caractre avant le premier slash est sans effet avec les fonctions PHP. Celui situ aprs le dernier slash peut tre par exemple un :
j j j

i afin de prciser que la recherche doit tre insensible la casse. s afin que le mtacaractre . concerne galement les retours la ligne. Dautres valeurs encore.

413

Chapitre 7

La manipulation des chanes de caractres

Les fonctions PHP Filtrage par expression rgulire

preg_grep()
Retourne un tableau ne contenant que les lments vrifiant une expression rgulire. Syntaxe $expReg $chaines retour array preg_grep(string expReg, array $chaines) Lexpression rgulire filtrante. Chanes de caractres vrifier. Tableau sans les valeurs ne vrifiant pas lexpression rgulire.

Listing 7.32 : preg_grep.php


<?php $chaines = array( "toto@blabla.fr", "toto$blabla.fr", "toto$blabla.com", "toto_titi@blabla.com", ); print_r(preg_grep("/[a-zA-Z0-9._-]+@[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/", $chaines)); ?>

dont le rsultat est :


Array ( [0] => toto@blabla.fr [3] => toto_titi@blabla.com )

7. La manipulation des chanes de caractres

Substitution par expression rgulire

preg_replace()
Recherche une portion de chane de caractres correspondant une expression rgulire et la remplace.

414

Expressions rgulires

Syntaxe $motif

mixed preg_replace(mixed $motif, mixed $remplacement, mixed $chaine[, int $limite]) Lexpression rgulire rechercher. Peut tre un tableau ; dans ce cas, si $remplacement est un tableau, alors les motifs seront remplacs par llment de mme index de $remplacement. Chane de substitution ; si celui-ci est une chane de caractres, alors tous les motifs trouvs seront remplacs par cette chane. Chane de caractres o effectuer les modifications. Si $chaine est un tableau, alors la recherche seffectue sur tous les lments du tableau. Si cet argument est spcifi, alors au plus $limite occurrences seront remplaces. $chaine modifie (sera un tableau si $chaine en est un).

$remplacement $chaine $limite retour

Voici un code source dexemple :

Listing 7.33 : preg_replace.php


<?php echo preg_replace("/\d+/", "...des chiffres...", "En 2000, 1123442 serveurs ...")."<br />\n"; $chaines=array("En 2000, 1123442 serveurs ...", "12 elephants sur un arbre"); print_r($chaines)."<br />\n"; print_r(preg_replace("/\d+/", "...des chiffres...", $chaines)); $motifs = array("/([a-zA-Z0-9._-]+)@([a-zA-Z0-9]+)\.com/", "/([a-zA-Z0-9._-]+)@([a-zA-Z0-9]+)\.fr/"); $remplacement = array("Une adresse en .com", "Une adresse en .fr"); $chaine = "test@toutestfacile.com et test@toutestfacile.fr"; echo $chaine."<br />\n"; print_r(preg_replace($motifs, $remplacement, $chaine)); ?>

7. La manipulation des chanes de caractres

dont le rsultat est :


En ...des chiffres..., ...des chiffres... serveurs ...<br /> Array ( [0] => En 2000, 1123442 serveurs ... [1] => 12 elephants sur un arbre ) Array ( [0] => En ...des chiffres..., ...des chiffres... serveurs ... [1] => ...des chiffres... elephants sur un arbre ) test@toutestfacile.com et test@toutestfacile.fr<br /> Une adresse en .com et Une adresse en .fr

415

Chapitre 7

La manipulation des chanes de caractres

Pour rutiliser un motif captur en remplacement, il suffit dy faire appel avec la syntaxe \\n, o n est la position du motif captur. Par exemple :

Listing 7.34 : preg_replace2.php


<?php echo preg_replace("/(\d+)/", "\\1", "En 2000, 1123442 serveurs ..."). "<br />\n"; ?>

dont le rsultat est :


En 2000, 1123442 serveurs ...

preg_replace() vs. str_replace() Bien quil soit possible dutiliser preg_replace() la place de str_replace(), il est tout de mme prfrable, pour des raisons de rapidit, dutiliser str_replace()lorsque le motif recherch savre tre une chane ne faisant intervenir aucun joker. Bien entendu, la diffrence ne se fera ressentir que si cette fonction est appele de nombreuses fois.

preg_replace_callback()
Cette fonction est semblable la prcdente, si ce nest quelle permet dappeler une fonction avec, en paramtre, les motifs capturs. Syntaxe $motif mixed preg_replace_callback(mixed $motif, mixed $fonction, mixed $subject [, int $limite]) Lexpression rgulire rechercher. Peut tre un tableau ; dans ce cas, si $remplacement est un tableau, alors les motifs seront remplacs par llment de mme index de $remplacement. Fonction appeler qui fera la transformation partir des motifs capturs. Chane de caractres o effectuer les modifications. Si $chaine est un tableau, alors la recherche seffectue sur tous les lments du tableau. Si cet argument est spcifi, alors au plus $limite occurrences seront remplaces. $chaine modifie (sera un tableau si $chaine en est un).

7. La manipulation des chanes de caractres

$fonction $chaine $limite retour

416

Expressions rgulires

Dcoupe par expression rgulire

preg_split()
Permet de casser une chane en sous-lments en prcisant le dlimiteur par une expression rgulire. Syntaxe $motif $chaine $limite $mode array preg_split(string $motif, string $chaine [, int $limite [, int $mode]]) Lexpression rgulire qui servira de dlimiteur. Chane de caractres casser. Nombre limite de sous-chanes. Options pouvant tre cumules par OU logique (|). PREG_SPLIT_NO_EMPTY : seules les chanes non vides seront retournes. PREG_SPLIT_DELIM_CAPTURE : les expressions entre parenthses entre les dlimiteurs de motifs seront aussi captures. Le tableau index des sous-chanes.

retour Voici un exemple :

Listing 7.35 : preg_split.php


<?php print_r(preg_split("/[:;-]/", "element 1:element 2-element 3;element 4")); ?>

dont le rsultat est :

7. La manipulation des chanes de caractres

Array ( [0] [1] [2] [3] )

=> => => =>

element element element element

1 2 3 4

Extraction par expression rgulire

preg_match()
Recherche un motif dans une chane de caractres.

417

Chapitre 7

La manipulation des chanes de caractres

Syntaxe $motif $chaine $resultat

int preg_match(string $motif, string $chaine [, array &$resultat [, int $option]) Le motif retrouver. Chane de caractres dans laquelle rechercher le motif. Variable dans laquelle sera copi un tableau index dont llment dindice 0 est le motif en entier, llment 1 le premier lment captur (entre parenthses), llment 2 le deuxime, etc. Seul PREG_OFFSET_CAPTURE est disponible. Cette option nest disponible que depuis PHP 4.3.0 Le nombre dlments capturs, ou FALSE si une erreur sest produite.

$option retour

Listing 7.36 : preg_match()


<?php echo preg_match("/([a-zA-Z0-9._-]+)@([a-zA-Z0-9]+)\.([a-zA-Z]{2,3})/", "Voici mon adresse: biblephp@exemple.com, elle est bidon",$elements); print_r($elements); ?>

dont le rsultat est :


1 Array ( [0] [1] [2] [3] )

=> => => =>

biblephp@exemple.com biblephp exemple com

7. La manipulation des chanes de caractres

preg_match_all()
Recherche un motif dans une chane de caractres, et ritre la recherche sur tout le reste de la chane de caractres. Syntaxe $motif $chaine $resultat $option int preg_match_all(string $motif, string $chaine, array &$resultat [, int $option]) Le motif rechercher. La chane de caractres rechercher. Le tableau o stocker les rsultats. Permet entre autres de dfinir lordre dans lequel ranger les rsultats. Cela peut tre dfini par les constantes : PREG_PATTERN_ORDER : $resultat[0] sera un tableau index contenant les motifs en entier, $resultat[1] sera un tableau contenant les premiers motifs entre parenthses.

418

Expressions rgulires

PREG_SET_ORDER : $resulat[0] sera un tableau des motifs entre parenthses de la premire sous-chane reconnue. PREG_OFFSET_CAPTURE est galement disponible depuis PHP 4.3.0, elle peut tre combine lune des deux prcdentes. retour Retourne le nombre de motifs retrouvs, ou FALSE si une erreur sest produite.

Listing 7.37 : preg_match_all.php


<?php echo preg_match_all("/<(\w*)>([^<]*)<\/\w*>/", "<b>Gras</b><i>Italique</i><u>Souligne</u>", $resultat)."\n"; print_r($resultat); echo preg_match_all("/<(\w*)>([^<]*)<\/\w*>/", "<b>Gras</b><i>Italique</i><u>Souligne</u>", $resultat, PREG_PATTERN_ORDER )."\n"; print_r($resultat); echo preg_match_all("/<(\w*)>([^<]*)<\/\w*>/", "<b>Gras</b><i>Italique</i><u>Souligne</u>", $resultat, PREG_SET_ORDER )."\n"; print_r($resultat); ?>

Le rsultat de ce script est :


3 Array ( [0] => Array ( [0] => <b>Gras</b> [1] => <i>Italique</i> [2] => <u>Souligne</u> ) [1] => Array ( [0] => b [1] => i [2] => u ) [2] => Array ( [0] => Gras [1] => Italique [2] => Souligne ) )

7. La manipulation des chanes de caractres 419

Chapitre 7

La manipulation des chanes de caractres

3 Array ( [0] => Array ( [0] => <b>Gras</b> [1] => <i>Italique</i> [2] => <u>Souligne</u> ) [1] => Array ( [0] => b [1] => i [2] => u ) [2] => Array ( [0] => Gras [1] => Italique [2] => Souligne ) ) 3 Array ( [0] => Array ( [0] => <b>Gras</b> [1] => b [2] => Gras ) [1] => Array ( [0] => <i>Italique</i> [1] => i [2] => Italique ) [2] => Array ( [0] => <u>Souligne</u> [1] => u [2] => Souligne ) )

7. La manipulation des chanes de caractres 420

Expressions rgulires

Divers

preg_quote()
Permet dchapper les caractres spciaux (. ,\\, +, * ,?, [, ^, ], $, (, ), {, }, =, !, <, >, |, :) des expressions rgulires. Syntaxe $chaine $delimiteur retour string preg_quote(string $chaine [, string $delimiteur]) Chane de caractres dont vous souhaitez chapper les caractres spciaux. Caractre qui sera galement chapp. Une chane de caractres dont les caractres ne sont pas des caractres spciaux.

Voici un court exemple montrant limportance dchapper les caractres spciaux :

Listing 7.38 : preg_quote.php


<?php $chaine="2*3+4"; // retournera 0 car lexpression regulire filtre les expressions // dont la dfinition est : // "0 ou plus 2 suivi de au moins un 3 et dun 4" echo preg_match("/$chaine/","2*3+4")."\n"; echo preg_quote($chaine)."\n"; // Ici les caractres + et = seront chapps. echo preg_match("/".preg_quote($chaine)."/","2*3+4"); ?>

7. La manipulation des chanes de caractres

dont le rsultat est :


0 2\*3\+4 1

Posix
Les expressions rgulires de POSIX sont trs semblables celles en Perl ; elles sont utilises sous UNIX pour crer des scripts.

421

Chapitre 7

La manipulation des chanes de caractres

Gnralits
La plus simple
La plus simple des expressions rgulires est une sous-chane de caractres compose de chiffres, de lettres et despaces. Lexpression rgulire "morceau rechercher" pourra servir rechercher la sous-chane "morceau rechercher" dans une chane.

Les mtacaractres
Le point
Un caractre trs utile est le point ".". Dans une expression rgulire, il remplace nimporte quel caractre. Par exemple "PHP. est la dernire version" est une expression regulire pour "PHP3 est la dernire version" ou "PHP4 est la dernire version", mais ne fonctionnera pas pour "PHP 10 est la dernire version", car 10 est sur deux caractres. (Inversement "PHP.. est la dernire version" fonctionnera pour la version 10, mais pas pour les versions 3 ou 4). Utiliser le point tel quel peut poser problme si lon veut rechercher le caractre point, et uniquement celui-ci. En effet, pour rechercher "3.14", il ne faudra pas crire "3.14", sans quoi les expressions "3F14", "3214", "3:14" seront reconnues par cette expression rgulire. Pour utiliser le caractre point en tant que simple caractre (et non comme mtacaractre), il faut le prcder du caractres dchappement : "\". Pour rechercher "3.14" il faut donc crire "3\.14".

Le point dinterrogation
7. La manipulation des chanes de caractres
Le point dinterrogation permet dindiquer la prsence dau plus une occurrence dun caractre. Le point dinterrogation est mettre aprs le caractre en question. Voici quelques exemples : "chanes? de caractres" reconnatra "chanes de caractres" et "chane de caractres". "points? et interrogations?" permettra de reconnatre "points et interrogations" "points et interrogation", "point et interrogations" et "point et interrogation". Pour utiliser le caractre ? en tant que simple caractre (et non comme mtacaractre), il faut le faire prcder de \.

Le signe "plus"
Le signe "plus" (+) permet dindiquer la prsence dune ou plusieurs occurrences dun caractre. Le signe plus est mettre aprs le caractre en question. Voici quelques exemples : "Whaoo+" reconnatra "Whaoo", "Whaooo", "Whaoooo" mais pas "Whao". "coo+l" servira pour reconnatre "cool", "coool", "cooooooool" mais pas "col".

422

Expressions rgulires

Pour utiliser le caractre + en tant que simple caractre (et non comme mtacaractre), il faut le faire prcder de \.

Le signe multiplier
Le signe multiplier (*)permet dindiquer la prsence daucune ou de plusieurs occurrences dun caractre. Le signe multiplier est mettre aprs le caractre en question. Voici quelques exemples: "Whao*" reconnatra "Wha", "Whao", "Whaoo" "cooo*l" servira pour reconnatre "cool", "coool", "cooooooool" Pour utiliser le caractre * en tant que simple caractre (et non comme mtacaractre), il faut le faire prcder de \.

Combinaison de mtacaractres
Le point peut tre combin avec les signes ?, + ou *. Cela permettra dindiquer, par exemple, la prsence de nimporte quel caractre au moins une fois dans le cas du signe +. Voici quelques exemples : "Cest .*bien" servira pour "Cest trs bien", "Cest vraiment bien", "Cest rien bien" et mme "Cest bien".

Des exemples
Voici une srie dexemples. Les expressions rgulires peuvent vite devenir complexes lire ; il suffit de procder par tapes pour viter les erreurs :

Tableau 7.9 : Exemples


Expression a.z Dfinition Caractre a suivi dun seul caractre suivi de z Exemples reconnus az abz a_z azz a.z abz abcz azzz a.z a..z az a+z a++z a+++z Exemples non reconnus az abcz a_-z abz az

7. La manipulation des chanes de caractres

a\.z a.+z

Caractre a suivi du caractre . suivi de z Caractre a suivi dau moins un caractre suivi de z Caractre a suivi dau moins un caractre . suivi de z Caractre a suivi dau moins un caractre + suivi de z

a\.+z

az

a\++

az

423

Chapitre 7

La manipulation des chanes de caractres

Expression ab?c+d*e

Dfinition Caractre a suivi dun ou daucun caractre b puis dun caractre c ou plus, puis dventuellement 1 ou plusieurs d puis dun e

Exemples reconnus abcde acde abccccccde abce abccccce abcddddde

Exemples non reconnus bcde abcd abde abbcde

Pour affiner la recherche, il est possible de dfinir certains types de caractres, avec la notation suivante :

Tableau 7.10 : Ensembles de caractres


Notation [:digit:] [:^digit:] [:alpha:] [:^alpha:] [:alnum:] [:^alnum:] [:ascii:] [:^ascii:] [:lower:] [:upper:] [:print:] Dfinition Tout caractre numrique (0, 1, 2, 3, 4, 5, 6, 7, 8, 9). Tout caractre non numrique. Tout caractre alphabtique. Tout caractre non alphabtique. Tout caractre alphanumrique. Tout caractre non alphanumrique. Tout caractre alphanumrique. Tout caractre non alphanumrique. Tout caractre alphabtique en minuscule. Tout caractre alphabtique en majuscule. Tout caractre imprimable. Tout caractre alphanumrique en minuscule et le signe soulign _. Tout caractre qui nest pas alphanumrique en minuscule ni le caractre soulign _. Tous les caractres despacement (espace, tabulation, retour chariot) et tout autre caractre qui nutiliserait pas dencre sur une imprimante. Tous les caractres qui ne sont pas des caractres despacement. Tout caractre de ponctuation. Tout caractre hexadcimal ([0-9a-f]). Tout caractre de contrle.

7. La manipulation des chanes de caractres

[:word:] [:^word] [:space:] [:^space:] [:punct:] [:xdigit:] [:cntrl:]

Voici une nouvelle srie dexemples illustrant ce que lon peut dfinir avec ces ensembles de caractres.

424

Expressions rgulires

Tableau 7.11 : Exemples


Expression [[:word:]] +@[[:word:]] +\.com Dfinition Exemples reconnus Exemples non reconnus

Une srie de caractres thomas@toutestfacile thomas@toutestfacile.fr alphanumriques (ou .com toto.com _) puis le signe @ puis une autre srie de caractres alphanumrique (ou _) suivi de .com. 0a1b1 -2 0abc1 d2

[:digit:][:word:] Un chiffre suivi dun 0abc1 -2 [:^digit:][:word:] caractre 0_aa1 %2 [:digit:][:space:] alphanumrique puis [:^word:][:digit:] dun caractre qui nest pas un chiffre puis un caractre alphanumrique puis un chiffre, un caractre despacement, dun caractre non alphanumrique et enfin un chiffre

Il est galement possible de prciser les nombres minimum et maximum doccurrences dun caractre en utilisant une notation entre accolades, les deux valeurs tant spares par une virgule.
ab{2,4}c signifie : un caractre a suivi de deux quatre caractres b puis du caractre c.

Pour permettre une alternative, il suffit dutiliser le caractre |.


ab|ac signifie : soit la chane ab, soit la chane ac et aucune autre.

7. La manipulation des chanes de caractres

Enfin, pour permettre certains caractres ou une certaine plage de caractres, on peut utiliser des crochets.
a[bcde]f permettra de reconnatre abf, acf, adf et aef, mais pas abcf par exemple.

Pour dfinir une certaine plage de caractres, il suffit de placer un signe entre les caractres dlimitant la plage.
a[be]f est identique lexemple prcdent.

Pour ajouter le signe la liste des caractres, il suffit de le placer juste avant le crochet fermant.
a[be]f permettra de reconnatre abf, acf, adf, aef et af.

Lutilisation des crochets peut galement permettre dexclure certains caractres, en utilisant le caractre dexclusion ^.
[^bc]oule permettra de reconnatre foule, roule mais pas boule ni coule.

lintrieur des crochets, les rgles dchappement ne sappliquent pas de la mme manire ; seuls les caractres [, ] et \ doivent tre prcds du signe \.

425

Chapitre 7

La manipulation des chanes de caractres

Tableau 7.12 : Dautres exemples


Expression [02468]{3,5} Dfinition Un nombre de trois cinq caractres composs de chiffres pairs. Exemples reconnus 24804 8602 666 a_111 g_753 Exemples non reconnus 135 1222 20 7_765 4_a33

[az]_[09]{3,3} Une lettre minuscule suivie du signe _ puis dexactement trois chiffres. [\[\]\\]+ Une composition de caractres [, ] et \.

\[]\][]\][ [\] \\\]][[[

[a]

[azAZ09._] Un ou plusieurs +@[azAZ09] caractres +\.[azAZ]{2,3} alphanumriques ou ., _, suivi de @, de un ou plusieurs caractres alphanumriques, dun point puis de deux ou trois lettres.

livrephp@toutestfacile @toutestfacile.com .com toto@_.com manuel@brazil.br thomas.heute@toutestfacile .com

Dbut et n de ligne
En dehors des crochets, le caractre ^ permet de dfinir le dbut dune chane. Le caractre $ dsigne la fin dune chane.
abc reconnatra "abc", "dabc", "dabce".

7. La manipulation des chanes de caractres

^abc reconnatra "abc" et "abcd". ^abc$ reconnatra "abc" (uniquement).

Les fonctions PHP Substitution par expression rgulire

ereg_replace()
Permet de remplacer une partie de chane de caractres par une autre. Syntaxe $expression $remplacement string ereg_replace(string $expression, string $remplacement, string $chaine) Expression rgulire qui correspond la partie remplacer. Chane de substitution qui peut rcuprer les motifs capturs par \\n , o n est le numro du motif.

426

Expressions rgulires

$chaine retour

Chane dans laquelle remplacer une partie. La chane de caractres modifie.

Voici un script dexemple :


<?php echo ereg_replace("([[:alpha:]]+)@([[:alpha:]]+)\.com", "Premire partie de ladresse:\\1 Domaine:\\2", "webmaster@toutestfacile.com"); ?>

dont le rsultat est :


Premire partie de ladresse:webmaster Domaine:toutestfacile

ereg_replace() vs. str_replace() Bien quil soit possible dutiliser ereg_replace() la place de str_replace(), il est tout de mme prfrable, pour des raisons de rapidit, dutiliser str_replace()lorsque le motif recherch savre tre une chane ne faisant intervenir aucun joker. Bien entendu, la diffrence ne se fera ressentir que si cette fonction est appele de nombreuses fois.

eregi_replace()
Permet de remplacer une partie de chane de caractres par une autre expression rgulire insensible la casse. Syntaxe $expression $remplacement $chaine retour string eregi_replace(string $expression, string $remplacement, string $chaine) Expression rgulire qui correspond la partie remplacer. Chane de substitution qui peut rcuprer les motifs capturs par \\n, o n est le numro du motif. Chane dans laquelle remplacer une partie. La chane de caractres modifie.

7. La manipulation des chanes de caractres

Voici un script dexemple :

Listing 7.39 : eregi_replace.php


<?php echo ereg_replace("([[:alpha:]]+)@([[:alpha:]]+)\.com", "Premire partie de ladresse:\\1 Domaine:\\2", "webmaster@toutestfacile.Com"); ?>

427

Chapitre 7

La manipulation des chanes de caractres

dont le rsultat est :


Premire partie de ladresse:webmaster Domaine:toutestfacile

Extraction et comparaison par expression rgulire

ereg()
Permet de retourner les motifs capturs dune chane de caractres ou, tout simplement, de vrifier si cette dernire satisfait une expression rgulire. Syntaxe $expression $chaine $resultat retour int ereg(string $expression, string $chaine [, array &$resultat]) Expression rgulire vrifier. Chane dont on veut vrifier quelle correspond lexpression rgulire. Les motifs capturs sont stocks dans ce tableau. TRUE si la chane vrifie lexpression rgulire, FALSE sinon.

Voici un script dexemple :

Listing 7.40 : ereg.php


<?php echo (ereg("([[:alpha:]]+)@([[:alpha:]]+)\.com", "webmaster@toutestfacile.com")) ? "Ca matche" : "Ca matche pas"; echo "<br />\n"; echo (ereg("([[:alpha:]]+)@([[:alpha:]]+)\.com", "webmaster@toutestfacile.COM")) ? "Ca matche" : "Ca matche pas"; ?>

7. La manipulation des chanes de caractres

dont le rsultat est :


Ca matche Ca matche pas

eregi()
Permet de retourner les motifs capturs dune chane de caractres ou, tout simplement, de vrifier si cette dernire satisfait une expression rgulire, sans tenir compte de la casse (les minuscules et majuscules sont confondues). Syntaxe $expression int eregi(string $expression, string $chaine[, array $resultat]) Expression rgulire vrifier.

428

Expressions rgulires

$chaine $resultat retour

Chane dont vous souhaitez extraire des motifs, ou vrifier quelle correspond lexpression rgulire. Les motifs capturs sont stocks dans ce tableau. TRUE si la chane vrifie lexpression rgulire, FALSE sinon.

Voici un script dexemple :

Listing 7.41 : eregi.php


<?php echo (eregi("([[:alpha:]]+)@([[:alpha:]]+)\.com", "webmaster@toutestfacile.com")) ? "Ca matche" : "Ca matche pas"; echo "<br />\n"; echo (eregi("([[:alpha:]]+)@([[:alpha:]]+)\.com", "webmaster@toutestfacile.COM")) ? "Ca matche" : "Ca matche pas"; ?>

dont le rsultat est :


Ca matche Ca matche

Dcoupe par expression rgulire

split()
Permet de dcouper une chane de caractres en morceaux selon une expression rgulire. Syntaxe $expression $chaine $limite retour array split(string $expression, string $chaine [, int $limite]) Expression rgulire du sparateur. Chane dcouper. Nombre dlments maximum du tableau. Un tableau des diffrentes parties spares par lexpression rgulire.

7. La manipulation des chanes de caractres

Encore un petit exemple dapplication :

Listing 7.42 : split.php


<?php print_r(split("[:;,.]", "Comment,separer;des.elements,dune:chaine")); ?>

429

Chapitre 7

La manipulation des chanes de caractres

qui produira :
Array ( [0] [1] [2] [3] [4] [5] )

=> => => => => =>

Comment separer des elements dune chaine

spliti()
Permet de dcouper une chane de caractres en morceaux, lexpression rgulire ignorant la casse des caractres. Syntaxe $expression $chaine $limite retour array split(string $expression, string $chaine[, int $limite]) Expression rgulire du sparateur. Chane dcouper. Nombre dlments maximum du tableau. Un tableau des diffrentes parties spares par lexpression rgulire.

Divers

7. La manipulation des chanes de caractres

sql_regcase()
Permet de crer une expression rgulire ngligeant la casse. Syntaxe $chaine retour Encore un exemple : string sql_regcase(string $chaine) Chane de caractres. Une expression rgulire.

Listing 7.43 : sql_regcase.php


<?php echo sql_regcase("Cest Cool."); ?>

Et son rsultat :
[Cc][Ee][Ss][Tt] [Cc][Oo][Oo][Ll].

430

Adapter le texte la langue du visiteur

7.9.

Adapter le texte la langue du visiteur

Si vous souhaitez proposer le mme site web des visiteurs provenant de diffrents horizons linguistiques, vous devrez trouver une solution vous permettant dadapter le texte en fonction de la langue choisie. Une des solutions consiste utiliser la bibliothque gettext. Malheureusement, sans que nous puissions vritablement dterminer lorigine du problme, il se trouve que cette bibliothque na correctement fonctionn que dans un des trois environnements tests. Nous ne nous tendrons pas sur ce sujet, dautant quil est trs facile darriver au mme rsultat sans avoir utiliser la moindre bibliothque (ce qui garantit un fonctionnement dans nimporte quel environnement). En effet, il vous suffit de crer un script par langue que vous souhaitez proposer, chacun de ces scripts dfinissant un tableau associatif ayant pour cls les identifiants de message (qui pourraient tre les versions franaises du message) et pour valeurs les traductions. Ce qui donne, par exemple :

Listing 7.44 : lang_en_inc.php


<?php $msg["titre"] = "Welcome! This is our acme website"; $msg["Bonjour"] = "Hi"; $msg["Quoi de neuf?"] = "Whats up?"; ?>

Listing 7.45 : lang_fr_inc.php


<?php $msg["titre"] = "Bienvenue! Cest notre super site"; $msg["Bonjour"] = "Bonjour"; $msg["Quoi de neuf?"] = "Quoi de neuf?"; ?>

Il suffira alors dinclure le fichier correspondant la langue choisie, et de faire appel aux valeurs du tableau pour chaque affichage. Comme dans lexemple suivant :

7. La manipulation des chanes de caractres

Listing 7.46 : lang_accueil.php


<?php switch ($_GET["lang"]) { case "en" : { include("lang_en_inc.php"); break; } case "fr" : default : { include("lang_fr_inc.php"); break; } }

431

Chapitre 7

La manipulation des chanes de caractres

?> <html> <head> <title><?php echo $msg["titre"]; ?></title> </head> <body> <h1><?php echo $msg["Bonjour"]; ?></h1> <?php echo $msg["Quoi de neuf?"]; ?> </body> </html>

Ainsi, lappel lang_accueil.php?lang=fr (ou tout autre valeur de lang diffrente de "en") retournera :
Bonjour Quoi de neuf?

avec pour titre :


"Bonjour! Cest notre super site"

Alors que lappel lang_accueil.php?lang=en retournera :


Hi Whats up?

avec pour titre :


Welcome! This is our acme website

Mme si votre site nest quen franais, cette mthode peut prsenter des avantages, puisquen faisant ainsi, tous les textes sont centraliss dans un unique fichier (ce qui ne peut que simplifier les mises jour).

7. La manipulation des chanes de caractres

Dtection automatique de la langue prfre Si vous souhaitez dterminer automatiquement la langue prfre de votre visiteur, vous pourrez faire appel la variable externe $_SERVER["HTTP_ACCEPT _LANGUAGE"]. Celle-ci contient une liste des codes pays (sur deux lettres) spars par des virgules et dans lordre de prfrence. Vous pourrez alors dterminer la langue prfre supporte par votre site (ici, "en" et "fr") grce au script suivant :
<?php function languePreferree() { $langs = explode(",", $_SERVER["HTTP_ACCEPT_LANGUAGE"]); for ($i=0; (($i<count($langs))&&(!isset($lang))); $i++) { if (in_array($langs[$i], array("en", "fr"))) $lang = $langs[$i]; } return $lang; } ?>

432

Chapitre 8

La gestion des dates et des calendriers


8.1 8.2 8.3 Les fonctions de date et heure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435 Les dates et calendriers particuliers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444 Les gestionnaires dvnements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449

Les fonctions de date et heure

8.1.

Les fonctions de date et heure

Le langage PHP offre des fonctions similaires ce que lon peut rencontrer en C/C++. La plupart de ces fonctions sappuient sur une date dfinie par un entier correspondant au nombre de secondes coules depuis le 1er janvier 1970 00:00:00 (aussi appel epoch). Une date ainsi dfinie sera galement appele timestamp UNIX.

Jusquen 2037 Ce timestamp UNIX nest valable que dans la plage de temps comprise entre le 1er janvier 1970 et 2037.

Rcuprer une date au "format informatique"


Ainsi, gnralement, la premire opration raliser lorsque lon souhaite manipuler des dates consiste rcuprer la date voulue au format timestamp UNIX. Pour cela, nous disposons des fonctions time(), mktime() et strtotime().

time()
Retourne la date courante. Syntaxe retour int time(void) Nombre de secondes coules depuis le 1er janvier 1970.

mktime()
Retourne le timestamp de la date spcifie.

8. La gestion des dates et des calendriers

Syntaxe $heure $minute $seconde $mois $jour $annee retour

int mktime(int $heure, int $minute, int $seconde, int $mois, int $jour, int $annee) Lheure. Les minutes. Les secondes. Le mois. Le jour. Lanne. Nombre de secondes coules entre le 1er janvier 1970 et la date spcifie.

435

Chapitre 8

La gestion des dates et des calendriers

strtotime()
Retourne le timestamp dune date spcifie sous la forme dune chane de caractres et exprime en anglais. Syntaxe $date retour int strtotime(string $date) Date exprime en anglais. Nombre de secondes coules entre le 1er janvier 1970 et la date spcifie.

Listing 8.1 : datetime_01.php


<?php echo "Le timestamp actuel est ".time()."<br />"; echo "Le timestamp pour la date du 10/01/2001 18:15 est "; echo mktime(18, 15, 0, 1, 10, 2001)."<br />"; echo "Le timestamp pour la date du 10 Janvier 2001 18:15 est "; echo strtotime("10 January 2001 18:15")."<br />"; echo "Le timestamp pour la date du 2001-01-10 18:15 est "; echo strtotime("2001-01-10 18:15")."<br />"; ?>

retournera :
Le Le Le Le timestamp timestamp timestamp timestamp actuel est (valeur variable) pour la date du 10/01/2001 18:15 est 979146900 pour la date du 10 Janvier 2001 18:15 est 979146900 pour la date du 2001-01-10 18:15 est 979146900

Dates au format SQL Comme vous pouvez le constater, strtotime() permet de traiter des dates issues dune base de donnes (i.e. au format AAAAMMJJ hh:mm:ss).

8. La gestion des dates et des calendriers

Effectuer des oprations sur les dates


Lorsque vous avez une date au format timestamp UNIX (issue, par exemple, de la fonction time()), vous pouvez ajouter/soustraire des secondes, des minutes, des heures, des jours simplement en ajoutant/soustrayant le nombre de secondes correspondant.

Listing 8.2 : datetime_02a.php


<?php echo "Le timestamp dhier la mme heure est ".(time()-24*3600)."<br />"; ?>

436

Les fonctions de date et heure

Si, en revanche, vous voulez ajouter/soustraire des mois ou des annes, vous devrez dcomposer la date exprime en secondes depuis le 1er janvier 1970 en jours, mois, annes, heures, minutes et secondes. Pour cela, vous pouvez faire appel la fonction getDate().

getDate()
Retourne les diffrents champs dune date (ou de la date courante). Syntaxe $date retour array getDate([int $date]) Date exprime en nombre de secondes depuis 1970 (par dfaut, la date courante). Tableau associatif contenant (entre autres) les cls : "mday" jour. "mon" mois. "year" anne. "hours" heure. "minutes" minutes. "seconds" secondes.

Listing 8.3 : datetime_02b.php


<?php $tableauDate = getdate(); // Calcul de la date courante - 6 mois $tableauDate["mon"] = $tableauDate["mon"] - 6; if ($tableauDate["mon"] < 1) { $tableauDate["mon"] = $tableauDate["mon"] + 12; $tableauDate["year"] = $tableauDate["year"] - 1; } echo echo echo echo ?> "Il y a 6 mois, nous tions le "; $tableauDate["mday"]."/".$tableauDate["mon"]; "/".$tableauDate["year"]; "<br />";

8. La gestion des dates et des calendriers

Afficher des dates


Il existe diffrentes fonctions daffichage (ou, plus exactement, de reprsentation) des dates, mais toutes sappuient sur une date exprime en secondes depuis le 1er janvier 1970. Parmi elles, vous trouverez les fonctions date() et strftime().

437

Chapitre 8

La gestion des dates et des calendriers

date()
Reprsente une date (ou date courante) selon le format spcifi. Syntaxe $format $date retour string date(string $format [, ind $date]) Chane prcisant le format de reprsentation de la date en sappuyant sur les cls prsentes ci-aprs. Date exprime en nombre de secondes depuis 1970 (par dfaut, date courante). Chane de caractres reprsentant la date.

Dans le cadre de la fonction date(), les cls sont :

Tableau 8.1 : Les diffrentes cls pour reprsenter un format de date avec date()
Cl l D w d j S z F M m n Signification Pour le jour en toutes lettres (en anglais). Pour les trois premires lettres du jour (en anglais). Pour le jour de la semaine (0 = Dimanche, ..., 6 = Samedi). Pour le jour du mois, sur deux chiffres. Pour le jour du mois (sur un ou deux chiffres). Pour le suffixe sur deux lettres (en anglais) du nombre indiquant le jour. Pour le numro du jour dans lanne (0 = 1er Janvier). Pour le mois en toutes lettres (en anglais). Pour les premires lettres du mois (en anglais). Pour le mois, sur deux chiffres. Pour le mois (sur un ou deux chiffres). Pour le nombre de jours dans le mois. Pour lanne, sur quatre chiffres. Pour lanne, sur deux chiffres. Pour "1" si lanne est bissextile, "0" sinon. Pour lheure sur 12 heures (sur un ou deux chiffres). Pour lheure sur 24 heures (sur un ou deux chiffres). Pour lheure sur 12 heures, sur deux chiffres. Concernant les jours

Concernant les mois

8. La gestion des dates et des calendriers

t Y y L g G h

Concernant les annes

Concernant les heures

438

Les fonctions de date et heure

Cl H a A I T Z B i s r U Lexemple :

Signification Pour lheure sur 24 heures, sur deux chiffres. Pour "am" ou "pm". Pour "AM" ou "PM". Pour "1" en heure dt et "0" en heure dhiver. Pour le fuseau horaire. Pour le dcalage horaire GMT en secondes. Pour lheure internet Swatch. Pour les minutes, sur deux chiffres. Pour les secondes, sur 2 chiffres. Pour la date au format RFC 822 (Tue, 22 Jan 2002 11:09:42 +0100). Retourne simplement le timestamp.

Concernant les minutes Concernant les secondes Concernant la date dans son ensemble

Listing 8.4 : datetime_03a.php


<?php echo "Nous sommes le ".date("l j F Y")." "; echo "Il est ".date("H:i:s")."<br />"; ?>

pourra retourner quelque chose comme :


Nous sommes le Tuesday 9 July 2002 Il est 22:39:06

La fonction date() propose donc de nombreuses possibilits de formatage dune date, mais nous lui prfrons la fonction strftime() qui, elle, tient compte de la langue locale lors de la restitution dinformations en toutes lettres.

8. La gestion des dates et des calendriers

strftime()
Reprsente une date (ou la date courante) selon le format spcifi. Syntaxe $format string strftime(string $format [, int $date]) Chane prcisant le format de reprsentation de la date en sappuyant sur les cls prsentes ci-aprs.

439

Chapitre 8

La gestion des dates et des calendriers

$date retour

Date exprime en nombre de secondes depuis 1970 (par dfaut, la date courante). Chane de caractres reprsentant la date.

Dans le cadre de la fonction strftime(), les cls sont :

Tableau 8.2 : Les diffrentes cls pour reprsenter un format de date avec strftime()
Cl %A %a %d %e (*) %j %u (*) %w %B %b %h (*) %m %y %Y %H %I Signification Pour le jour en toutes lettres (dans la langue locale). Pour les trois premires lettres du jour (dans la langue locale). Pour le jour du mois, sur deux chiffres. Pour le jour du mois (sur un ou deux chiffres). Pour le numro du jour dans lanne, sur trois chiffres (1 = 1er janvier). Pour le jour de la semaine (1 = lundi, ..., 7 = dimanche). Pour le jour de la semaine (0 = dimanche, ..., 6 = samedi). Pour le mois en toutes lettres (dans la langue locale). Pour les trois premires lettres du mois (dans la langue locale). Comme %b. Pour le mois; sur deux chiffres. Pour lanne, sur deux chiffres. Pour lanne, sur quatre chiffres. Pour lheure sur 24 heures, sur deux chiffres. Pour lheure sur 12 heures, sur deux chiffres. Pour AM ou PM. Pour le fuseau horaire. Pour les minutes, sur deux chiffres. Pour les secondes, sur deux chiffres. Pour le numro de la semaine (1 = semaine du 1er dimanche de lanne). Pour le numro de la semaine (ISO 8601:1988), sur deux chiffres. Concernant le jour

Concernant le mois

Concernant lanne

Concernant lheure

8. La gestion des dates et des calendriers

%p %Z %M %S %U %V (*)

Concernant les minutes Concernant les secondes Concernant la semaine

440

Les fonctions de date et heure

Cl %W %C (*) %D (*) %r (*) %R (*) %T (*) %c %x %X Autre %n %t %% Lexemple :

Signification Pour le numro de la semaine (1 = semaine du 1er lundi de lanne). Pour le sicle, sur deux chiffres. Pour la date au format %m/%d/%y. Pour lheure au format %I:%M:%S %p. Pour lheure au format %H:%M. Pour lheure au format %H:%M:%S. Pour laffichage traditionnel de la date dans la langue locale (ex. : JJ/MM/AA hh:mm:ss en France). Pour laffichage traditionnel de la date dans la langue locale, sans lheure (ex. : JJ/MM/AA en France). Pour laffichage traditionnel de lheure dans la langue locale (ex. : hh:mm:ss en France). Pour insrer un retour la ligne. Pour insrer une tabulation. Pour afficher un pourcentage.

Concernant le sicle Concernant la date dans son ensemble

Listing 8.5 : datetime_03b.php


<?php setLocale(LC_TIME, "fr"); echo "Nous sommes le ".strftime("%A %d %B %Y")."<br />"; echo "Il est ".strftime("%H:%M:%S")."<br />";

?>

8. La gestion des dates et des calendriers

retournera quelque chose comme :


Nous sommes le mardi 09 juillet 2002 Il est 22:51:06

Portabilit Malheureusement, il est possible que votre bibliothque PHP ait t compile avec une bibliothque C ne supportant pas toutes ces options. Les cls marques dun astrisque ne sont pas disponibles dans les versions Windows, alors quelles le sont parfaitement sous Linux.

441

Chapitre 8

La gestion des dates et des calendriers

Les heures GMT


Les fonctions mktime(), date() et strftime() se dclinent en gmmktime(), gmdate() et gmstrftime(). Ces fonctions sutilisent exactement de la mme faon, mais :
j j
gmmktime() retourne le timestamp UNIX local (tenant compte du dcalage horaire) dune date donne en heures GMT. gmdate() et gmstrftime() retournent les valeurs GMT pour des dates exprimes localement (tenant compte du dcalage horaire).

Listing 8.6 : datetime_04.php


<?php echo "Le 1/1/2003 11:00:00 GMT donne "; echo strftime("%H:%M:%S",gmmktime(11,0,0,1,1,2003)); echo "localement <br />"; echo strftime("A %H:%M:%S ",mktime(12,0,0,1,1,2003)); echo "localement<br />"; echo gmstrftime("Il est %H:%M:%S",mktime(12,0,0,1,1,2003)); echo " GMT (daprs gmstrftime).<br />"; echo "Il est ".gmdate("H:i:s",mktime(12,0,0,1,1,2003)); echo " GMT (daprs gmdate).<br />";

?>

affichera :
Le 1/1/2003 11:00:00 GMT donne 12:00:00localement A 12:00:00 localement Il est 11:00:00 GMT (daprs gmstrftime). Il est 11:00:00 GMT (daprs gmdate).

Les microsecondes
8. La gestion des dates et des calendriers
PHP dispose de deux fonctions permettant de rcuprer lheure la microseconde prs. Il sagit des fonctions getTimeOfDay() et microtime().

getTimeOfDay()
Retourne les champs de la date courante, y compris les microsecondes. Syntaxe retour array getTimeOfDay(void) Tableau associatif contenant (entre autres) les cls : "sec" contenant le timestamp UNIX. "usec" contenant les microsecondes.

442

Les fonctions de date et heure

microtime()
Retourne une chane de caractres contenant les microsecondes de la date courante. Syntaxe retour string microtime(void) Chane de caractres contenant les microsecondes (0.xxxxxx), une espace puis le timestamp UNIX.

Listing 8.7 : datetime_05.php


<?php $top0=getTimeOfDay(); echo "Temps dexecution avec getTimeOfDay<br />"; $top1=getTimeOfDay(); $diff=($top1["usec"]+$top1["sec"]*1E6) ($top0["usec"]+$top0["sec"]*1E6); echo "Temps = $diff micro-secondes<br />"; list($usec0,$sec0)=explode(" ",microtime()); echo "Temps dexecution avec microtime<br />"; list($usec1,$sec1)=explode(" ",microtime()); $diff=($sec1+$usec1) - ($sec0+$usec0); echo "Temps = $diff secondes<br />"; ?>

Autres fonctions
Outre les fonctions permettant de rcuprer ou de formater des dates, heures et microsecondes, PHP propose la fonction checkDate() qui permet de contrler la validit dune date (en tenant compte notamment des annes bissextiles).

8. La gestion des dates et des calendriers

checkDate()
Teste la validit de la date. Syntaxe $mois $jour $annee retour boolean checkDate(int $mois, int $jour, int $annee) Le mois. Le jour. Lanne. TRUE si la date existe, FALSE sinon.

443

Chapitre 8

La gestion des dates et des calendriers

La fonction localTime() qui permet de rcuprer les diffrents champs dune date nest pas prsente en dtail ici, puisque ses fonctionnalits se retrouvent dans les fonctions prsentes prcdemment.

8.2.

Les dates et calendriers particuliers

Vous trouverez galement, avec le langage PHP, quelques fonctions vous permettant de dterminer, pour chaque anne, des dates particulires (en loccurrence celle de Pques), mais aussi des fonctions permettant de convertir des dates dun calendrier lautre (grgorien, julien, juif, rpublicain). Pour cela, vous devez faire appel la bibliothque Calendar.

Installation
Sous Windows
Que ce soit avec larchive de PHP Group ou avec EasyPHP, la bibliothque Calendar est active par dfaut.

Sous Linux
Lutilisation de cette bibliothque ncessite davoir compil PHP avec loption
enablecalendar.

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur la compilation de PHP.

Vrication
8. La gestion des dates et des calendriers
Vous pouvez vrifier que le support de la bibliothque Calendar est effectif en appelant un script contenant simplement <?php phpinfo(); ?> et qui doit afficher :

Figure 8.1 : phpinfo()

Pques
Pour connatre la date correspondant Pques pour une anne donne, il suffit de faire appel la fonction easter_date().

444

Les dates et calendriers particuliers

easter_date()
Retourne la date de Pques pour lanne donne (ou lanne courante). Syntaxe $annee retour int easter_date([int $annee]) Anne considre (par dfaut, anne courante) entre 1970 et 2037. Timestamp UNIX de Pques.

Si, toutefois, vous souhaitez effectuer la mme opration pour une anne situe en dehors de la plage de validit du timestamp UNIX (i.e. avant le 1er janvier 1970 ou aprs 2037), vous devez faire appel easter_days().

easter_days()
Retourne le nombre de jours entre le 21 mars et Pques pour lanne donne (ou lanne courante). Syntaxe $annee retour int easter_days([int $annee]) Anne considre (par dfaut, anne courante). Nombre de jours.

Listing 8.8 : calendar_01.php


<?php setLocale(LC_TIME, "fr"); echo strftime("Cette anne, Pques tombe le %A %d %B<br />", easter_date()); echo strftime("En 2001, Pques tait le %A %d %B<br />", easter_date(2001)); // Pour les annes prcdant 1970 ou suivant 2037 // utiliser easter_days // La date de rfrence est le 21 Mars $jour = 21; $mois = 3; $annee = 1969; $nbJour = easter_days($annee); if ($nbJour > 10) { $mois++; $jour = $nbJour - 10; } else { $jour += $nbJour; } echo "En $annee, Pques cest le $jour/$mois<br />";

8. La gestion des dates et des calendriers

?>

retourne, en 2002,

445

Chapitre 8

La gestion des dates et des calendriers

Cette anne, Pques tombe le dimanche 31 mars En 2001, Pques tait le dimanche 15 avril En 1969, Pques cest le 6/4

Conversion dune date dun calendrier lautre


Toutes ces fonctions sappuient sur une date exprime dans le calendrier julien (et non le calendrier grgorien auquel nous sommes habitus). Mais, pour linstant, commenons par les fonctions de conversion de/vers le timestamp UNIX.

unixToJD()
Retourne le nombre de jours du calendrier julien partir de la date donne (ou, dfaut, la date courante) en timestamp UNIX. Syntaxe $date retour int unixToJD([timestamp $date]) Date en nombre de secondes depuis le 1er janvier 1970. Nombre de jours du calendrier julien.

JDToUnix()
Retourne la date en timestamp UNIX partir de la date donne en nombre de jours du calendrier julien. Syntaxe $dateJulien retour int JDToUnix(int $dateJulien) Date en nombre de jours du calendrier julien. Date en timestamp UNIX.

8. La gestion des dates et des calendriers

Informations sur les diffrents calendriers Vous trouverez plus dinformations sur ces diffrents calendriers ladresse : http://www.bdl.fr/Granpub/Calendriers.html.
Voici maintenant les autres fonctions de conversion de calendriers.

JDToGregorian()
Retourne une chane au format "mois/jour/anne" du calendrier grgorien, correspondant au nombre de jours donns dans le calendrier julien.

446

Les dates et calendriers particuliers

Syntaxe $jour retour

string JDToGregorian(int $jour) Nombre de jours dans le calendrier julien. Chane au format "mois/jour/anne" du calendrier grgorien.

gregorianToJD()
Retourne le nombre de jours du calendrier julien correspondant la date donne dans le calendrier grgorien. Syntaxe $mois $jour $annee retour int gregorianToJD(int $mois, int $jour, int $annee) Mois dans le calendrier julien. Jour dans le calendrier julien. Anne dans le calendrier julien. Nombre de jours du calendrier julien.

JDToJewish()
Retourne une chane au format "mois/jour/anne" du calendrier juif correspondant au nombre de jours donns dans le calendrier julien. Syntaxe $jour retour string JDToJewish(int $jour) Nombre de jours dans le calendrier julien. Chane au format "mois/jour/anne" du calendrier juif.

jewishToJD()
8. La gestion des dates et des calendriers
Retourne le nombre de jours du calendrier julien correspondant la date donne dans le calendrier juif. Syntaxe $mois $jour $annee retour int jewishToJD(int $mois, int $jour, int $annee) Mois dans le calendrier juif. Jour dans le calendrier juif. Anne dans le calendrier juif. Nombre de jours du calendrier julien.

447

Chapitre 8

La gestion des dates et des calendriers

JDToFrench()
Retourne une chane au format "mois/jour/anne" du calendrier rpublicain franais correspondant au nombre de jours donns dans le calendrier julien. Syntaxe $jour retour string JDToFrench(int $jour) Nombre de jours dans le calendrier julien. Chane au format "mois/jour/anne" du calendrier rpublicain franais.

frenchToJD()
Retourne le nombre de jours du calendrier julien correspondant la date donne dans le calendrier rpublicain franais (valable pour les dates du 22 septembre 1792 au 22 septembre 1806 du calendrier grgorien, mme si son utilisation a t abandonne le 31 dcembre 1805). Syntaxe $mois $jour $annee retour int frenchToJD(int $mois, int $jour, int $annee) Mois dans le calendrier rpublicain franais. Jour dans le calendrier rpublicain franais. Anne dans le calendrier rpublicain franais. Nombre de jours du calendrier julien.

JDToJulian()
Retourne la date du calendrier julien au format "mois/jour/anne" partir de la date exprime en nombre de jours. Syntaxe $jour string JDToJulian(int $jour) Nombre de jours dans le calendrier julien. Date du calendrier julien au format "mois/jour/anne".

8. La gestion des dates et des calendriers

retour

julianToJD()
Retourne la date du calendrier julien exprime en nombre de jours. Syntaxe $mois $jour int julianToJD(int $mois, int $jour, int $annee) Mois dans le calendrier julien. Jour dans le calendrier julien.

448

Les gestionnaires dvnements

$annee retour

Anne dans le calendrier julien. Nombre de jours.

Manipulation dune date dans le calendrier julien

JDMonthName()
Retourne en toutes lettres (en anglais) le nom du mois dans le calendrier prcis. Syntaxe $dateJulien $calendrier string JDMonthName(int $dateJulien, int $calendrier) Date exprime en nombre de jours du calendrier julien. Une des valeurs suivantes : 0 = grgorien (abrg aux trois premires lettres). 1 = grgorien. 2 = julien (abrg aux trois premires lettres). 3 = julien. 4 = juif. 5 = rpublicain franais (uniquement valable pour les dates allant du 22 septembre 1792 au 22 septembre 1806 du calendrier grgorien). retour Nom du mois.

JDDayOfWeek()
Retourne le nom (en anglais) du jour de la semaine ou son numro. Syntaxe $dateJulien $mode mixed JDDayOfWeek(int $dateJulien, int $mode) Date exprime en nombre de jours du calendrier julien. Une des valeurs suivantes : 0 = numro du jour (1 = dimanche). 1 = nom du jour. 2 = nom du jour abrg aux trois premires lettres. retour Numro du jour de la semaine (mode = 0), nom du jour sinon.

8. La gestion des dates et des calendriers

8.3.

Les gestionnaires dvnements

Jusqu larrive de PHP 5, PHP proposait des bibliothques permettant dinteragir avec des gestionnaires dvnements supportant le protocole ICAP (iCalendar Protocol).

449

Chapitre 8

La gestion des dates et des calendriers

Si vous utilisez PHP4, il vous est donc possible de crer votre propre interface Internet de suivi et dadministration de vos agendas. Cette interface vous sera alors accessible depuis nimporte quel poste disposant dun navigateur (et non pas seulement depuis les postes quips du logiciel client de la solution de gestionnaire dvnements retenue). Pour cela, vous devrez utiliser la bibliothque MCAL (Modular Calendar AccessLibrary). Celle-ci, en plus de supporter le protocole ICAP, permet dutiliser des fichiers locaux comme support des donnes. De plus, cette bibliothque a t dveloppe pour tre modulaire ce qui, en thorie du moins, lui permet de supporter dautres protocoles.

En savoir plus Le protocole ICAP est dfini par les RFC-2445 "Internet Calendaring and Scheduling Core Object Specification (iCalendar)" et RFC-2446 "iCalendar Transport-Independent Interoperability Protocol (iTIP)" disponibles en anglais aux adresses suivantes :
http://www.ietf.org/rfc/rfc2445.txt http://www.ietf.org/rfc/rfc2446.txt

Pour tre utilise, cette bibliothque doit au pralable tre rcupre, compile et intgre PHP.

Installation
Cette bibliothque nest pas disponible sous Windows.

Sous Linux
Pr-requis Pour pouvoir compiler cette bibliothque, il faut avoir install au pralable les outils de compilation et autres commandes telles que "flex".
La bibliothque MCAL est compose de deux lments :

8. La gestion des dates et des calendriers

j j

libmcal : la bibliothque proprement dite ; mcaldrivers : les modules de la bibliothque comprenant les pilotes pour le protocole ICAP et ceux pour les fichiers locaux (mstore).

Ces deux fichiers (disponibles sur le CD-ROM) peuvent tre tlchargs ladresse
http://sourceforge.net/projects/libmcal/.

Aprs les avoir copis dans un rpertoire donn (ex. : /usr/local/src/lib), dcompressez ces deux fichiers laide des commandes suivantes :
# # # # gunzip libmcal-0.7.tar.gz tar xvf libmcal-0.7.tar gunzip mcaldrivers-0.9.tar.gz tar xvf mcaldrivers-0.9.tar

450

Les gestionnaires dvnements

Puis, dplacez le contenu de mcaldrivers dans libmcal :


# mv mcal-drivers/* libmcal

Ensuite, passez la gnration des pilotes mstore et icap :


# # # # # # # cd libmcal cd mstore make cd .. cd icap make cd ..

Enfin, passez la gnration de la bibliothque :


# chmod +x configure # ./configure --with-mstore --with-icap # make

Un fichier libmcal.a est alors gnr. Il est maintenant possible de (re)compiler PHP aprs avoir ajout loption "--with-mcal=<chemin vers le rpertoire libmcal contenant libmcal.a>" (ex. : withmcal=/ usr/local/src/lib/libmcal ).

Vous pouvez consulter le chapitre "Prise en main" pour plus de dtails sur la compilation de PHP. Initialisation mstore Si vous souhaitez utiliser le module mstore (autrement dit utiliser un fichier local pour stocker vos agendas), il vous faut dabord crer un rpertoire pour hberger ces agendas, ainsi quun fichier de mots de passe. Pour cela, il suffit de suivre la procdure suivante :
# # # # mkdir chmod touch chmod /var/calendar 1777 /var/calendar /etc/mpasswd a+r /etc/mpasswd

8. La gestion des dates et des calendriers

Mstore utilisant un fichier de mots de passe au format identique celui dApache, vous devez utiliser la commande htpasswd fournie avec Apache pour le gnrer. Vous prendrez soin, ici, de remplacer la variable $APACHE_HOME par sa valeur (qui

pourra tre /usr/local/apache, /usr ou autre selon votre configuration).


# $APACHE_HOME/bin/htpasswd -b /etc/mpasswd <login> <mot de passe>

451

Chapitre 8

La gestion des dates et des calendriers

Vrication
Vous pouvez vrifier que le support de la bibliothque MCAL est effectif en appelant un script contenant simplement <?php phpinfo(); ?> et qui doit afficher :

Figure 8.2 : phpinfo()

Les fonctions
Il est possible de distinguer deux types de fonctions : celles qui permettent de manipuler les dates et celles qui permettent effectivement de manipuler les informations stockes dans les agendas. Les fonctions de manipulation de dates trouvent, pour la plupart, leur quivalent parmi les fonctions proposes par dfaut avec PHP. Il y a toutefois une petite diffrence, puisque, contrairement aux autres, les fonctions de la bibliothque MCAL sont galement valables pour des dates prcdant le 1er janvier 1970.

mcal_date_valid()
Teste la validit de la date. Syntaxe $annee $mois $jour retour boolean mcal_date_valid(int $annee, int $mois, int $jour) Anne. Mois. Jour. TRUE si la date est valide, FALSE sinon.

quivalent sans la bibliothque MCAL :

8. La gestion des dates et des calendriers

checkdate($mois, $jour, $annee);

mcal_time_valid()
Teste la validit de lheure. Syntaxe $heure $minute $seconde boolean mcal_time_valid(int $heure, int $minute, int $seconde) Heure. Minute. Seconde.

452

Les gestionnaires dvnements

retour

TRUE si lheure est valide, FALSE sinon.

quivalent sans la bibliothque MCAL :


( ($heure>=0 && $heure<24 ) && ($minute>=0 && $minute<60) && ($seconde>=0 && $seconde<60))

mcal_day_of_week()
Retourne le numro du jour dans la semaine de la date donne. Syntaxe $annee $mois $jour retour int mcal_day_of_week(int $annee, int $mois, int $jour) Anne. Mois. Jour. Numro du jour dans la semaine (0 = dimanche, ..., 6 = samedi). En fait, des constantes existent MCAL_SUNDAY, MCAL_MONDAY, MCAL_TUESDAY, MCAL_THURSDAY, MCAL_FRIDAY, MCAL_Saturday.

quivalent sans la bibliothque MCAL (pour les dates dans la limite de validit des timestamps) :
$tab = getdate(mktime(0, 0, 0, $mois, $jour, $annee)); return $tab["wday"];

mcal_day_of_year()
Retourne le numro du jour dans lanne de la date donne. Syntaxe $annee $mois $jour retour int mcal_day_of_year(int $annee, int $mois, int $jour) Anne. Mois. Jour. Numro du jour dans lanne (1 = 1er janvier, ...).

8. La gestion des dates et des calendriers

quivalent sans la bibliothque MCAL (pour les dates dans la limite de validit des timestamps) :
$tab = getdate(mktime(0, 0, 0, $mois, $jour, $annee)); return $tab["yday"] + 1;

453

Chapitre 8

La gestion des dates et des calendriers

mcal_date_compare()
Compare deux dates. Syntaxe $annee1 $mois1 $jour1 $annee2 $mois2 $jour2 retour int mcal_date_compare(int $annee1, int $mois1, int $jour1, int $annee2, int $mois2, int $jour2) Anne de la 1re date comparer. Mois de la 1re date comparer. Jour de la 1re date comparer. Anne de la 2e date comparer. Mois de la 2e date comparer. Jour de la 2e date comparer. 1 si la 1re date est antrieure la seconde, 0 si elles sont identiques, 1 sinon.

quivalent sans la bibliothque MCAL (pour les dates dans la limite de validit des timestamps) :
$diff = mktime(0, 0, 0, $mois1, $jour1, $annee1) mktime(0, 0, 0, $mois2, $jour2, $annee2); if ($diff == 0) return 0; return $diff>0?1:-1;

mcal_is_leap_year()
Teste si lanne est bissextile. Syntaxe $annee retour boolean mcal_is_leap_year(int $annee) Anne. TRUE si lanne est bissextile, FALSE sinon.

8. La gestion des dates et des calendriers

quivalent sans la bibliothque MCAL :


return checkdate(2, 29, $annee);

mcal_days_in_month()
Retourne le nombre de jours dans le mois en tenant compte des annes bissextiles.

454

Les gestionnaires dvnements

Syntaxe $mois $bissextile retour

int mcal_days_in_month(int $mois, boolean $bissextile) Mois. Indiquez TRUE sil sagit dune anne bissextile, FALSE sinon. Nombre de jours dans le mois.

quivalent sans la bibliothque MCAL :


if ($mois == 2) { if ($bissextile) { return 29; } else { return 28; } } if (checkdate($mois, 31, 2000)) { return 31; } else { return 30; }

Une utilisation courante de ces fonctions consiste afficher un calendrier (annuel, mensuel, etc.).

8. La gestion des dates et des calendriers

Figure 8.3 : Calendrier annuel

455

Chapitre 8

La gestion des dates et des calendriers

Figure 8.4 : Calendrier mensuel

Ce rsultat peut tre obtenu avec le script suivant :

Listing 8.9 : mcal_01_inc.php


<?php class MCAL_Agenda { /** * Affiche une anne sous forme de calendrier */ function afficheAnnee($annee) { $labelMois = array(1 => "Janv.", "Fvr.", "Mars", "Avril", "Mai", "Juin", "Juil.", "Aot", "Sept.", "Oct.", "Nov.", "Dc."); $labelJour = array("Di.","Lu.","Ma.","Me.","Je.","Ve.","Sa."); echo "<table cellspacing=\"10\">\n"; echo "<tr><td colspan=\"12\" align=\"center\">$annee</td></tr>\n"; // Affiche les enttes de colonnes (les mois) echo "<tr>"; for ($mois = 1; $mois <= 12; $mois++) { echo "<td>".$labelMois[$mois]."</td>"; } echo "</tr>\n"; // Complte chaque mois echo "<tr>"; for ($mois = 1; $mois <= 12; $mois++) { // Donne une couleur de fond diffrente pour les mois // pairs et les mois impairs if (($mois % 2) == 0) { $cssClass = "moisPair"; } else { $cssClass = "moisImpair"; } echo "<td class=\"$cssClass\">\n"; echo "<table cellspacing=\"0\" cellpadding=\"0\">"; // Dtermine le nombre de jours dans le mois // en tenant compte des annes bissextiles

8. La gestion des dates et des calendriers 456

Les gestionnaires dvnements

$nbJour = mcal_days_in_month($mois,mcal_is_leap_year($annee)); for ($jour = 1; $jour <= $nbJour; $jour++) { echo "<tr>"; echo "<td align=\"left\">"; // Determine de quel jour il sagit // pour lafficher en toutes lettres echo $labelJour[mcal_day_of_week($annee,$mois,$jour)]."</td>"; $cssClass = "date"; echo "<td align=\"right\" class=\"$cssClass\">"; echo "$jour</td>"; echo "</tr>"; } // Ajoute des blancs en bas de tableau si necessaire for ($jour = $nbJour + 1; $jour <= 31; $jour++) { echo "<tr><td>&nbsp;</td><td>&nbsp;</td></tr>"; } echo "</table>\n"; echo "</td>"; } echo "</tr>"; echo "</table>\n"; } /** * Affiche un mois sous forme de calendrier */ function afficheMois($mois, $annee, $mcal="") { $labelMois = array(1 => "Janvier", "Fvrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aot", "Septembre", "Octobre", "Novembre", "Dcembre"); $labelJour = array("Lu.","Ma.","Me.","Je.","Ve.","Sa.","Di.");

// Dtermine le nombre de jours dans le mois // en tenant compte des annes bissextiles $nbJours=mcal_days_in_month($mois, mcal_is_leap_year($annee)); echo "<table>\n"; echo "<tr><td colspan=\"4\">$labelMois[$mois]</td>"; echo "<td colspan=\"3\" align=\"right\">$annee</td></tr>\n"; echo "<tr>"; for ($i = 0; $i < 7; $i++) { echo "<td>$labelJour[$i]</td>"; } echo "</tr>\n"; echo "<tr>"; $premierJour = mcal_day_of_week($annee, $mois, 1);

8. La gestion des dates et des calendriers 457

Chapitre 8

La gestion des dates et des calendriers

// convertir 0=Dimanche...6=Samedi // en 0=Lundi...6=Dimanche $premierJour = ($premierJour + 6) % 7; // Sauter autant de colonne que ncessaire pour atteindre // le premier jour de la semaine for ($i = 0; $i < $premierJour; $i++) { echo "<td></td>"; } // Puis passer en revue tous les jours du mois for ($i = 0; $i < $nbJours; $i++) { if (($i + $premierJour) % 7 == 0) { // Retour la ligne chaque Lundi echo "</tr>\n<tr>"; } $cssClass = "date"; echo "<td align=\"right\" class=\"$cssClass\">"; echo ($i+1); echo "</td>"; } echo "</tr>\n"; echo "</table>\n"; } } ?>

Ce script pourra tre appel de la faon suivante (ici, pour afficher les deux types de calendrier) :

Listing 8.10 : mcal_01.php


<?php include("mcal_01_inc.php"); ?> <html> <head> <style> .moisPair { background-color: #DDDDFF; } .moisImpair { background-color: #9999FF; } .date { background-color: #DDDDFF; } </style> </head> <body>

8. La gestion des dates et des calendriers 458

Les gestionnaires dvnements

<h2>Bibliothque MCAL</h2> <?php $dateCourante = getdate(); MCAL_Agenda::afficheAnnee($dateCourante["year"]); MCAL_Agenda::afficheMois($dateCourante["mon"], $dateCourante["year"]); ?> </body> </html>

Les fonctions daccs aux agendas


Comme le veut la logique, pour accder un agenda, il faut dabord se connecter. Il existe ce propos trois fonctions : mcal_open(), mcal_popen(), et mcal_reopen().

mcal_open()
Ouvre un calendrier. Syntaxe $calendrier $utilisateur $motDePasse $options retour resource mcal_open(string $calendrier, string $utilisateur, string $motDePasse[, int $options]) Identifiant du calendrier que vous souhaitez ouvrir. Chane de la forme {serveur/protocole}<proprietaire>calendrier. Nom de lutilisateur. Mot de passe de lutilisateur. Manifestement inutilis. Retourne un identifiant de connexion, ou FALSE en cas dchec.

Cette fonction se dcline galement en mcal_popen() (mais la persistance de la connexion nest pas dmontre) et mcal_reopen() (dont le fonctionnement ne semble pas tout fait satisfaisant). Il nest dailleurs pas assur que leur dveloppement soit tout fait finalis. Dans le cas dune connexion un calendrier via le protocole mstore, le serveur est ncessairement local. La chane didentification du serveur sera donc de la forme {/mstore}<proprietaire>calendrier. Il est noter quun utilisateur peut se connecter lagenda dune autre personne pour accder ses informations publiques. Do lutilit possible du champ propritaire. Toutefois, si ce paramtre nest pas prcis, cest le calendrier de lutilisateur qui est considr. Nous ajouterons donc notre classe MCAL_Agenda la mthode suivante :

8. La gestion des dates et des calendriers

Listing 8.11 : mcal_02_inc.php (extrait)


<?php // Extrait de la Classe MCAL

459

Chapitre 8

La gestion des dates et des calendriers

class MCAL_Agenda { /** * Se connecte lagenda * et retourne lidentifiant associ */ function connect() { $mcal = mcal_open("{/mstore}biblephp","biblephp","pwd") or die("La connexion lagenda a chou"); return $mcal; } (...) } ?>

Une fois toutes les oprations effectues, il sera possible de librer les ressources en fermant la connexion au calendrier par mcal_close().

mcal_close()
Ferme la connexion au calendrier. Syntaxe $idConnexion $options retour boolean mcal_close(resource $idConnexion [, int $options]) Identifiant de connexion tel que retourn par mcal_open(). Rle indtermin. Retourne FALSE en cas dchec, TRUE sinon.

Lecture des vnements


8. La gestion des dates et des calendriers
Une des premires oprations que vous serez amen faire sera probablement de rcuprer la liste des vnements que vous avez nots dans lagenda sur une priode donne. Pour cela, vous devrez faire appel la fonction mcal_list_events().

mcal_list_events()
Retourne la liste des vnements intervenant entre deux dates. Syntaxe array mcal_list_events(resource $idConnexion, int $anneeDebut, int $moisDebut, int $jourDebut, int $anneeFin, int $moisFin, int $jourFin)

460

Les gestionnaires dvnements

$idConnexion $anneeDebut $moisDebut $jourDebut $anneeFin $moisFin $jourFin retour

Identifiant de connexion tel que retourn par mcal_open(). Anne de la date de dbut de recherche. Mois de la date de dbut de recherche. Jour de la date de dbut de recherche. Anne de la date de fin de recherche. Mois de la date de fin de recherche. Jour de la date de fin de recherche. Tableau index ayant pour valeurs des entiers correspondant des identifiants dvnements.

Cela nous permet dj de crer une fonction (ou plus exactement une mthode) entranant laffichage dun calendrier avec, en surbrillance, les jours auxquels des vnements sont associs. Voici donc la mthode daffichage dun calendrier enrichi par cette nouvelle fonctionnalit :

Listing 8.12 : mcal_02_inc.php (extrait)


<?php // Extrait de la classe MCAL_Agenda class MCAL_Agenda { // (...) /** * Affiche une anne sous forme de calendrier * et montre les dates associes un vnement */ function afficheAnnee($annee, $mcal="") { $labelMois = array(1 => "Janv.", "Fvr.", "Mars", "Avril", "Mai", "Juin", "Juil.", "Aot", "Sept.", "Oct.", "Nov.", "Dc."); $labelJour = array("Di.","Lu.","Ma.","Me.","Je.","Ve.","Sa."); echo "<table cellspacing=\"10\">\n"; echo "<tr><td colspan=\"12\" align=\"center\">$annee</td></tr>\n"; // Affiche les enttes de colonnes (les mois) echo "<tr>"; for ($mois = 1; $mois <= 12; $mois++) { echo "<td>".$labelMois[$mois]."</td>"; } echo "</tr>\n"; // Complte chaque mois echo "<tr>";

8. La gestion des dates et des calendriers 461

Chapitre 8

La gestion des dates et des calendriers

for ($mois = 1; $mois <= 12; $mois++) { // Donne une couleur de fond diffrente pour les mois // pairs et les mois impairs if (($mois % 2) == 0) { $cssClass = "moisPair"; } else { $cssClass = "moisImpair"; } echo "<td class=\"$cssClass\">\n"; echo "<table cellspacing=\"0\" cellpadding=\"0\">"; // Dtermine le nombre de jours dans le mois // en tenant compte des annes bissextiles $nbJour = mcal_days_in_month($mois, mcal_is_leap_year($annee)); for ($jour = 1; $jour <= $nbJour; $jour++) { echo "<tr>"; echo "<td align=\"left\">"; // Determine de quel jour il sagit // pour lafficher en toutes lettres echo $labelJour[mcal_day_of_week($annee,$mois,$jour)]."</td>"; // A-t-on un vnement li cette date ? $avecEvenement = FALSE; if ($mcal != "") { $evenements = mcal_list_events($mcal, $annee, $mois, $jour, $annee, $mois, $jour); if (count($evenements) >0 ) $avecEvenement = TRUE; }

8. La gestion des dates et des calendriers

if ($avecEvenement) { $cssClass = "dateEvenement"; } else { $cssClass = "date"; } echo "<td align=\"right\" class=\"$cssClass\">"; echo "$jour</td>"; echo "</tr>"; } // Ajoute des blancs en bas de tableau si ncessaire for ($jour = $nbJour + 1; $jour <= 31; $jour++) { echo "<tr><td>&nbsp;</td><td>&nbsp;</td></tr>"; } echo "</table>\n"; echo "</td>"; } echo "</tr>";

462

Les gestionnaires dvnements

echo "</table>\n"; } // (...) } ?>

qui pourra tre appel par :

Listing 8.13 : mcal_02.php


<?php include("mcal_02_inc.php"); ?> <html> <head> <style> .moisPair { background-color: #DDDDFF; } .moisImpair { background-color: #9999FF; } .date { background-color: #DDDDFF; } .dateEvenement { background-color: #FF0000; } </style> </head> <body> <h2>Bibliothque MCAL</h2> <?php $mcal = MCAL_Agenda::connect();

8. La gestion des dates et des calendriers

$dateCourante = getdate(); MCAL_Agenda::afficheAnnee($dateCourante["year"], $mcal); MCAL_Agenda::afficheMois($dateCourante["mon"], $dateCourante["year"], $mcal); ?> </body> </html>

Le fichier mcal_02.php nest rien dautre que mcal_01.php auquel nous avons ajout un style afin de prciser la couleur des dates associes un vnement et une connexion lagenda.

463

Chapitre 8

La gestion des dates et des calendriers

Voici un exemple de rsultat obtenu (dans les cas dun vnement mensuel sur toute lanne et dun vnement hebdomadaire sur les derniers mois).

Figure 8.5 : Calendrier annuel avec des vnements

8. La gestion des dates et des calendriers

Attention aux vnements rcurrents Nous aurions pu (comme nous lavons vu dans des exemples proposs sur Internet) viter un appel la fonction mcal_list_event() pour chaque jour, et se contenter de lappliquer lensemble de la priode considre. Le problme est que, dans ce cas, pour les vnements rcurrents, nous naurions pu calculer leurs diffrentes dates dapparition (la fonction mcal_list_event() ne retournant quune seule fois lidentifiant de lvnement, quel que soit son nombre dapparitions sur la priode donne). Cette mthode nest donc srieusement envisageable que dans le cas dun agenda ne contenant que des vnements ponctuels.
Comme vous le constatez, la fonction mcal_list_event() ne retourne quune liste didentifiants, mais pas le descriptif des vnements. Pour cela, vous devez faire appel (pour chaque identifiant) la fonction mcal_fetch_event().

464

Les gestionnaires dvnements

mcal_fetch_event()
Retourne les proprits dun vnement. Syntaxe $idConnexion $idEvenement $options retour object mcal_fetch_event(resource $idConnexion, int $idEvenement [, int $options]) Identifiant de connexion tel que retourn par mcal_open(). Identifiant de lvnement. Manifestement inutilis. Objet vnement.

Les proprits dun vnement sont donc retournes sous la forme dun objet. Cet objet possde les attributs publics suivants:
j j j j j j j j j
id (int) : identifiant de lvnement ; public (boolean) : TRUE si lvnement est public, FALSE sil est priv ; title (string) : nom de lvnement ; category (string) : chane de caractres libre destine indiquer la catgorie de lvnement ; description (string) : description de lvnement ; attrlist (array) : tableau associatif des attributs personnaliss (attribut => valeur) ; start (objet date et heure) : date de dbut (de la premire occurrence) de lvnement ; end (objet date et heure) : date de fin (de la premire occurrence) de lvnement ; recur_type (int) : type de frquence pouvant avoir une des valeurs MCAL_RECUR_NONE (ponctuelle), MCAL_RECUR_DAILY (frquence exprime en jours), MCAL_RECUR_WEEKLY (frquence exprime en semaines), MCAL_RECUR_MONTHLY_MDAY (frquence exprime en mois), MCAL_RECUR_MONTHLY_WDAY (frquence exprime en mois, base sur le jour de la semaine), MCAL_RECUR_YEARLY (frquence exprime en annes). recur_interval (int) : frquence 1 (jour/semaine/mois/anne) sur recur_interval (ex . : un jour sur deux si recur_type = MCAL_RECUR_DAILY et recur_interval = 2) ;

j j

8. La gestion des dates et des calendriers

recur_data (int) : jours de la semaine pendant lesquels lvnement a lieu (si recur_type = MCAL_RECUR_WEEKLY). Cette valeur est la somme des valeurs suivantes : 1 = dimanche, 2 = lundi, 4 = mardi, 8 = mercredi, 16 = jeudi, 32 = vendredi, 64 = samedi). recur_enddate (objet date et heure) : date laquelle lvnement rcurrent sarrte ; alarm (int) : dlai (en minutes) prcdant lvnement pour lequel il faut dclencher une alarme.

j j

Lobjet date et heure, quant lui, possde les attributs publics suivants :
j j
year (int) : anne ; month (int) : mois ;

465

Chapitre 8

La gestion des dates et des calendriers

j j j j j

mday (int) : jour ; hour (int) : heure ; min (int) : minutes ; sec (min) : secondes ; alarm (min) : ce paramtre nest toutefois pas utilis.

Nous pouvons donc ajouter une mthode affichant (brut de fonderie) les proprits dun vnement.

Listing 8.14 : mcal_03_inc.php (extrait)


<?php // Extrait de la Classe MCAL_Agenda class MCAL_Agenda { // (...) function afficheEvenement($idEvenement, $mcal) { $evenement = mcal_fetch_event($mcal, $idEvenement); echo "<table>"; echo "<td colspan=\"2\" class=\"titreEvenement\">"; echo $evenement->title." (".$evenement->id."/"; if ($evenement->public) { echo "Publique"; } else { echo "Priv"; } echo ")</td></tr>\n"; echo "<tr><td>Catgorie</td><td>".$evenement->category."</td></tr>"; echo "<tr><td>Description</td>"; echo "<td>".$evenement->description."</td></tr>"; echo "<tr><td>Attributs Personnaliss</td>"; echo "<td>"; foreach ($evenement->attrlist as $nom => $valeur) { echo "$nom = $valeur<br />"; } echo "</td></tr>"; echo "<tr><td>Alarme</td>"; echo "<td>".$evenement->alarm." minutes avant</td></tr>"; $dateDebut = $evenement->start; echo "<tr><td>Dbut</td>"; echo "<td>".$dateDebut->mday."/".$dateDebut->month."/"; echo $dateDebut->year." ".$dateDebut->hour.":".$dateDebut->min; echo ":".$dateDebut->sec.; echo " (Alarme : ".$dateDebut->alarm.")</td></tr>";

8. La gestion des dates et des calendriers 466

Les gestionnaires dvnements

$dateFin = $evenement->end; echo "<tr><td>Fin</td><td>".$dateFin->mday."/".$dateFin->month."/"; echo $dateFin->year." ".$dateFin->hour.":".$dateFin->min; echo ":".$dateFin->sec." (Alarme : ".$dateFin->alarm.")</td></tr>"; echo "<tr><td>Frquence</td>"; echo "<td>"; switch ($evenement->recur_type) { case 0 : echo "Ponctuel"; break; case 1 : if ($evenement->recur_interval == 1) { echo "Quotidien"; } else { echo "1 jour sur ".$evenement->recur_interval; } break; case 2 : if ($evenement->recur_interval == 1) { echo "Hebdomadaire"; } else { echo "1 semaine sur ".$evenement->recur_interval; } echo "<br />Les "; if (($evenement->recur_data & 1)>0) echo "Dimanche "; if (($evenement->recur_data & 2)>0) echo "Lundi "; if (($evenement->recur_data & 4)>0) echo "Mardi "; if (($evenement->recur_data & 8)>0) echo "Mercredi "; if (($evenement->recur_data & 16)>0) echo "Jeudi "; if (($evenement->recur_data & 32)>0) echo "Vendredi "; if (($evenement->recur_data & 64)>0) echo "Samedi "; break; case 3 : if ($evenement->recur_interval == 1) { echo "Mensuel"; } else { echo "1 mois sur ".$evenement->recur_interval; } break; case 4 : echo "Tous les N-ime jour (Dim, Lun...) du mois."; if ($evenement->recur_interval == 1) { echo "Mensuel"; } else { echo "1 mois sur ".$evenement->recur_interval; } break; case 5 : if ($evenement->recur_interval == 1) { echo "Annuel"; } else { echo "1 an sur ".$evenement->recur_interval; } break; default : echo "????"; break;

8. La gestion des dates et des calendriers 467

Chapitre 8

La gestion des dates et des calendriers

} echo "</td></tr>"; $dateFinRecur = $evenement->recur_enddate; echo "<tr><td>Jusquau</td>"; echo "<td>".$dateFinRecur->mday."/".$dateFinRecur->month."/"; echo $dateFinRecur->year." "; echo $dateFinRecur->hour.":".$dateFinRecur->min; echo ":".$dateFinRecur->sec; echo " (Alarme : ".$dateFinRecur->alarm.")</td></tr>"; echo "</table>"; } } ?> Figure 8.6 : Fiche vnement

Il est galement possible de connatre la date du prochain vnement par rapport une date donne.

mcal_next_recurrence()
Retourne la date de lvnement suivant la date donne. Syntaxe

8. La gestion des dates et des calendriers

object mcal_next_recurrence(resource $idConnexion, int $weekstart, array $dateDebut) Identifiant de connexion tel que retourn par mcal_open(). Vraiment pas clair, le rle de cet argument ! Il ne semble avoir aucune influence sur le rsultat Tableau associatif contenant la date de dbut de recherche avec les cls : "year" pour lanne. "month" pour le mois. "mday" pour le jour. "hour" pour lheure. "min" pour les minutes. "sec" pour les secondes. Objet date.

$idConnexion $weekstart $dateDebut

retour

468

Les gestionnaires dvnements

Dnition des donnes des vnements


Linsertion de nouveaux vnements dans lagenda dbute par linitialisation des donnes de lvnement en cours de description par un appel mcal_event_init().

mcal_event_init()
Initialise une nouvelle description dvnement. Syntaxe $idConnexion retour boolean mcal_event_init(resource $idConnexion) Identifiant de connexion tel que retourn par mcal_open(). TRUE.

Il est ensuite possible de dfinir, pour lvnement en cours :


j j j j j j

Sa visibilit (publique ou prive) ; Son titre ; Sa description ; Sa catgorie ; Ses paramtres personnaliss ; Sa date.

mcal_event_set_class()
Fixe la visibilit (publique ou prive) de lvnement. Par dfaut, un vnement est priv. Syntaxe $idConnexion $visibilite retour boolean mcal_event_set_class(resource $idConnexion, boolean $visibilite) Identifiant de connexion tel que retourn par mcal_open().

8. La gestion des dates et des calendriers

Visibilit de lvnement (TRUE = publique, FALSE = prive). TRUE.

mcal_event_set_title()
Associe un nom lvnement. Syntaxe boolean mcal_event_set_title(resource $idConnexion, string $nom)

469

Chapitre 8

La gestion des dates et des calendriers

$idConnexion $nom retour

Identifiant de connexion tel que retourn par mcal_open(). Intitul de lvnement. TRUE.

mcal_event_set_description()
Associe un commentaire lvnement. Syntaxe $idConnexion $description retour boolean mcal_event_set_description(resource $idConnexion, string $description) Identifiant de connexion tel que retourn par mcal_open(). Descriptif de lvnement. TRUE.

mcal_event_set_category()
Associe une catgorie lvnement. Syntaxe $idConnexion $category retour boolean mcal_event_set_category(resource $idConnexion, string $category) Identifiant de connexion tel que retourn par mcal_open(). Catgorie de lvnement (il ny a pas de valeurs prdfinies : vous de les crer). TRUE.

8. La gestion des dates et des calendriers

mcal_event_add_attribute()
Associe lvnement un attribut personnalis. Syntaxe $idConnexion $attribut $valeur boolean mcal_event_add_attribute(resource $mcal, string $attribut, string $valeur) Identifiant de connexion tel que retourn par mcal_open(). Nom de lattribut personnalis. Valeur associe lattribut personnalis.

470

Les gestionnaires dvnements

Dnition des dates dapparition des vnements


Les dates des vnements sappuient sur plusieurs lments. En effet, les vnements ntant pas toujours ponctuels, prciser des dates de dbut et de fin se rvle souvent insuffisant. Vous serez donc probablement amen devoir prciser une frquence dapparition de lvnement. Un vnement pourra, en effet, avoir lieu un jour sur N, une semaine sur N, un mois sur N (en sappuyant soit sur le numro du jour dans le mois, soit sur le nom du jour de la semaine et le numro de la semaine dans le mois) ou bien encore un an sur N.

mcal_event_set_start()
Prcise la date de dbut (de la premire occurrence) de lvnement. Syntaxe boolean mcal_event_set_start(resource $idConnexion, int $annee, int $mois [, int $jour [, int $heure [, int $minute [, int $seconde]]]]) Identifiant de connexion tel que retourn par mcal_open(). Anne de dbut de lvnement. Mois de dbut de lvnement. Jour de dbut de lvnement. Heure de dbut de lvnement. Minutes de la date de dbut de lvnement. Secondes de la date de dbut de lvnement. TRUE.

$idConnexion $annee $mois $jour $heure $minute $seconde retour

mcal_event_set_end()
Prcise la date de fin (de la premire occurrence) de lvnement. Syntaxe boolean mcal_event_set_end(resource $idConnexion, int $annee, int $mois [, int $jour [, int $heure [, int $minute [, int $seconde]]]]) Identifiant de connexion tel que retourn par mcal_open(). Anne de dbut de lvnement. Mois de dbut de lvnement. Jour de dbut de lvnement. Heure de dbut de lvnement. Minutes de la date de fin de lvnement. Secondes de la date de fin de lvnement. TRUE.

8. La gestion des dates et des calendriers

$idConnexion $annee $mois $jour $heure $minute $seconde retour

471

Chapitre 8

La gestion des dates et des calendriers

mcal_event_set_recur_daily()
Prcise la frquence de lvnement sur la base des jours. Syntaxe $idConnexion $annee $mois $jour $frequence retour boolean mcal_event_set_recur_daily(resource $idConnexion, int $annee, int $mois, int $jour, int $frequence) Identifiant de connexion tel que retourn par mcal_open(). Anne de la date de fin de rcurrence de lvnement. Mois de la date de fin de rcurrence de lvnement. Jour de la date de fin de rcurrence de lvnement. Lvnement a lieu un jour sur $frequence. (Si $frequence = 0, lvnement est ponctuel.) TRUE.

mcal_event_set_recur_weekly()
Prcise la frquence de lvnement sur la base des semaines. Syntaxe boolean mcal_event_set_recur_weekly(resource $idConnexion, int $annee, int $mois, int $jour, int $frequence, int $joursSemaine) Identifiant de connexion tel que retourn par mcal_open(). Anne de la date de fin de rcurrence de lvnement. Mois de la date de fin de rcurrence de lvnement. Jour de la date de fin de rcurrence de lvnement. Lvnement a lieu une semaine sur $frequence. Indique quels jours de la semaine lvnement a lieu. Cette valeur est laddition des valeurs suivantes : 1 = dimanche, 2 = lundi, 4 = mardi, 8 = mercredi, 16 = jeudi, 32 = vendredi, 64 = samedi. TRUE.

$idConnexion $annee $mois $jour $frequence $joursSemaine

8. La gestion des dates et des calendriers

retour

mcal_event_set_recur_monthly_mday()
Prcise la frquence de lvnement sur la base des mois. Syntaxe boolean mcal_event_set_recur_monthly_mday(resource $idConnexion, int $annee, int $mois, int $jour, int $frequence)

472

Les gestionnaires dvnements

$idConnexion $annee $mois $jour $frequence retour

Identifiant de connexion tel que retourn par mcal_open(). Anne de la date de fin de rcurrence de lvnement. Mois de la date de fin de rcurrence de lvnement. Jour de la date de fin de rcurrence de lvnement. Lvnement a lieu un mois sur $frequence ( la mme date que le jour de dbut de la premire occurrence). TRUE.

Semaines incompltes Le comportement de cette fonction peut surprendre dans certains cas (mme sil reste assez logique). Si vous prenez lanne 2003, qui commence par un mercredi, et que vous souhaitez indiquer que, tout au long de lanne, vous aurez une runion le premier lundi du mois, vous prenez comme date de dbut de lvnement le lundi 6 janvier (premier lundi du mois de janvier, mais lundi de la seconde semaine du mois) : vous pointerez donc chaque mois sur le lundi de la seconde semaine du mois.

mcal_event_set_recur_monthly_wday()
Prcise la frquence de lvnement sur la base des mois (au mme jour de la mme semaine chaque mois). Syntaxe $idConnexion $annee $mois $jour $frequence retour boolean mcal_event_set_recur_monthly_wday(resource $idConnexion, int $annee, int $mois, int $jour, int $frequence) Identifiant de connexion tel que retourn par mcal_open(). Anne de la date de fin de rcurrence de lvnement. Mois de la date de fin de rcurrence de lvnement. Jour de la date de fin de rcurrence de lvnement. Lvnement a lieu un mois sur $frequence (le mme jour de la mme semaine que la date de dbut de la premire occurrence). TRUE.

8. La gestion des dates et des calendriers

mcal_event_set_recur_yearly()
Prcise la frquence de lvnement sur la base des annes. Syntaxe boolean mcal_event_set_recur_yearly(resource $idConnexion, int $annee, int $mois, int $jour, int $frequence)

473

Chapitre 8

La gestion des dates et des calendriers

$idConnexion $annee $mois $jour $frequence retour

Identifiant de connexion tel que retourn par mcal_open(). Anne de la date de fin de rcurrence de lvnement. Mois de la date de fin de rcurrence de lvnement. Jour de la date de fin de rcurrence de lvnement. Lvnement a lieu un an sur $frequence. TRUE.

Dclenchement de lalarme

mcal_event_set_alarm()
Prpare une alarme pour lvnement. Syntaxe $idConnexion $delaisRappel retour boolean mcal_event_set_alarm(resource $idConnexion, int $delaisRappel) Identifiant de connexion tel que retourn par mcal_open(). Indique, en minutes, combien de temps avant lchance lalarme doit se dclencher. TRUE.

Synthse des proprits dun vnement


Nous vous proposons de regrouper toutes ces proprits dans un objet "fait maison". Lintrt en est peut-tre limit, mais, comme il sagit dun objet, vous pouvez toujours lenrichir votre guise. Il permet toutefois de dfinir les proprits par des noms dattributs en franais (pour les non anglophones) et, surtout, de distinguer la dfinition de lobjet (assignation des valeurs des attributs) des "appels" aux calendriers (avec passage du paramtre $idConnexion). Cette dernire opration est ici ralise par une unique mthode prepare($idConnexion).

8. La gestion des dates et des calendriers

Listing 8.15 : mcal_evenement_inc.php (extrait)


<?php // Extrait de MCAL_Evenement class MCAL_Evenement { var var var var var var $visibilite; $titre, $description, $categorie; $dateDebut, $heureDebut; $dateFin, $heureFin; $frequenceType; $frequence;

474

Les gestionnaires dvnements

var $frequenceDateFin; var $frequenceJours; var $alarme; // Les attributs personnaliss var $monAttribut1, $monAttribut2; // Libre vous de construire // les mthodes setXX() et getXX() qui vont bien

// Stocke tous les attributs de lobjet // dans lvnement courant // (avant sauvegarde) function prepare($mcal) { mcal_event_init($mcal); if (isset($this->visibilite)) mcal_event_set_class($mcal, $this->visibilite); if (isset($this->titre)) mcal_event_set_title($mcal, $this->titre); if (isset($this->description)) mcal_event_set_description($mcal, $this->description); if (isset($this->categorie)) { mcal_event_set_category($mcal, $this->categorie); } if (isset($this->dateDebut)) { list($annee, $mois, $jour) = explode("-", $this->dateDebut); if (isset($this->heureDebut)) { list($heure, $minutes, $secondes) = explode(":", $this->heureDebut); } mcal_event_set_start($mcal, $annee, $mois, $jour, $heure, $minutes, $secondes); } if (isset($this->dateFin)) { list($annee, $mois, $jour) = explode("-", $this->dateFin); if (isset($this->heureFin)) { list($heure, $minutes, $secondes) = explode(":", $this->heureFin); } mcal_event_set_end($mcal,

8. La gestion des dates et des calendriers 475

Chapitre 8

La gestion des dates et des calendriers

$annee, $mois, $jour, $heure, $minutes, $secondes); } if (isset($this->frequenceType) && isset($this->frequenceDateFin) && isset($this->frequence)) { if (isset($this->frequenceDateFin)) { list($annee, $mois, $jour) = explode("-", $this->frequenceDateFin); } switch ($this->frequenceType) { case MCAL_RECUR_DAILY : mcal_event_set_recur_daily($mcal, $annee, $mois, $jour, $this->frequence); break; case MCAL_RECUR_WEEKLY : mcal_event_set_recur_weekly($mcal, $annee, $mois, $jour, $this->frequence, $this->frequenceJours); break; case MCAL_RECUR_MONTHLY_MDAY : mcal_event_set_recur_monthly_mday($mcal, $annee, $mois, $jour, $this->frequence); break; case MCAL_RECUR_MONTHLY_WDAY : mcal_event_set_recur_monthly_wday($mcal, $annee, $mois, $jour, $this->frequence); break; case MCAL_RECUR_YEARLY : mcal_event_set_recur_yearly($mcal, $annee, $mois, $jour, $this->frequence); break; default: // vnement ponctuel break; } } if (isset($this->alarme)) { mcal_event_set_alarm($mcal, $this->alarme); } if (isset($this->monAttribut1)) { mcal_event_add_attribute($mcal, "monAttribut1",$this->monAttribut1); }

8. La gestion des dates et des calendriers 476

Les gestionnaires dvnements

if (isset($this->monAttribut2)) { mcal_event_add_attribute($mcal, "monAttribut2",$this->monAttribut2); } } // (...) }

noter que, dans notre cas, nous avons un objet qui pourra contenir deux attributs personnaliss, que nous appellerons respectivement monAttribut1 et monAttribut2. Nous verrons un exemple dutilisation de cet objet un peu plus loin dans ce chapitre.

Consultation de lvnement en cours


Il est possible tout moment de consulter le contenu de lvnement en cours grce mcal_fetch_current_stream_event(). Ceci peut tre utile pour le dbogage, afin de vrifier ce que nous nous apprtons sauvegarder.

mcal_fetch_current_stream_event()
Retourne les proprits de lobjet en cours. Syntaxe $idConnexion retour object mcal_fetch_current_stream_event(resource $idConnexion) Identifiant de connexion tel que retourn par mcal_open(). Objet vnement.

cette fin, nous avons ajout une mthode lobjet MCAL_Evenement voqu prcdemment.

Listing 8.16 : mcal_evenement_inc.php (extrait)


<?php // Extrait de MCAL_Evenement class MCAL_Evenement { // (...) function toHTMLStringCurrentEvent($mcal) { $even = mcal_fetch_current_stream_event($mcal); $txt $txt $txt $txt $txt = .= .= .= .= ""; "Id = ".$even->id."<br />"; "Titre = ".$even->title."<br />"; "Visibilit = ".$even->public."<br />"; "Categorie = ".$even->category."<br />";

8. La gestion des dates et des calendriers 477

Chapitre 8

La gestion des dates et des calendriers

$txt .= "Description = ".$even->description."<br />"; $attrlist = $even->attrlist; $txt .= "monAttribut1 = ".$attrlist["monAttribut1"]."<br />"; $txt .= "monAttribut2 = ".$attrlist["monAttribut2"]."<br />"; $date = $txt .= $txt .= $txt .= $txt .= $date = $txt .= $txt .= $txt .= $txt .= $even->start; "debut = "; $date->year."-".$date->month."-".$date->mday; " ".$date->hour.":".$date->min.":".$date->sec; "<br />"; $even->end; "debut = "; $date->year."-".$date->month."-".$date->mday; " ".$date->hour.":".$date->min.":".$date->sec; "<br />";

$txt .= "frequenceType = ".$even->recur_type."<br />"; $txt .= "frequence = ".$even->recur_interval."<br />"; $txt .= "frequenceJours = ".$even->recur_data."<br />"; $date = $txt .= $txt .= $txt .= $even->recur_enddate; "frequenceDateFin = "; $date->year."-".$date->month."-".$date->mday; "<br />";

$txt.="Alarme = ".$even->alarm."<br />"; return $txt; } }

Sauvegarde des vnements


Enfin, pour sauvegarder lvnement, nous disposons de la fonction mcal_store_event().

8. La gestion des dates et des calendriers

mcal_store_event()
Enregistre lvnement en cours. ( lissue de cet appel, ltat de lvnement courant est indtermin. Il convient donc de faire un appel mcal_event_init().) Syntaxe $idConnexion retour int mcal_store_event(resource $idConnexion) Identifiant de connexion tel que retourn par mcal_open(). Identifiant de lvnement ainsi ajout, ou FALSE en cas dchec.

478

Les gestionnaires dvnements

mcal_append_event() Depuis la version 4.0, est apparue la fonction mcal_append_event(), qui semble avoir le mme comportement que mcal_store_event() (mme si la documentation PHP indique que lune sert modifier un vnement, tandis que lautre sert lajouter lagenda).
Ceci nous permet denrichir notre objet MCAL_Evenement avec une mthode sauve().

Listing 8.17 : mcal_evenement_inc.php (extrait)


<?php // Extrait de MCAL_Evenement class MCAL_Evenement { // (...) // Sauve lvnement function sauve($mcal) { $this->prepare($mcal); $id=mcal_store_event($mcal); if ($id !== FALSE) { $this->id=$id; } return $id; } }

Remarquez, quici, nous en profitons pour stocker lidentifiant de lvnement dans lobjet MCAL_Evenement. Maintenant, comme nous ne voulons pas avoir crit cette classe pour rien, nous allons lutiliser afin denregistrer un vnement dans lagenda. Mais, pour cela, un formulaire de saisie tant plus que pratique, nous allons ajouter cette classe une mthode permettant dafficher un formulaire adapt.

8. La gestion des dates et des calendriers

Listing 8.18 : mcal_evenement_inc.php (extrait)


<?php // extrait de MCAL_Evenement class MCAL_Evenement { // (...) /**

479

Chapitre 8

La gestion des dates et des calendriers

* Affiche un formulaire de saisie dvnement * * @param action string page appeler lors de lenvoi des donnes */ function afficheFormulaire($action="mcal_evenement_sauve.php") { echo "<form action=\"$action\" method=\"post\">\n"; echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"2\">\n"; echo "<tr class=\"champsdescription\"><td><b>Titre</b></td>"; echo "<td><input type=\"texte\" name=\"titre\"/></td>"; echo "<td><select name=\"visibilite\">"; echo "<option value=\"0\">Priv</option>"; echo "<option value=\"1\">Publique</option>"; echo "</select></td></tr>\n"; echo "<tr class=\"champsdescription\"><td><b>Catgorie</b></td>"; echo "<td colspan=\"2\"><select name=\"categorie\">"; echo "<option value=\"boulot\">Boulot</option>"; echo "<option value=\"loisirs\">Loisirs</option>"; echo "<option value=\"divers\">Divers</option>"; echo "</select></td>"; echo "</tr>\n"; echo "<tr class=\"champsdescription\"><td><b>Description</b></td>"; echo "<td colspan=\"2\"><textarea name=\"description\">"; echo "</textarea></td>"; echo "</tr>\n"; echo "<tr class=\"champsdescription\"><td><b>Salle</b>(*)</td>"; echo "<td colspan=\"2\"><input type=\"text\" name=\"salle\"></td>"; echo "</tr>\n"; echo "<tr class=\"champsdate\"><td><b>Date Dbut</b></td>"; echo "<td><input type=\"text\" name=\"dateDebut\" /></td>"; echo "<td>(AAAA-MM-JJ)</td>"; echo "</tr>\n"; echo "<tr class=\"champsdate\"><td><b>Heure Dbut</b></td>"; echo "<td><input type=\"text\" name=\"heureDebut\" /></td>"; echo "<td>(HH:MM:SS)</td>"; echo "</tr>\n"; echo "<tr class=\"champsdate\"><td><b>Date Fin</b></td>"; echo "<td><input type=\"text\" name=\"dateFin\" /></td>"; echo "<td>(AAAA-MM-JJ)</td>"; echo "</tr>\n"; echo "<tr class=\"champsdate\"><td><b>Heure Fin</b></td>"; echo "<td><input type=\"text\" name=\"heureFin\" /></td>"; echo "<td>(HH:MM:SS)</td>"; echo "</tr>\n"; echo "<tr class=\"champsfrequence\">"; echo "<td><b>Frquence</b></td>"; echo "<td>1 <select name=\"frequenceType\">"; echo "<option value=\"0\">(Evnement ponctuel)</option>"; echo "<option value=\"1\">Jour</option>"; echo "<option value=\"2\">Semaine</option>"; echo "<option value=\"3\">Mois (mme date)</option>"; echo "<option value=\"4\">Mois (mme jour,semaine)</option>";

8. La gestion des dates et des calendriers 480

Les gestionnaires dvnements

echo "<option value=\"5\">An</option>"; echo "</select></td>\n"; echo "<td>sur <input type=\"text\" name=\"frequence\"". " size=\"3\"></td>"; echo "</tr>\n"; echo "<tr class=\"champsfrequence\">"; echo "<td><b>Jours de la semaine</b><br />(si hebdomadaire)</td>"; echo "<td colspan=\"2\"><table><tr>"; echo "<td><input type=\"checkbox\" name=\"dimanche\" />Dimanche</td>"; echo "<td><input type=\"checkbox\" name=\"lundi\" />Lundi</td>"; echo "<td><input type=\"checkbox\" name=\"mardi\" />Mardi</td>"; echo "<td><input type=\"checkbox\" name=\"mercredi\" />Mercredi</td>"; echo "</tr><tr>"; echo "<td><input type=\"checkbox\" name=\"jeudi\" />Jeudi</td>"; echo "<td><input type=\"checkbox\" name=\"vendredi\" />Vendredi</td>"; echo "<td><input type=\"checkbox\" name=\"samedi\" />Samedi</td>"; echo "</tr></table></td></tr>\n"; echo "<tr class=\"champsfrequence\">"; echo "<td><b>Jusquau</b></td>"; echo "<td><input type=\"text\" name=\"frequenceDateFin\" /></td>"; echo "<td>(AAAA-MM-JJ)</td></tr>\n"; echo "<tr class=\"champsalarme\"><td><b>Prevenez moi</b></td>"; echo "<td colspan=\"2\">"; echo "<select name=\"alarme\">"; echo "<option value=\"0\">(pas)</option>"; echo "<option value=\"5\" selected=\"selected\">5 min.</option>"; echo "<option value=\"10\">10 min.</option>"; echo "<option value=\"15\">1/4 h.</option>"; echo "<option value=\"30\">1/2 h.</option>"; echo "<option value=\"60\">1 h.</option>"; echo "</select>"; echo " avant</td></tr>"; echo "<tr><td colspan=\"3\">"; echo "(*) Exemple dattribut personnalis</td></tr>\n"; echo "<tr><td colspan=\"3\" align=\"center\">"; echo "<input type=\"submit\" value=\"Ajouter\" />"; echo "</td></tr>"; echo "</table>\n"; echo "</form>"; } // (...) }

8. La gestion des dates et des calendriers

Ce formulaire aura lallure suivante (certes, il manque de fioritures, mais cest efficace) (voir fig. 8.7) : Lors de la validation du formulaire, la page mcal_evenement_sauve.php sera appele. Celle-ci a donc pour mission de copier les paramtres issus de la mthode POST dans un objet MCAL_Evenement et dappeler tout bonnement la mthode sauve() aprs avoir ouvert une connexion sur lagenda.

481

Chapitre 8

La gestion des dates et des calendriers

Figure 8.7 : Formulaire de saisie dvnement

Listing 8.19 : mcal_evenement_sauve.php


<?php include("mcal_03_inc.php"); include("mcal_evenement_inc.php"); // Connexion lagenda $mcal = MCAL_Agenda::connect();

// Instanciation dun objet MCAL_Evenement // (objet construit par nos soins) $evenement = new MCAL_Evenement(); // Copie des donnes issues du formulaire // dans la structure de lobjet $evenement->visibilite $evenement->titre $evenement->categorie $evenement->description $evenement->monAttribut1 $evenement->dateDebut $evenement->heureDebut $evenement->dateFin $evenement->heureFin = = = = $_POST["visibilite"]; stripslashes($_POST["titre"]); $_POST["categorie"]; stripslashes($_POST["description"]);

8. La gestion des dates et des calendriers

= $_POST["salle"]; = $_POST["dateDebut"]; = $_POST["heureDebut"]; = $_POST["dateFin"]; = $_POST["heureFin"];

$evenement->frequenceType = $_POST["frequenceType"]; $evenement->frequence = $_POST["frequence"]; if ($evenement->frequenceType == 2) {

482

Les gestionnaires dvnements

+= 64; } $evenement->frequenceDateFin = $_POST["frequenceDateFin"]; $evenement->alarme = $_POST["alarme"];

$evenement->frequenceJours = 0; if ($_POST["dimanche"] == "on") $evenement->frequenceJours if ($_POST["lundi"] == "on") $evenement->frequenceJours if ($_POST["mardi"] == "on") $evenement->frequenceJours if ($_POST["mercredi"] == "on") $evenement->frequenceJours if ($_POST["jeudi"] == "on") $evenement->frequenceJours if ($_POST["vendredi"] == "on") $evenement->frequenceJours if ($_POST["samedi"] == "on") $evenement->frequenceJours

+= 1; += 2; += 4; += 8; += 16; += 32;

$id = $evenement->sauve($mcal); ?> <html> <body> <h1>Enregistrement dun vnement</h1> <?php if ($d !== FALSE) { echo "Votre nouvel vnement a t enregistr (avec lidentifiant". " $id)"; } else { echo "La tentative denregistrement de lvnement chou"; } echo $evenement->toHTMLString(); ?> </body> </html>

8. La gestion des dates et des calendriers

Utilisation de stripSlashes() Comme les paramtres titre et description sont des chanes de caractres librement saisies par lutilisateur, ils peuvent contenir (entre autres) des apostrophes. Or, par dfaut, PHP est configur avec loption magic_quotes_gpc = on, ce qui fait que les valeurs passes par les mthodes POST, et GET ou par cookies voient leurs apostrophes prcdes dun anti-slash (comme le fait la fonction addSlashes()). Il faut les supprimer, car, bien que fort utiles dans le cas dun ajout dans une base de donnes, ils sont gnants lorsque les valeurs sont simplement passes en paramtre dune fonction (ici les fonctions mcal).

483

Chapitre 8

La gestion des dates et des calendriers

Oprations sur les vnements enregistrs


Une fois lvnement enregistr, il est tout de mme possible de supprimer facilement lalarme qui lui est associe par un appel la fonction mcal_snooze().

mcal_snooze()
Supprime lalarme associe un vnement. Syntaxe $idConnexion $idEvenement retour boolean mcal_snooze(resource $idConnexion, int $idEvenement) Identifiant de connexion tel que retourn par mcal_open(). Identifiant de lvnement. TRUE.

La bibliothque propose une fonction qui est cense retourner la liste des vnements ayant une alarme programme la date donne. Mais il est difficile den tirer quelque chose. En voici tout de mme la syntaxe (corrige par rapport celle propose par la documentation PHP) :
array mcal_list_alarms(resource $idConnexion[, int $annee [, int $mois [, int $jour [, int $heure [, int $minutes [, int $secondes]]]]]])

Et, bien videmment, il est possible de supprimer un vnement de lagenda par un appel mcal_delete_event().

mcal_delete_event()
Supprime un vnement. Syntaxe $idConnexion boolean mcal_delete_event(resource $idConnexion, resource $idEvenement) Identifiant de connexion tel que retourn par mcal_open(). Identifiant de lvnement supprimer. TRUE (mme si lvnement nexiste pas).

8. La gestion des dates et des calendriers

$idEvenement retour

Divers
La bibliothque MCAL prsente des fonctions destines la manipulation des agendas (dans leur ensemble). Il sagit des fonctions mcal_create_calendar(), mcal_rename_calendar(), mcal_delete_calendar(), mais celles-ci ne semblent pas avoir t vritablement implmentes et se contentent de retourner TRUE.

484

Chapitre 9

La gestion des chiers et des rpertoires


9.1 9.2 9.3 Le systme de chiers POSIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 Accder au systme de chiers du serveur . . . . . . . . . . . . . . . . . . . . . . . . 490 Les streams ou les ux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593

Le systme de fichiers POSIX

a manipulation et le traitement des donnes ncessitent, voire imposent, de pouvoir stocker celles-ci une fois le travail et les diffrentes oprations effectus. Mme si, souvent, lutilisation dune base de donnes est plus efficace, le stockage sur le disque reste une solution simple mettre en uvre, et parfois mme la seule solution pertinente. Dans ce chapitre, nous allons voir comment le langage PHP peut permettre de lister, lire et crire des fichiers. Tout au long de ce chapitre, nous allons mettre en place diffrentes fonctions qui nous permettront, au final, de dvelopper un explorateur de fichiers simple et sympa (attention toutefois : il nest pas laisser entre toutes les mains). Dans une deuxime partie, nous allons voir comment il est possible daccder au systme de fichier, rseau, socket laide dune mthode introduite avec PHP 4.3 et disponible galement sur PHP 5 : Les streams ou flux.

9. La gestion des fichiers et des rpertoires

9.1.

Le systme de chiers POSIX

Mme si vous tes un adepte des produits Microsoft, il est probable que votre application sera hberge sur une plateforme de type UNIX/Linux. Cest en effet le systme dexploitation adopt par la majorit des hbergeurs quils soient ou non gratuits. Nous vous offrons donc, ici, un petit cours de rattrapage en faisant un point sur les spcificits du systme de fichiers de ces systmes dexploitation (ceci est valable pour tous les systmes de fichiers la norme POSIX que sont Linux et tous les UNIX modernes). Mme si, petit petit, Windows tente (pniblement) de rattraper son retard en termes de scurit, avec UNIX/Linux, les droits des utilisateurs ne sont dj pas un vain mot. Ainsi, lutilisateur devra ncessairement sidentifier pour se connecter au systme, ce qui constitue la base de la scurit de la machine. UNIX tant, ds son origine, un systme multi-utilisateur, il a t conu de sorte que les fichiers ne soient accessibles qu certains utilisateurs et certains groupes dutilisateurs. Seul ladministrateur, appel le plus souvent "root", possde tous les droits sur tous les fichiers du systme (sil existait des virus dans un environnement UNIX/Linux, il faudrait encore quils accdent au compte "root" pour causer des dommages irrparables ; de mme, un utilisateur protgeant ses fichiers vis--vis des autres utilisateurs ne pourrait tre contamin). Chaque utilisateur peut appartenir un ou plusieurs groupes que lon dfinira librement (ex. : groupe des chercheurs, des invits, des utilisateurs du service web, etc). Chaque fichier est la proprit dun utilisateur et dun groupe dutilisateurs. Ainsi, si vous listez le contenu dun rpertoire dun systme UNIX/Linux (si vous faites appel aux services dun hbergeur, vous pouvez, par exemple, vous connecter sous votre compte FTP, et taper la commande ls), vous observerez une srie de lignes ayant lallure suivante :
rwxrwr 1 laurent user 985540 Mai 4 09:16 Monfichier

Chaque ligne est associe un fichier ou un rpertoire dont le nom est prcis dans la dernire colonne (ici : Monfichier).

On ne rigole pas avec la casse... UNIX respecte la casse. Faites donc bien attention au respect des majuscules et minuscules des noms de fichiers et rpertoires. Vous pouvez trs bien avoir un fichier nomm toto.txt qui coexiste, dans le mme rpertoire, avec un fichier toto.TXT.

487

Chapitre 9

La gestion des fichiers et des rpertoires

Les troisime et quatrime colonnes nous indiquent que le propritaire du fichier est "laurent" et que le groupe auquel appartient le fichier est "user".

9. La gestion des fichiers et des rpertoires

Mais attention, ce nest pas parce que le fichier appartient "laurent" et au groupe "user" que Laurent et les membres du groupe "user" ont tous les droits, ni non plus que tous les autres utilisateurs nont aucun droit sur ce fichier. Les permissions sont dfinies ici par les proprits -rwxrw-r-- quil faut dcomposer en un caractre suivi de trois blocs de trois caractres. Nous reviendrons plus tard sur ce premier caractre. Le premier bloc de trois caractres prcise les droits de lutilisateur, le bloc suivant ceux des membres du groupe et enfin le dernier bloc de trois caractres indique les droits des autres utilisateurs. Chaque bloc se dcompose ainsi : 1. Un premier caractre pouvant prendre la valeur "r" pour indiquer que le fichier est accessible en lecture (pour lutilisateur, les membres du groupe ou les autres, selon les cas) ou "-" sinon. Dans le cas dun rpertoire, ceci indique que lon peut lister le contenu du rpertoire. Un second caractre pouvant prendre la valeur "w" pour indiquer que le fichier est accessible en criture (pour lutilisateur, les membres du groupe ou les autres, selon les cas), ce qui inclut la possibilit deffacer le fichier ou "-" sinon. Dans le cas dun rpertoire, ceci indique que lon peut modifier les fichiers contenus dans le rpertoire ( condition que les droits individuels des fichiers le permettent). Un troisime caractre pouvant prendre la valeur "x" pour indiquer que le fichier peut tre excut (par lutilisateur, les membres du groupe ou les autres, selon les cas) condition, toutefois, que ce soit un "excutable" ou "-" sinon. Dans le cas dun rpertoire, ceci indique que lon peut se dplacer dans le rpertoire.

2.

3.

Dans notre exemple, nous pouvons donc dire que le fichier est accessible en lecture, criture et excution pour lutilisateur. Le groupe possde les permissions en lecture et criture, mais ne peut pas excuter le fichier. Enfin, les autres utilisateurs ne sont autoriss qu la lecture. Les droits ne sont gnralement pas spcifis sous forme alphabtique, mais sous la forme dun nombre exprim en octal (base 8) et compos de trois chiffres (prcds dun 0 pour indiquer PHP quil sagit dun nombre en octal et non en dcimal). Chaque chiffre reprsente les droits dune catgorie (propritaire, groupe et autres). Pour chaque catgorie, il faut faire la somme des valeurs de chaque droit en considrant que r=4, w=2 et x=1. Imaginons, pour prendre un exemple, un fichier possdant les droits rwx pour lutilisateur, rx pour le groupe et r pour toutes les autres personnes.

Tableau 9.1 : Les droits en octal donnent pour le cas prsent : 0754
Propritaire Read(r) = 4 Write(w) = 2 Execute(x) = 1 Total Oui Oui Oui 4+2+1=7 Groupe Oui Non Oui 4+0+1=5 Autres Oui Non Non 4+0+0=4

Retenez bien cette leon, nous nous en resservirons un peu plus tard.

488

Le systme de fichiers POSIX

Revenons maintenant au premier caractre de la chane indiquant les droits du fichier. Il prcise le type du "fichier". Ici, "" indique que cest un fichier classique, mais cela aurait pu tre un rpertoire reprsent par la lettre "d", un priphrique dfini par "b" ou "c", ou un encore un lien symbolique associ la lettre "l". Vous savez tous ce quest un fichier ou un rpertoire (mme si certains ont russi imposer leur terminologie et parlent de dossier). Afin de ne pas nous tendre davantage sur les spcificits Linux/UNIX, nous ne parlerons pas des priphriques. Mais, afin de mieux comprendre certaines fonctions proposes par PHP, il est bon de vous prsenter ce quest un lien. Sous Linux/UNIX, il est possible de crer un "fichier" (une entre dans un rpertoire) qui sera en fait un lien, dit lien symbolique, vers un "vrai" fichier. Sous Windows, vous connaissez un ersatz du lien symbolique appel "raccourci". Double-cliquer sur un raccourci Windows revient double-cliquer sur le fichier point. En revanche, si vous souhaitez accder au contenu du raccourci, vous naccderez qu un fichier descripteur et non au contenu du fichier point. Sous Linux/UNIX, que vous accdiez au lien symbolique ou directement au fichier, le rsultat est le mme. Il existe une variante du lien symbolique appel lien physique, mais la nuance est subtile. Alors que le lien symbolique est un renvoi vers le fichier, le lien physique est une copie du descripteur de fichier. De ce fait, contrairement au lien physique, si vous supprimez le fichier "original", le lien symbolique nest plus valide. Dans les lignes retournes par la commande ls (via FTP ou ls l en accs direct sur le systme), le chiffre suivant correspond au nombre de liens physiques vers le fichier. Dans notre exemple, 1 signifie que le fichier ne possde aucun lien mis part lui-mme. Le nombre qui suit le groupe dappartenance du fichier est le poids (la taille) en octets. Ensuite, on retrouve la date de la dernire modification du fichier.

9. La gestion des fichiers et des rpertoires

Point et point-point sont dans un rpertoire... Pour chaque rpertoire vous noterez deux fichiers portant des noms particuliers : il sagit de "." et "..". Point est, en fait, une reprsentation du rpertoire courant, et point-point une reprsentation du rpertoire suprieur. Cest un point ;-) connatre lorsque vous souhaitez en lister le contenu.

Les chiers textes, les chiers binaires


Les fichiers peuvent tre rangs en deux catgories : les fichiers textes et les fichiers binaires. Dans le premier cas, ce sont des fichiers qui ne contiennent que des lignes de texte ; ce peut tre un document quelconque, un listing de programme ou des donnes textes. Le fichier binaire est destin contenir des donnes brutes qui ne peuvent pas tre sectionnes en lignes. Ce sont, en rgle gnrale, des fichiers de type image ou des donnes complexes comme des fichiers de traitement de texte ou de tableur. Sous un systme de type UNIX, la diffrence entre les fichiers textes et binaires concerne les traitements de fin de fichier et de fin de lignes. Alors quun fichier texte est spar en lignes termines par un "\n" et que la fin du fichier est identifie par un "\0", la fin dun fichier de type binaire est donne par le systme dexploitation lui-mme. Cest sa taille en octets qui indique que le fichier a t entirement lu et, donc, que le pointeur de lecture est arriv la fin du fichier. Il est, de ce fait, inutile de spcifier le mode binaire dans vos fonctions douverture de fichier.

489

Chapitre 9

La gestion des fichiers et des rpertoires

UNIX, conforme la norme POSIX, ne fait aucune diffrence entre un fichier binaire et un fichier texte.

9. La gestion des fichiers et des rpertoires

En revanche, lorsque vous manipulez un fichier avec Windows, il est ncessaire de prciser si le fichier ouvrir est de type texte ou binaire. Par dfaut, il sera considr comme tant de type texte.

Fins de lignes
Attention galement aux fins de lignes sous Windows. Toutes les lignes sont spares par le couple de caractres \r\n, qui indique de passer la ligne suivante. Lorsque vous passez un fichier dun systme un autre, nhsitez pas effectuer une conversion du fichier texte laide de la commande UNIX dos2unix ou depuis votre diteur sil en possde loption (cest le cas dUltraEdit par exemple). Ce dtail, qui peut paratre insignifiant, peut se rvler source de problmes dans bien des cas.

9.2.

Accder au systme de chiers du serveur

Lire et crire le contenu dun chier


La mthodologie pour traiter un fichier est la suivante :
j j j

Ouverture du fichier ; Opration sur le fichier (lecture, criture, lecture et criture) ; Fermeture du fichier.

Ouvrir et fermer un chier


Louverture dun fichier se fait laide de linstruction fopen(). Linstruction retourne un descripteur de fichier qui servira par la suite lors des oprations dentre et de sortie. Il est ncessaire de donner la fonction le mode douverture (lecture, criture, lecture et criture, etc.) du fichier. Notez que cette fonction permet aussi douvrir des "fichiers" distants en donnant une URL la place du chemin du fichier. Notez que vous ne pouvez pas utiliser les ouvertures de fichiers distance si vous avez compil PHP avec loption --disable-url-fopen-wrapper pour PHP 4.0.3, ou initialis le paramtre allow_url_fopen off dans le fichier php.ini pour les versions suprieures de PHP.

fopen()
Ouverture dun fichier ou dune URL. Syntaxe resource fopen(string $nomFichier, string $mode [, int $cheminInclude [, resource $contexte]])

490

Accder au systme de fichiers du serveur

$nomFichier $mode

Chemin du fichier, URL (HTTP ou FTP) du fichier ou encore entre/sortie standard.

9. La gestion des fichiers et des rpertoires

Dfinit le mode douverture du fichier : "r" pour la lecture seule (le fichier doit exister). "r+" pour une lecture et une criture (le fichier doit exister). "w" pour une criture avec crasement des donnes. "w+" pour un mode en lecture et criture avec crasement des donnes (si le fichier nexiste pas, il sera cr). "a" pour louverture en ajout de donnes. "a+" pour louverture du fichier en mode lecture et criture par ajout (si le fichier nexiste pas, il sera cr). Sous Windows, vous pouvez accoler lun des arguments suivants : "t" (valeur par dfaut) signalant que le fichier est un fichier texte. "b" qui dsigne un fichier binaire. TRUE si le fichier doit tre recherch dans les rpertoires prciss dans include_path., FALSE sinon. La valeur par dfaut est FALSE. Paramtre optionnel, utilisable depuis les versions 4.3 de PHP, spcifiant la ressource de contexte cre par stream_context_create() utiliser. Voir le sous-chapitre sur les flux pour plus de renseignements sur les contextes de flux. Retourne un pointeur sur le fichier, ou FALSE en cas derreur.

$cheminInclude $contexte

retour

include_path La variable include_path est dfinie dans le php.ini et spcifie PHP une liste de dossiers o les fonctions comme include() ou require() vont chercher les fichiers.

Vous pouvez vous reporter au chapitre "Prise en main" pour plus de dtails sur le fichier php.ini.
Le nom du fichier peut tre indiqu sous diffrentes formes :
j j

Un chemin de fichier ; fopen() tentera alors daccder ce fichier dans le mode demand. Une URL du style http://www.toto.com et, dans ce cas, une connexion HTTP est ouverte sur le serveur. Lidentifiant retourn pointe sur le document. Notez que vous ne pouvez ouvrir ces fichiers quen lecture seule. Vous pouvez galement accder des fichiers sur un serveur demandant une autorisation daccs. Pour cela, vous devez passer, dans lURL, lidentifiant de lutilisateur ainsi que son mot de passe de la faon suivante : http://utilisateur:motdepasse@domaine.com. Une adresse FTP. Une connexion FTP est cre avec le serveur. Vous pouvez ouvrir les fichiers en lecture ou en criture. Les doubles modes lecture et criture (mode full duplex) ne sont pas supports. Pour lauthentification, utilisez la syntaxe identique une

491

Chapitre 9

La gestion des fichiers et des rpertoires

9. La gestion des fichiers et des rpertoires

authentification HTTP : ftp://utilisateur:motdepasse@ftp.domaine.com. Notez que le serveur distant doit supporter le mode passif ; dans le cas contraire la connexion ne pourra seffectuer.
j

Une entre/sortie standard du style php://. Ce peut-tre php://stdin pour lentre standard, php://stdout pour la sortie standard ou php://stderr pour la sortie derreur.

Les actions effectuer sur le fichier sont dfinir ds son ouverture. Cest le mode du fichier qui indique la fonction fopen() pour quelle opration le fichier est ouvert.
<?php $fp = fopen("/home/laurent/data.txt", "a"); // Ouverture du fichier data.txt en ajout de donnes $fp = fopen("http://www.linux.org/", "r"); // Ouverture de lURL distante http://www.linux.org $fp = fopen("http://utilisateur:motdepasse@localhost/", "r"); // Ouverture dune URL demandant une authentification $fp = fopen("ftp://utilisateur:motdepasse@ftp.tuxfamily.org/", "w"); // Ouverture dune connexion FTP avec lutilisateur et le mot de passe dfinie ?>

La partie du nom de fichier du genre http://, ftp://, php:// fait rfrence un gestionnaire de flux (les streams). Il en existe dautres. Nous verrons en particulier celui charg de la gestion des fichiers compresss et nous verrons galement quil est possible de dfinir ses propres gestionnaires.

Pour plus dinformations, reportez-vous plus loin au chapitre Les steams ou les flux

Droits de proprit... Noubliez pas quUNIX gre les droits de lecture et dcriture. Si vous utilisez FTP pour uploader un fichier sous votre compte utilisateur (avec les droits qui lui sont propres), le serveur HTTP naura pas forcment les permissions pour y accder (en lecture ou en criture). Vous devrez alors modifier les droits via votre accs FTP et la commande chmod. Par exemple, pour donner tous les droits :
chmod 777 monfichier

Le chemin des fichiers sous Windows Sous Windows, le caractre habituellement utilis pour sparer les noms des rpertoires est lanti-slash ; assurez-vous bien de doubler ces anti-slashes.
<?php $fp = fopen("c:\\Rep1\\Rep2\\data.txt", "a"); ?>

492

Accder au systme de fichiers du serveur

Fichiers HTTP
Pour les fichiers accds via HTTP, len-tte retourn par le serveur ne fait pas partie des donnes accessibles laide de lidentifiant de fichier. Il est toutefois possible dy accder via la variable globale $http_response_header (attention, cette variable est bien en minuscules et non en majuscules). Celle-ci contient alors un tableau index o chaque entre est une ligne de len-tte. partir de PHP 4.3, vous devez utiliser la fonction file_get_wrapper_data()() pour rcuprer cette information.

9. La gestion des fichiers et des rpertoires

le_get_wrapper_data()
Retourne len-tte HTTP dun fichier ouvert ( partir de PHP 4.3). Syntaxe $fp retour array file_get_wrapper_data(resource $fp) Pointeur du fichier tel que retourn par fopen(). Tableau index o chaque entre est une ligne de len-tte.

Fichiers temporaires
En supposant que vous ayez plusieurs fichiers manipuler la fois, il est probable que vous soyez amen utiliser des fichiers temporaires. Vous pouvez bien entendu crer ces fichiers avec la fonction fopen() et les supprimer une fois que la manipulation a t effectue avec linstruction unlink(), mais le langage PHP possde une fonction adquate pour grer ces fichiers. La commande tmpfile() ouvre un fichier sous un nom unique et retourne un pointeur. Le fichier est automatiquement dtruit lorsque la ressource est libre avec linstruction fclose().

tmple()
Crer un fichier temporaire en mode criture seule et retourne un identifiant unique permettant dcrire dans ce fichier. Syntaxe retour resource tmpfile(void) Retourne un pointeur de fichier.

<?php $fpT = tmpfile(); // Traitements divers fclose($fpT); ?>

493

Chapitre 9

La gestion des fichiers et des rpertoires

Fermeture des chiers


9. La gestion des fichiers et des rpertoires
La fermeture des fichiers ainsi ouverts se fait laide de la fonction fclose(). La fonction a pour objectif de librer les ressources utilises. Attention, si vous oubliez de fermer vos fichiers, vous risquez de perdre des donnes.

fclose()
Ferme un fichier pralablement ouvert. Syntaxe $fp retour boolean fclose(resource $fp) Pointeur du fichier tel que retourn par fopen(), tmpfile() ou fsockopen(). TRUE en cas de russite, FALSE sinon.

Si le pointeur de fichier nest pas valide, la fonction renvoie une erreur.


<?php $fp = fopen("monfichier.txt", "a"); // Traitements divers if (fclose($fp)) { echo "Le fichier monfichier.txt a t correctement ferm !"; } else { echo "Le fichier monfichier.txt na pas t ferm !"; } ?>

fsockopen() est une fonction douverture dune socket de connexion. Rendez-vous dans le chapitre "La gestion des protocoles" pour plus dinformations sur le sujet.

crire dans un chier


Pour crire dans un fichier, vous disposez de la fonction fwrite().

fwrite()
criture dune chane de caractres dans un fichier. Syntaxe $fp $chaine int fwrite(resource $fp, string $chaine [, int $longueur]) Identifiant de fichier tel que retourn par fopen(), popen(), tmpfile() ou fsockopen(). Chane de caractres crire dans le fichier.

494

Accder au systme de fichiers du serveur

$longueur retour

Paramtre optionnel indiquant combien de caractres doivent tre crits. Sil est omis, la chane complte est crite dans le fichier.

9. La gestion des fichiers et des rpertoires

Nombre de caractres qui ont t crits dans le fichier. En cas derreur, linstruction retourne FALSE.

La fonction fwrite() dispose dun alias appel fputs(). Les deux fonctions sont donc utilises de la mme faon.

criture binaire Notez bien que la fonction fwrite() nexcepte quune chane de caractres comme paramtre. Si vous souhaitez crire des donnes binaires, vous devrez convertir au pralable la valeur de chaque octet en son quivalent ASCII. Ainsi, fwrite($fp, 255); stockera la chane de caractres "255" et non un octet ayant la valeur 255 (comme on pourrait sy attendre). Pour ajouter au fichier loctet ayant la valeur 255, il faut utiliser lappel suivant : fwrite($fp, chr(255));.
Les quelques fonctions vues jusque-l nous permettent dcrire un petit programme qui pourrait constituer la base dun systme de discussion. En effet, ce script crit, dans un fichier texte, des messages envoys laide dun formulaire HTML. Le fichier rsultant possde une ligne par message et contient la date du message, le pseudo de lutilisateur, et le message lui-mme, les lments tant spars par une tabulation. Nous pourrons donc, par la suite, afficher la liste des derniers messages qui ont t crits dans le fichier texte.

Listing 9.1 : fwrite.php


<?php // Vrifie que les donnes sont bien postes if ($_POST["message"] && $_POST["pseudo"]) { // Ouverture du fichier en criture (mode ajout) $fp = fopen("message.txt", "a+"); // Rcupration de lheure $heure = date(H:m:s); // Ecriture de lheure et dune tabulation fwrite($fp, $heure."\t"); // Ecriture du pseudo et dune tabulation /* On utilise linstruction htmlEntities afin de convertir les caractres spciaux dans leur version HTML */ fwrite($fp, htmlEntities($_POST["pseudo"])."\t"); // Ecriture du message fwrite($fp, htmlEntities($_POST["message"])."\n"); // On ferme le fichier. fclose($fp);

495

Chapitre 9

La gestion des fichiers et des rpertoires

} ?>

9. La gestion des fichiers et des rpertoires

<html> <title>Ecrire des messages dans un fichier</title> </head> <body> <table border="0" width="100%"> <tr> <form method="post"> <td width="600"> pseudo: <input type="text" name="pseudo" value="<?php htmlEntities($_GET["pseudo"]); ?>" size="20" maxlength="20"> message: <input type="text" name="message" size="40" maxlength="255"> <input type="submit" name="envoyer" VALUE="&gt;&gt;"> </td> </form> <td>&nbsp;</td> </tr> </body> </html>

Le fichier rsultant prsente alors cette forme :


15:07:48<tab>Laurent<tab>Cest bon, je suis enfin en vacances ! 15:07:50<tab>Damien<tab>Non mais tu r&ecirc;ves... tu as un chapitre &agrave; rendre ! 15:07:49<tab>Pem<tab>Hi hi hi... :) 15:07:48<tab>Laurent<tab>Groupf... Je vais devoir y passer la nuit l&agrave; ! 15:07:49<tab>Thomas<tab>Tu devrais faire comme moi. 15:07:00<tab>Thomas<tab>Des jours que je ne dors plus ! 15:07:10<tab>Thomas<tab>Mon secret ? La caf&eacute;ine !

Il est temps de passer la lecture du contenu dun fichier.

Lire des informations dans un chier


La lecture des donnes contenues dans un fichier peut se faire octet par octet, bloc de N octets par bloc de N octets, ligne par ligne ou encore dun bloc. Ceci est assur par les diffrentes fonctions que sont fread(), fgets(), fgetss(), fgetc() et deux instructions particulires que sont file() et readfile().

Lecture octet par octet


Tout comme le langage C, PHP possde la fonction fgetc() qui retourne le caractre se trouvant la position courante du pointeur de fichier. Notez quen langage C ce nest pas le caractre qui est retourn, mais son code ASCII.

496

Accder au systme de fichiers du serveur

fgetc()
Retourne le caractre se trouvant la position courante du pointeur de lecture. Syntaxe $fp retour string fgetc(resource $fp) Identifiant de fichier tel que retourn par fopen(), popen()ou fsockopen(). Le caractre se trouvant la position courante, ou FALSE si cest la fin du fichier.

9. La gestion des fichiers et des rpertoires

Lecture N octets par N octets


fread() a pour objectif de lire des donnes dans un fichier, la lecture se faisant paquet doctets

par paquet doctets (ce qui est habituellement utilis pour les fichiers binaires ou pour ceux formats sur la base de chanes de caractres de longueur constante).

fread()
Lecture des donnes contenues dans un fichier. Syntaxe $fp $nbOctet retour string fread(resource $fp, int $nbOctet) Identifiant de fichier tel que retourn par fopen(), popen()ou fsockopen(). Nombre doctets qui doivent tre lus. Chane contenant les donnes lues, ou FALSE si cest la fin du fichier.

Pour lire le contenu du fichier prcdemment gnr, nous pourrions donc envisager dcrire le script suivant :

Listing 9.2 : fread.php


<?php // Reprenons notre fichier message.txt. $fp = fopen("message.txt","r"); // Lecture du fichier jusqu la fin de celui-ci. while ($lecture = fread($fp, 70)) { // Affichage des 70 caractres lus puis // retour la ligne. echo $lecture."<br />"; } fclose($fp); ?>

497

Chapitre 9

La gestion des fichiers et des rpertoires

Ce qui donnerait :

9. La gestion des fichiers et des rpertoires

22:06:38 Laurent Cest bon, je suis enfin en vacances ! 22:07:10 Damie n Non mais tu rves... tu as un chapitre rendre ! 22:07 :26 Pem Hi hi hi... :) 22:08:01 Laurent Groupf... Je vais devoir y pas ser la nuit l ! 22:08:30 Thomas Tu devrais faire comme moi. 22 :08:30 Thomas Des jours que je ne dors plus ! 22:08:39 Thomas Mon secr et ? La cafine !

Certes, tout le contenu y est (en HTML, les tabulations apparaissent comme une simple espace). Mais pour la mise en forme... ce nest pas a ! En fait, plutt que de lire le fichier 70 caractres par 70 caractres, il aurait t prfrable de le lire ligne par ligne. Mais fread() ne tient pas compte des retours la ligne. Nous vous rassurons tout de suite, nous allons trouver une solution !

Lire en une fois Il est possible de lire un fichier texte en une seule fois simplement en passant en argument de taille la taille du fichier texte. Vous devrez alors utiliser linstruction fileSize() qui nous retourne la taille du fichier en octets (cette fonction est dcrite plus loin dans ce chapitre).
<?php // Ouverture du fichier message.txt. $fp = fopen("message.txt","r"); // Rcupration de la taille du fichier en octets. $taille = fileSize("message.txt"); // Lecture de la totalit du fichier. $lecture = fread($fp, $taille); // Affichage du fichier. echo $lecture; fclose($fp); ?>

Lecture ligne par ligne


Comme vous lattendiez, vous pouvez galement lire le fichier ligne par ligne. La fonction fgets() permet de retourner la ligne courante (o se trouve le pointeur). La lecture de la ligne se termine lorsque le caractre retour chariot \n est trouv, lorsque le nombre de caractres maximum est lu, ou lorsque la fin du fichier a t dtecte.

fgets()
Lecture de la ligne courante du fichier. Syntaxe string fgets(resource $fp, int $nbOctet)

498

Accder au systme de fichiers du serveur

$fp $nbOctet retour

Identifiant de fichier tel que retourn par fopen(), popen()ou fsockopen().

9. La gestion des fichiers et des rpertoires

Nombre doctets qui doivent tre lus. Chane contenant les donnes lues de la ligne courante, ou FALSE si le pointeur est en fin de fichier.

La lecture du fichier peut alors se faire comme suit :

Listing 9.3 : fgets.php


<?php // Ouverture du fichier $fp = fopen("message.txt","r"); // Lecture de chaques ligne // jusqu la fin du fichier while ($lecture = fgets($fp,255)) { // Affichage de la ligne echo $lecture; echo "<br />"; } // Fermeture du fichier fclose($fp); ?>

Dans ce cas, le rsultat obtenu est bien celui escompt. Lire un fichier ligne par ligne permet ventuellement de manipuler ces lignes avant de les afficher.

Des chiers formats


Un fichier est, le plus souvent, cens contenir une srie de donnes selon un format particulier choisi par le dveloppeur. Cela peut tre une srie de valeurs spares par des tabulations comme pour notre exemple du systme de discussion. Si le format du fichier a t bien pens, alors son analyse, et donc la rcupration des donnes quil contient, se trouve grandement simplifie par lutilisation de linstruction fscanf(). Cette fonction lit les caractres en provenance dun fichier que vous aurez pralablement ouvert, et les traitent en fonction dun schma que vous aurez spcifi.

fscanf()
Rcupre les donnes dune ligne dun fichier en fonction dun format spcifi. Syntaxe mixed fscanf(resource $fp, string $format [, string &$variable1 [, ...]])

499

Chapitre 9

La gestion des fichiers et des rpertoires

$fp

Identifiant sur un fichier ouvert laide de linstruction fopen(). Format de la chane de caractres et des donnes rcuprer. Variables dans lesquelles les valeurs seront copies. Selon les cas : Le nombre de donnes qui ont t lues si des variables ont t passes en paramtre. Un tableau index contenant les diffrentes valeurs si les paramtres ont t omis. Lorsque le pointeur de lecture arrive la fin du fichier, la fonction retourne FALSE.

9. La gestion des fichiers et des rpertoires

$format $variable1, ... retour

Le format de la chane est identique au format quutilise la fonction sscanf(). Rendez-vous au chapitre "La manipulation des chanes de caractres" pour plus de dtails sur les formats.
Ainsi, il est ais de rcuprer nos donnes depuis le fichier messages.txt et dafficher les diffrents messages, ainsi que la date et le pseudo de lutilisateur ayant post ce message. Ensuite, il ne reste plus qu afficher cela dans une page HTML.

Listing 9.4 : fscanf.php


<?php // fichier "fwrite.php" // Ecrire des messages dans un fichier texte // Vrifie que les donnes sont bien postes if($_POST["message"] && $_POST["pseudo"]) { // Ouverture du fichier en criture $fp = fopen("message.txt", "a+"); // Rcupration de lheure $heure = date(H:m:s); // Ecriture de lheure fwrite($fp, $heure."\t"); // Ecriture du pseudo /* On utilise linstruction htmlEntities afin de convertir les caractres spciaux dans leur entit HTML */ fwrite($fp, htmlEntities($_POST["pseudo"])."\t"); // Ecriture du message fwrite($fp, htmlEntities($_POST["message"])."\n"); // On ferme le fichier. fclose($fp); } ?>

500

Accder au systme de fichiers du serveur

<html> <title>Ecrire des messages dans un fichier</title> </head> <body> <table border="0" width="100%"> <?php // Affiche les messages $fp = fopen("message.txt","r"); while($donnee = fscanf($fp, "%s\t". "%s\t". "%[^\t]\n", $heure, $pseudo, $message)) { echo "<tr>"; echo " <td><font color=#0000ff>"; echo $heure; echo " </font></td>"; echo " <td><b>"; echo $pseudo; echo " </b></td>"; echo " <td>"; echo $message; echo " </td>"; echo "</tr>"; } fclose($fp); ?> </table> <hr /> <table border="0" width="100%"> <tr> <form method="post"> <td width="600"> pseudo: <input type="text" name="pseudo" value="<?php htmlEntities($_POST["pseudo"]);?>" size="20" maxlength="20"> message: <input type="text" name="message" size="40" maxlength="255"> <input type="submit" name="envoyer" VALUE="&gt;&gt;"> </td> </form> <td>&nbsp;</td> </tr> </body> </html>

9. La gestion des fichiers et des rpertoires 501

Les espaces qui ne passent pas... Dans le cas o vous devez rcuprer une donne comportant une espace, il est indispensable de ne pas utiliser le formatage des donnes avec "%s". Vous devez en

Chapitre 9

La gestion des fichiers et des rpertoires

9. La gestion des fichiers et des rpertoires

revanche utiliser les expressions rgulires afin de prciser quels caractres peut contenir la chane ou, plus simplement, prciser quels caractres ne peut contenir la chane (ici, la tabulation qui a t choisie comme dlimiteur).

Pour plus dinformations sur les expressions rgulires, reportez-vous au chapitre "La manipulation des chanes de caractres"

Lecture dun bloc


Le langage PHP possde une fonction permettant deffectuer cette opration sans avoir grer louverture et la fermeture des fichiers. Linstruction file() retourne en effet le contenu dun fichier dans un tableau, chaque entre tant une ligne du fichier.

le()
Retourne le contenu dun fichier dans un tableau. Syntaxe $nomFichier $cheminInclude $contexte array file(string $nomFichier [, int $cheminInclude [, resource $contexte]]) Nom du fichier lire. Cette fonction peut aussi lire les fichiers distants. TRUE si le fichier doit tre recherch dans les rpertoires prciss dans include_path., FALSE sinon. La valeur par dfaut est FALSE. Paramtre optionnel, utilisable depuis les versions 4.3 de PHP, spcifiant la ressource de contexte cre par stream_context_create() utiliser. Voir le sous-chapitre sur les flux pour plus de renseignements sur les contextes de flux. Tableau index contenant chaque ligne du fichier, ou FALSE si une erreur est survenue.

retour

Listing 9.5 : file.php


<?php $buffer = file("message.txt"); for ($i=0;$i<count($buffer);$i++) { echo "<font color=#cc0000>message ".($i+1)."</font>:"; echo $buffer[$i]; echo "<br />"; } ?>

Si vous souhaitez simplement afficher le contenu du fichier sur la sortie, il existe une fonction plus pratique ; readfile() permet en effet ce type dopration.

502

Accder au systme de fichiers du serveur

readle()
Retourne, sur la sortie standard, le contenu du fichier pass en paramtre. Syntaxe $nomFichier $cheminInclude $contexte int readfile(string $nomFichier [, int $cheminInclude [, resource $contexte]]). Nom du fichier lire. Cette fonction peut aussi lire les fichiers distants. TRUE si le fichier doit tre recherch dans les rpertoires prciss dans include_path., FALSE sinon. La valeur par dfaut est FALSE. Paramtre optionnel, utilisable depuis les versions 4.3 de PHP, spcifiant la ressource de contexte cre par stream_context_create() utiliser. Voir le sous-chapitre sur les flux pour plus de renseignements sur les contextes de flux. Retourne le nombre doctets qui ont t lus, ou FALSE en cas derreur.

9. La gestion des fichiers et des rpertoires

retour

Listing 9.6 : readfile_01.php


<?php $taille = readfile("http://www.mozilla.org"); echo "<hr />"; echo "Taille de la page = ".$taille." octets"; ?>

Cette fonction est galement pratique (associe un en-tte appropri) pour forcer le tlchargement de fichiers, y compris sil sagit de fichiers habituellement interprts par le navigateurs (.txt, .html, etc.).

Listing 9.7 : readfile_02.php


<?php header("Content-type: application/octet-stream"); header("Content-disposition: attachment; filename=\"message.txt\"); readfile("message.txt"); ?>

Le premier en-tte permet de "forcer" le type du document en un type thoriquement non interprt par le navigateur du client (sauf si ce dernier la configur de manire inadquate), ce qui aura pour effet de proposer la sauvegarde du fichier sur le disque. Le second en-tte permet de suggrer un nom de sauvegarde pour le fichier. Et, enfin, lappel readfile() envoie les donnes au client. De la mme faon, il est possible de rediriger un fichier sur la sortie standard partir de la position courante du pointeur de lecture. fpassthru(), tout comme readfile(), est utilis pour envoyer au client le contenu dun fichier. Attention, fpassthru() ferme automatiquement le fichier (vous ne pouvez plus utiliser lidentifiant de fichier).

503

Chapitre 9

La gestion des fichiers et des rpertoires

9. La gestion des fichiers et des rpertoires

fpassthru()
Retourne sur la sortie standard le contenu dun fichier partir de la position courante du pointeur de lecture. Syntaxe $fp retour int fpassthru(resource $fp) Identifiant de fichier tel que retourn par fopen(), popen() et fsockopen(). Nombre doctets renvoys sur la sortie standard.

Listing 9.8 : fpassthru.php


<?php // Ouverture du fichier en mode lecture $fp = fopen("message.txt","r"); // Dplacement de la position courante de 20 octets. fseek($fp, 20, SEEK_SET); echo "<b>Affiche le fichier partir du 20me caractre.</b>"; echo "<br />"; fpassthru($fp); echo "<hr />"; // reouverture ncessaire du fichier en mode lecture $fp = fopen("message.txt","r"); // Dplacement de la position courante de 100 octets. fseek($fp, 100, SEEK_SET); echo "<b>Affiche le fichier partir du 100me caractre.</b>"; echo "<br />"; fpassthru($fp); ?>

Depuis PHP4.3, linstruction file_get_contents() a fait son apparition. Pratique cette fonction permet de rcuprer le contenu dun fichier directement dans une variable chane.

le_get_contents()
Retourne le contenu dun fichier dans une chane de caractres. Cette fonction est plus rapide utiliser quune lecture en utilisant fread() ou fgets(). Syntaxe : $nomFichier $cheminInclude string file_get_contents(string $nomFichier [, bool $cheminInclude [, ressource $contexte]]) Nom du fichier lire. Cette fonction peut aussi lire les fichiers distants. TRUE si le fichier doit tre recherch dans les rpertoires prciss dans include_path., FALSE sinon. La valeur par dfaut est FALSE.

504

Accder au systme de fichiers du serveur

$contexte

Paramtre optionnel spcifiant la ressource de contexte cre par stream_context_create() utiliser. Voir le sous-chapitre sur les flux pour plus de renseignement sur les contextes de flux. Retourne dans une chane de caractres le contenu du fichier spcifi en argument. Si la lecture a rencontr un problme, la fonction retourne FALSE.

9. La gestion des fichiers et des rpertoires

retour

Voici une alternative lexemple vu avec readfile():


<?php $contenu = file_get_contents("http://www.mozilla.org"); echo $contenu ; ?>

Lecture et ltrage HTML


Le langage PHP possde une instruction permettant de lire une page HTML et de la retourner sans les diffrentes balises. Il sagit de fgetss(), qui est similaire la fonction fgets() si ce nest que les donnes retournes ne possdent plus aucune balise HTML, hormis celles que le dveloppeur aura demand de conserver.

fgetss()
Lecture de la ligne courante du fichier sans les balises HTML le composant. Syntaxe $fp $nbOctet $tagsAutorise retour string fgetss(resource $fp, $nbOctet [, string $tagsAutorise]) Identifiant sur un fichier ouvert laide de linstruction fopen(), fsockopen() ou popen(). Nombre doctets qui doivent tre lus. Les balises qui ne doivent pas tre supprimes ; vous pouvez en spcifier plusieurs en les sparant par le caractre "|". Ex. : "<br>|<b>|<center>". Chane contenant les donnes lues de la ligne courante sans les balises HTML. Retourne FALSE si le pointeur se trouve la fin du fichier.

Listing 9.9 : fgetss.php


<?php $fp = fopen("http://www.gnu.org/home.fr.html","r"); while ($ligne=fgetss($fp, 255, "<br>|<center>")) { echo $ligne; } fclose($fp); ?>

505

Chapitre 9

La gestion des fichiers et des rpertoires

Les balises sur plusieurs lignes Le fait que linstruction fgetss() ne retourne quune ligne la fois fait quil est impossible de supprimer les balises de deux lignes et plus. Avant toute chose, il est donc important de vrifier que le code HTML de votre fichier ne possde pas de balises sur plusieurs lignes. Si vous ntes pas lauteur de la page que vous voulez traiter, commencez par mettre tout le code HTML sur une ligne unique, comme le fait le code ci-dessous.
<?php $buffer = file("http://www.gnu.org/home.fr.html"); $fichier = join("",$buffer); echo strip_tags($fichier,"<br>|<center>"); ?>

9. La gestion des fichiers et des rpertoires

La page retourne est ici compltement vide de balises HTML, lexception des balises <br> et <center> que nous avions choisi de conserver.

Figure 9.1 : Le site original

506

Accder au systme de fichiers du serveur

9. La gestion des fichiers et des rpertoires

Figure 9.2 : Le site aprs suppression des balises HTML

Lecture des chiers CSV


Un fichier CSV (pour Comma Separated Value, valeurs spares par des virgules) est un format utilis par un grand nombre de tableurs et de bases de donnes pour limportation et lexportation des donnes. Ce format est constitu de lignes comportant diffrentes valeurs spares par un dlimiteur ( lorigine une virgule, mais gnralement un point-virgule pour les versions franaises). Chacune des lignes du fichier reprsente alors une ligne dun tableau, et chacune des valeurs, une donne dun champ de ce tableau. Voici un exemple de fichier CSV :
Laurent;GUEDON;http://www.tild.com;Socit de dveloppement Pierre-Emmanuel;MULLER;http://pem.levillage.org;Journalisme Thomas;HEUTE;http://www.toutestfacile.com;Le site pour apprendre Damien;HEUTE;http://www.ootoogo.com;Le portail du Tourisme et des Loisirs

Limportation dans un tableau de type Excel ou Gnumeric donne un tableau de la forme ci-dessous (voir fig. 9.3) : Linstruction fgetcsv() permet de lire aisment ce type de fichier. Nous allons nous en servir pour rcuprer notre fichier de messages (il suffira dindiquer que le dlimiteur nest pas une virgule mais une tabulation).

507

Chapitre 9

La gestion des fichiers et des rpertoires

9. La gestion des fichiers et des rpertoires

Figure 9.3 : Un tableau Excel aprs importation des donnes du fichier CSV

fgetcsv()
Lit une ligne dun fichier et retourne un tableau contenant les diffrents champs CSV. Syntaxe $fp $nbOctet $delimiteur retour array fgetcsv(resource $fp, int $nbOctet [, string $delimiteur]) Identifiant sur un fichier ouvert laide de linstruction fopen(), fsockopen() ou popen(). Nombre doctets qui doivent tre lus au maximum. Caractre dlimitant chacune des donnes (par dfaut, le dlimiteur est la virgule). Retourne un tableau contenant les diffrentes donnes dune ligne du fichier CSV. Lorsque la fin du fichier est atteinte, la fonction retourne FALSE.

Et voil ! Cette fonction est particulirement bien adapte notre systme de discussion.

Listing 9.10 : chat.php


<?php // Vrifie que les donnes sont bien postes if($_POST["message"] && $_POST["pseudo"]) { // Ouverture du fichier en criture (mode ajout) $fp = fopen("message.txt", "a+"); // Rcupration de lheure $heure = date(H:m:s); // Ecriture de lheure et dune tabulation fwrite($fp, $heure."\t"); // Ecriture du pseudo et dune tabulation /* On utilise linstruction htmlEntities afin de convertir les caractres spciaux dans leur entit HTML */ fwrite($fp, htmlEntities($_POST["pseudo"])."\t"); // Ecriture du message fwrite($fp, htmlEntities($_POST["message"])."\n"); // On ferme le fichier.

508

Accder au systme de fichiers du serveur

fclose($fp); } ?> <html> <title>Ecrire des messages dans un fichier</title> </head> <body> <table border="0" width="100%"> <?php // Affiche les messages $fp = fopen("message.txt","r"); while($donnee = fgetcsv($fp, 255, "\t")) { echo "<tr>"; echo " <td><font color=#0000ff>"; echo $donnee[0]; echo " </font></td>"; echo " <td><b>"; echo $donnee[1]; echo " </b></td>"; echo " <td>"; echo $donnee[2]; echo " </td>"; echo "</tr>"; } fclose($fp); ?> </table> <hr /> <table border="0" width="100%"> <tr> <form method="post"> <td width="600"> pseudo: <input type="text" name="pseudo" value="<?php htmlEntities($_POST["pseudo"]);?>" size="20" maxlength="20"> message: <input type="text" name="message" size="40" maxlength="255"> <input type="submit" name="envoyer" VALUE="&gt;&gt;"> </td> </form> <td>&nbsp;</td> </tr> </body> </html>

509

9. La gestion des fichiers et des rpertoires

Chapitre 9

La gestion des fichiers et des rpertoires

9. La gestion des fichiers et des rpertoires

Figure 9.4 : Voici le systme de discussion quil ne vous reste plus qu perfectionner

Lecture des chiers .ini


Linstallation dun logiciel ou dune application ncessite la cration dun certain nombre de paramtres dpendant de lutilisateur ou de lenvironnement. Il est courant de stocker ces informations dans un fichier du type monFichier.ini. Le fichier de configuration php.ini est un bon exemple de ce genre de configuration. Celui-ci contient alors, sous un format bien spcifique, diffrentes donnes, regroupes par section, qui peuvent tre exploites par la suite. Le fichier se prsente de la faon suivante :
; Quelques lignes de commentaires. ; Le parseur ne les prendra pas en compte. [section1] utilisateur = 3 administrateur = 1 ;rien = rien [section2] titre = Mon application url = http://www.tild.com [section3] fichier = parse_ini_file.php chemin = /home/e-smith/files/ibays/kangouroo/html/bible/fichier droit = 755

Le langage PHP possde une fonction permettant de traiter les fichiers de ce type et den extraire les lments qui le composent. Linstruction parse_ini_file() retourne les diffrentes donnes dans un tableau associatif. Vous pouvez rcuprer un tableau sur deux niveaux comportant, dans le premier niveau, les diffrentes sections et, dans le second, les attributs et leurs valeurs.

510

Accder au systme de fichiers du serveur

parse_ini_le()
Retourne les diffrents lments composant un fichier du type .ini et forme un tableau associatif. Syntaxe $nomFichier $traiteSection retour array parse_ini_file(string $nomFichier [, boolean $traiteSection]) Nom du fichier lire. Cette fonction peut aussi lire les fichiers distants en donnant une URL en paramtre. TRUE si vous souhaitez que les donnes de chaque section soient regroupes dans des tableaux, FALSE (par dfaut) sinon. Selon les cas : Un tableau associatif ayant pour cls les noms des sections et pour valeur un tableau associatif ayant lui-mme pour cl le nom du paramtre et pour valeur la valeur associe si $traiteSection=TRUE. Un tableau associatif ayant pour cls les noms des paramtres (toutes sections confondues) et pour valeur la valeur associe si $traiteSection=FALSE.

9. La gestion des fichiers et des rpertoires

Listing 9.11 : parse_ini_file.php


<html> <head> <title>Lecture dun fichier CSV</title> </head> <body> <table border="1" cellpadding="1" cellspacing="0"> <tr> <td colspan="2"> <?php echo "Affichage des donnes sans les diffrentes sections."; echo " </td>"; echo "</tr>"; $tableauIni = parse_ini_file("emma.ini"); while (list($key, $val) = each($tableauIni)) { echo "<tr>"; echo " <td>"; echo "$key"; echo " </td>"; echo " <td>"; echo "$val"; echo " </td>"; echo "</tr>"; } ?> </table> <br /> <table border="1" cellpadding="1" cellspacing="0"> <tr>

511

Chapitre 9

La gestion des fichiers et des rpertoires

<td colspan="2"> <? echo "Affichage des donnes avec les diffrentes sections."; echo "<br />"; echo " </td>"; echo "</tr>"; $tableauIni = parse_ini_file("emma.ini", TRUE); while (list($section, $tableauPar) = each($tableauIni)) { echo "<tr>"; echo " <td colspan=2>"; echo " <b>".$section."</b>"; echo " </td>"; echo "</tr>"; while (list($key, $val) = each($tableauPar)) { echo "<tr>"; echo " <td>"; echo " $key"; echo " </td>"; echo " <td>"; echo " $val"; echo " </td>"; echo "</tr>"; } } ?> </table> </body> </html> Figure 9.5 : Le rsultat de traitement du fichier emma.ini

9. La gestion des fichiers et des rpertoires 512

Accder au systme de fichiers du serveur

Positionner le pointeur de lecture/criture


Lorsque lon dsire lire les donnes contenues dans un fichier, elles sont dans un premier temps copies dans un espace mmoire (buffer). On dit que le mode de lecture est "bufferis". Une fois le fichier ouvert, un pointeur de lecture se place automatiquement au dbut de ce fichier, chacun des appels une instruction de lecture faisant avancer ce pointeur. Lavance de ce pointeur peut tre contrle par trois fonctions qui sont feof(), fseek() ou rewind(). La premire instruction permet de dterminer si la fin du fichier ouvert est atteinte. La seconde instruction repositionne le pointeur de lecture (ou dcriture) une position spcifique. Quant la dernire fonction, elle renvoie le pointeur au dbut du fichier.

9. La gestion des fichiers et des rpertoires

feof()
Dtermine si la fin du fichier est atteinte. Syntaxe $fp retour boolean feof(resource $fp) Identifiant sur un fichier ouvert laide dune instruction fopen(), tmpfile(), fsockopen() ou popen(). Retourne TRUE si le pointeur est la fin du fichier, FALSE dans le cas contraire.

<?php $fp = fopen("data.txt", "r"); // Traitements divers if (feof($fp)) { echo "Fin du fichier.<br />"; } fclose($fp); ?>

Vous pouvez connatre la position courante du pointeur laide la fonction ftell().

ftell()
Retourne la position courante du fichier. Syntaxe $fp retour int ftell(resource $fp) Identifiant sur un fichier ouvert laide dune instruction fopen(), tmpfile(), fsockopen() ou popen(). Retourne la position courante du pointeur de lecture/criture.

<?php $fp = fopen("data.txt", "r");

513

Chapitre 9

La gestion des fichiers et des rpertoires

9. La gestion des fichiers et des rpertoires

echo "Position courante : ".ftell($fp); fclose($fp); ?>

fseek()
Dplace le pointeur de lecture/criture dun fichier une position spcifique. Syntaxe $fp $offset $origine int fseek(resource $fp, int $offset [, $origine]) Identifiant sur un fichier ouvert laide dune instruction fopen(), tmpfile(), fsockopen() ou popen(). Nombre indiquant le dplacement en octets (positif ou ngatif) par rapport lorigine slectionne. Indique partir de quel endroit doit tre compt le dplacement. Au choix : SEEK_SET ( = 0) partir du dbut du fichier. SEEK_CUR ( = 1) partir de la position courante du pointeur (valeur par dfaut). SEEK_END ( = 2) partir de la fin du fichier. retour 0 en cas de succs, et 1 en cas derreur..

Il est noter quun dplacement positif partir de la fin du fichier nentrane pas derreur. En effet, dplacer un pointeur au-del de EOF est possible.

Listing 9.12 : fseek.php


<?php echo "taille : ".filesize("message.txt"); // Affiche la taille du fichier en octets echo "<br />"; $fp = fopen("message.txt","r"); fseek($fp, 20, SEEK_SET); echo "Position par rapport au dbut du fichier (0+20) : "; echo ftell($fp)."<br />"; fseek($fp, 20, SEEK_CUR); echo "Position par rapport la position courante (20+20) : "; echo ftell($fp)."<br />"; fseek($fp, 20, SEEK_END); echo "Position par rapport la fin du fichier (Fin+20 ): "; echo ftell($fp)."<br />"; fclose($fp); ?>

514

Accder au systme de fichiers du serveur

pourrait retourner un rsultat du genre :


taille : Position Position Position 190 par rapport au dbut du fichier (0+20) : 20 par rapport la position courante (20+20) : 40 par rapport la fin du fichier (Fin+20 ): 210

9. La gestion des fichiers et des rpertoires

Le pointeur de lecture/criture Si vous ouvrez le fichier laide de linstruction fopen() avec le mode "a" ou "a+" (ouverture pour ajout de donnes), le pointeur est systmatiquement plac la fin du fichier.

rewind()
Repositionne le pointeur de lecture/criture au dbut du fichier. Syntaxe $fp retour boolean rewind(resource $fp) Identifiant sur un fichier ouvert laide dune instruction fopen(), tmpfile(), fsockopen() ou popen(). TRUE si lopration sest droule sans problme, et FALSE si le pointeur na pas pu tre repositionn.

<?php $fp = fopen("message.txt", "r"); // Traitements divers if (rewind($fp)) { echo "Le pointeur du fichier a t repositionn au dbut"; echo "<br />"; } fclose($fp); ?>

Tronquer un chier
Une fonction particulire permet de tronquer les fichiers qui ont t ouverts en mode criture. Le langage PHP permet de rcuprer une partie des informations contenues dans un fichier et de les rcrire en supprimant le reste des donnes. Linstruction ftruncate() ne fonctionne que dans le cas o le fichier a t ouvert en criture, cest--dire les modes criture seule (w, a), lecture et criture (w+, a+).

515

Chapitre 9

La gestion des fichiers et des rpertoires

9. La gestion des fichiers et des rpertoires

ftruncate()
Tronque un fichier (i.e. ne conserve que les premiers octets du fichier). Syntaxe $fp $taille retour int ftruncate(resource $fp, int $taille) Identifiant sur un fichier ouvert laide dune instruction fopen(), tmpfile(), fsockopen() ou popen(). Nouvelle taille du fichier. 1 (mais pas strictement TRUE) si le fichier a bien t tronqu, 0 (mais pas strictement FALSE) sinon.

Imaginons le contenu dun fichier dedicace.txt.


Je ddicace ce livre tous mes amis Et plus particulirement Myriam si adorable. A Amiel pour son soutien et ses comptences. A Damien pour savoir botter le cul quand il le faut. A Thomas pour son calme faire passer un bouddha pour un rocker sous ecsta.

Ce fichier est bien trop long et nous ne voulons conserver que les deux premires lignes. La principale difficult consiste donc dterminer la nouvelle taille que nous souhaitons donner ce fichier. Pour cela, il suffit de lire les deux premires lignes, et de dterminer quelle est la position atteinte par le pointeur de fichier (grce ftell()). Cette position correspondra la taille voulue.

Listing 9.13 : ftruncate.php


<?php // Ouvre un fichier texte en mode lecture et criture if ($fp = fopen("dedicace.txt", "r+")) { // Lecture des deux premires lignes fgets($fp, 255); fgets($fp, 255); // On tronque une taille gale // la position courante du pointeur de // lecture ftruncate($fp, ftell($fp)); // Fermeture du fichier fclose($fp); // Affichage du fichier une fois tronqu readfile("dedicace.txt"); } else { echo "Impossible douvrir le fichier ddicace."; } ?>

516

Accder au systme de fichiers du serveur

Ce qui donnera le rsultat suivant :


Je ddicace ce livre tous mes amis Et plus particulirement Myriam si adorable.

9. La gestion des fichiers et des rpertoires

Gestion de lespace tampon


Lcriture dans un fichier est effectue en deux temps. Les donnes sont dabord copies vers un buffer (espace mmoire) et sont ensuite crites sur le fichier ouvert. Ce systme de bufferisation permet de gagner du temps, car les appels systme se font plus rares. Imaginons que lon dsire crire dans un fichier 20 lignes de 200 caractres. Il faudra alors normalement 20 appels systme pour crire la totalit des donnes dans le fichier. Lutilisation du buffer permet dcrire une seule fois les 4 000 (20*200) caractres, cest--dire que le programme ne fait appel quune fois au systme dexploitation, et ne sollicite quune fois le disque dur pour crire dans le fichier. Le langage PHP possde, par dfaut, un buffer de 8 Ko, mais il est possible de lui fixer une autre taille avec linstruction set_file_buffer(). Il peut tre particulirement intressant daugmenter cette valeur si votre script doit traiter des fichiers de trs grande taille. Depuis PHP 4.3, linstruction stream_set_write_buffer() remplace cette fonction. set_file_buffer() demeure un alias pour des raisons de retro-compatibilits.

stream_set_write_buffer()
Fixe la taille du buffer. Syntaxe $fp $taille retour int stream_set_write_buffer(ressource $fp, int $taille) Identifiant sur un fichier ouvert laide dune instruction fopen(), tmpfile(), fsockopen() ou popen(). Nouvelle taille du buffer. 0 si linstruction se droule convenablement, EOF dans le cas contraire.

Du fait de la prsence de ce systme de cache, les donnes crites dans un fichier ne sont pas toujours disponibles immdiatement (pour les scripts cherchant en lire le contenu). Les donnes ne seront effectivement accessibles quune fois le buffer vid (ce qui intervient automatiquement ds quil est plein ou manuellement lorsque vous appelez la fonction fflush()). Notez galement que le buffer est automatiquement vid lors de lappel fclose(). A contrario, si vous quittez lexcution de votre programme sans faire appel fclose(), vous courez le risque de perdre les donnes restant dans le cache.

fflush()
crit et vide le buffer dun fichier. Syntaxe boolean fflush (resource $fp)

517

Chapitre 9

La gestion des fichiers et des rpertoires

$fp

Identifiant sur un fichier ouvert laide dune instruction fopen(), tmpfile(), fsockopen() ou popen(). Retourne TRUE si le buffer a t vid dans le fichier, ou FALSE dans le cas contraire.

9. La gestion des fichiers et des rpertoires

retour

Listing 9.14 : fflush.php


<?php $fp = fopen("twiki.txt", "w"); if ($fp) { // Les donnes seront crites tous les 500 octets set_file_buffer($fp, 500); // Cette phrase fait moins de 500 octets // elle nest donc pas immdiatement crite fputs($fp, "Bidibidibidi comme dirait Twiki."); // Mais qu cela ne tienne. Nous allons forcer lcriture fflush($fp); // Cette phrase attendra fclose() pour tre crite fputs($fp, "Glop Glop comme dirait Pifou."); fclose($fp); } ?>

Lister le contenu dun dossier


Nous avons vu que, pour visualiser le contenu dun fichier, il suffit de louvrir et dobtenir ainsi un pointeur vers ce fichier. Louverture dun rpertoire est similaire celle dun fichier. Vous crez, laide de la fonction openDir(), un identifiant, qui vous permet par la suite de lire ce dossier la faon dun fichier.

openDir()
Ouvre le rpertoire dsign et retourne un pointeur dessus. Syntaxe $chemin retour resource openDir(string $chemin) Chemin du dossier ouvrir. Pointeur sur le dossier ouvert.

Ne pas oublier de fermer le dossier laide de linstruction closeDir().

518

Accder au systme de fichiers du serveur

closeDir()
Fermer un dossier pralablement ouvert avec la fonction openDir(). Syntaxe $repertoire void closeDir(resource $repertoire) Pointeur sur un dossier ouvert avec linstruction openDir().

9. La gestion des fichiers et des rpertoires

<?php // Ouverture du dossier parent "/monrepertoire" $repertoire = openDir("/monrepertoire"); // Placer les diffrents traitements effectuer // ... // Fermeture du dossier closeDir($repertoire); ?>

Une fois un pointeur obtenu sur le rpertoire, il suffit, pour lister le contenu dun dossier, de faire appel la fonction readDir(). Le pointeur de lecture se place au dbut du rpertoire et chacun des appels la fonction readDir() le fait avancer sur lentre suivante, savoir le nom du fichier ou rpertoire suivant. De proche en proche, il est ainsi possible de lire la totalit du contenu dun dossier.

readDir()
Lecture des entres dans un dossier. Syntaxe $repertoire retour string readDir(resource $repertoire) Pointeur sur un dossier ouvert avec linstruction openDir(). Retourne le nom du fichier dsign par le pointeur de lecture.

Ainsi, pour afficher le contenu dun rpertoire, nous pouvons utiliser la fonction suivante :

Listing 9.15 : readdir.php


<?php // La fonction dexploration function explorer($chemin) { $repertoire = openDir($chemin); while ($fichier = readDir($repertoire)) { // Inutile dafficher les entres . et .. if (($fichier != ".")&&($fichier != "..")) { // noublions pas dajouter // le chemin au nom du fichier echo $chemin."/".$fichier<br />"; } }

519

Chapitre 9

La gestion des fichiers et des rpertoires

// Cest fini. On ferme ! closeDir($repertoire);

9. La gestion des fichiers et des rpertoires

} // Dfinition du chemin explorer $cheminRep = "."; // Lappel la fonction explorer($cheminRep); ?>

qui pourrait donner :


./fichier0.php ./fichier1.php ./fichier2.php ./repertoire

Nous pouvons, de plus, imaginer que tous les sous-rpertoires soient lists, permettant ainsi davoir la liste complte des fichiers contenus dans le dossier courant. Pour cela, nous allons utiliser les proprits de rcursivit du langage PHP. Nous devrons en outre tre capables de distinguer les rpertoires des fichiers. Pour cela, nous devrons faire appel la fonction is_dir() qui indique sil sagit dun rpertoire. Et, enfin, afin de distinguer le parcours du rpertoire du traitement du contenu, nous retournerons un tableau contenant les noms des fichiers.

Listing 9.16 : readdir_recursif.php


<?php // La fonction dexploration function explorer($chemin, $recursif=FALSE) { $listeFichier = array(); $repertoire = openDir($chemin); while ($fichier = readDir($repertoire)) { // Inutile de tenir compte des entres . et .. if (($fichier != ".")&&($fichier != "..")) { // Est-ce que $file est un rpertoire ? // Pour le savoir il suffit dappeler is_dir // mais attention noublions pas dajouter // le chemin au nom du fichier if (is_dir($chemin."/".$fichier)&&($recursif)) { // oui ? alors explorons-le // et ajoutons le rsultat la liste de fichiers $listeFichier = array_merge($listeFichier, explorer($chemin."/".$fichier, $recursif)); } else { // sinon, cest un fichier et on lajoute // la liste des fichiers $listeFichier[] = $chemin."/".$fichier; }

520

Accder au systme de fichiers du serveur

} } // Cest fini. On ferme ! closeDir($repertoire); // et on retourne le rsultat return $listeFichier; } // Dfinition du chemin explorer $cheminRep = "../."; // Lappel la fonction $fichiers = explorer($cheminRep, TRUE); // Affichage ( titre dmonstratif) for ($i=0; $i<count($fichiers); $i++) echo $fichiers[$i]."<br />"; ?>

9. La gestion des fichiers et des rpertoires

Ce script aisment rutilisable retournera donc quelque chose comme :


./fichier0.php ./fichier1.php ./fichier2.php ./repertoire/fichier0.php ./repertoire/fichier1.php ./repertoire/fichier2.php ./repertoire/fichier3.php ./repertoire/fichier4.php

Dans certains cas, comme la galerie dimages (un grand classique), il faut filtrer les noms des fichiers (gnralement daprs leur extension). Nous allons donc perfectionner encore notre fonction pour prciser une expression rgulire laquelle doit rpondre le nom du fichier. Une fois la liste des fichiers rcupre, il suffira dafficher les images.

Listing 9.17 : readdir_filtre.php


<?php // La fonction dexploration // $chemin : Rpertoire explorer // $recursif : TRUE si lexploration doit tre rcursive // $filtre : Expression rgulire de filtrage des fichiers function explorer($chemin, $recursif=FALSE, $filtre=NULL) { $listeFichier = array(); $repertoire = openDir($chemin); while ($fichier = readDir($repertoire)) { // Inutile de tenir compte des entres . et .. if (($fichier != ".")&&($fichier != "..")) { // Est-ce que $file est un rpertoire ? // Pour le savoir il suffit dappeler is_dir // mais attention noublions pas dajouter

521

Chapitre 9

La gestion des fichiers et des rpertoires

// le chemin au nom du fichier if (is_dir($chemin."/".$fichier)&&($recursif)) { // oui ? alors explorons-le // et ajoutons le rsultat la liste de fichiers $listeFichier = array_merge($listeFichier, explorer($chemin."/".$fichier, $recursif, $filtre)); } else { // sinon, cest un fichier et sil rpond // aux critres de lexpression rgulire // on lajoute a la liste des fichiers if (is_null($filtre)||eregi($filtre, $fichier)) { $listeFichier[] = $chemin."/".$fichier; } } } } // Cest fini. On ferme ! closeDir($repertoire); // et on retourne le rsultat return $listeFichier; } // Dfinition du chemin explorer $cheminRep = "../."; // Lappel la fonction $fichiers = explorer($cheminRep, TRUE, ".gif|.jpg|.png"); // Affichage ( titre dmonstratif) echo "<html><body>"; echo "<table width=100% border=0>"; for ($i=0; $i<count($fichiers); $i++) { // 5 images par ligne if ($i%5 == 0) echo "<tr></td>"; else echo "<td>"; echo "<img src=".$fichiers[$i]."><br />"; if (($i+1)%5 == 0) echo "</td></tr>\n"; else echo "</td>"; } echo "</table>"; echo "</body></html>"; ?>

9. La gestion des fichiers et des rpertoires 522

Accder au systme de fichiers du serveur

9. La gestion des fichiers et des rpertoires

Figure 9.6 : Notre galerie dimages

Lordre des fichiers Vous pouvez observer que la liste des fichiers nest pas donne dans lordre alphabtique. Si vous voulez ordonner cette liste, il vous suffit dappliquer la fonction sort() au tableau.
Dans les exemples prcdents, nous avons opt pour une solution retournant la liste des fichiers dans un tableau. Cette mthode peut ncessiter beaucoup de mmoire si la liste est longue. Une autre solution aurait pu consister ajouter la fonction un paramtre permettant de prciser le nom dune fonction appeler ds quun nouveau fichier est rencontr.

Pointeur de lecture du rpertoire


Lors de la lecture du contenu du dossier, vous pouvez dplacer le pointeur la premire entre laide de linstruction rewindDir().

523

Chapitre 9

La gestion des fichiers et des rpertoires

9. La gestion des fichiers et des rpertoires

rewindDir()
Dplace le pointeur de lecture du dossier la premire entre. Syntaxe $repertoire void rewindDir(resource $repertoire) Pointeur sur un dossier ouvert avec linstruction opendir().

<?php $repertoire = openDir("./"); while ($fichier = readDir($repertoire)) { echo $fichier."<br />"; } // Affichage de la liste des fichiers du dossier. while ($fichier = readDir($repertoire)) { echo $fichier."<br />"; } // Le programme naffiche rien. // On dplace le pointeur sur la premire entre rewindDir($repertoire); while ($fichier = readDir($repertoire)) { echo $fichier."<br />"; } // Affichage de la liste des fichiers du dossier. closeDir($repertoi