Vous êtes sur la page 1sur 704

Copyright

2008 Micro Application 20-22, rue des Petits-Htels 75010 Paris 1re dition - Mai 2008

Auteurs

Franois-Xavier BOIS 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. 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 et les marques ne sont utilises qu seule fin de dsignation des produits en tant que noms de ces derniers.

ISBN : 978-2-300-014147

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 : galement disponible sur www.microapp.com

Retrouvez des informations sur cet ouvrage ! Rendez-vous sur le site Internet de Micro Application www.microapp.com. Dans le module de recherche, sur la page daccueil du site, entrez la rfrence 4 chiffres indique sur le prsent livre. Vous accdez directement sa fiche produit.

1414

Avant-propos
Destine aussi bien aux dbutants quaux utilisateurs initis, la collection Guide Complet repose sur une mthode essentiellement pratique. Les explications, donnes dans un langage clair et prcis, sappuient sur de courts exemples. En n de chaque chapitre, dcouvrez, en fonction du sujet, des exercices, une check-list ou une srie de FAQ pour rpondre vos questions. Vous trouverez dans cette collection les principaux thmes de lunivers informatique : matriel, bureautique, programmation, nouvelles technologies...

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

: menu, commande, bote de dialogue, bouton, onglet. : zone de texte, liste droulante, case cocher, bouton

j italique

radio.
j

Police bton : Instruction, listing, adresse internet, texte

saisir.
j

: indique un retour la ligne volontaire d aux contraintes de la mise en page.


Il sagit dinformations supplmentaires relatives au sujet trait.

Met laccent sur un point important, souvent dordre technique quil ne faut ngliger aucun prix.

Propose conseils et trucs pratiques.

Donne en quelques lignes la dnition dun terme technique ou dune abrviation.

Sommaire

Chapitre 1
1.1. 1.2. 1.3. 1.4.

Introduction

13

Les langages de programmation .................................. 14 Le PHP ................................................................ 20 Internet, comment a marche ? .................................... 31 Check-list ............................................................. 46

Chapitre 2
2.1.

Lenvironnement de travail

47

2.2. 2.3.

WampServer .......................................................... 48 Installation ............................................................. 48 Premiers pas .......................................................... 53 Le menu de Wamp ................................................... 56 Lditeur Notepad++ ................................................. 59 Paramtrage de PHP ................................................ 60 Check-list ............................................................. 64

Chapitre 3
3.1. 3.2. 3.3. 3.4. 3.5.

Les fondamentaux

65

3.6.

3.7.

3.8.

Structure dun programme ......................................... 67 Les commentaires ................................................... 72 Les variables ......................................................... 74 Les constantes ....................................................... 78 Les types de donnes ............................................... 80 Les donnes numriques ............................................ 80 Les chanes de caractres ........................................... 82 Le type NULL ......................................................... 85 Changement de type ................................................. 85 Les structures de contrle .......................................... 86 Les conditions ........................................................ 87 Les boucles ........................................................... 93 Organisation du code ............................................... 99 Les fonctions .......................................................... 99 Inclusion de fichier .................................................. 109 Check-list ............................................................ 113

Chapitre 4
4.1.

Les tableaux

115

4.2.

4.3.

Prsentation ........................................................ 116 Les tableaux scalaires .............................................. 117 Les tableaux associatifs ............................................ 118 Les tableaux multidimensionnels .................................. 119 Parcours dun tableau ............................................. 121 Boucle foreach ...................................................... 121 Utilisation du pointeur interne ..................................... 123 Utilisation des rfrences .......................................... 124 Les fonctions ........................................................ 125 Suppression dune cellule .......................................... 125

4 LE GUIDE COMPLET

Sommaire
Affichage dun tableau .............................................. 126 Taille dun tableau ................................................... 127 Conversion chanes / tableaux ..................................... 128 Adjonction, soustraction dlments .............................. 130 Tri ..................................................................... 131 Prsence dune valeur dans un tableau ........................... 134 Srialisation ......................................................... 134 Les oprateurs sur les tableaux .................................. 136 Check-list ............................................................ 137

4.4. 4.5.

Chapitre 5
5.1.

Dates et heures

139

5.2.

5.3. 5.4.

La notion de timestamp ........................................... 140 Cration dun timestamp ........................................... 141 Conversion .......................................................... 142 Comparaison de dates ............................................. 144 Formatage dune date ............................................. 146 Echappement de caractres ....................................... 149 Constantes .......................................................... 150 Contrle de validit dune date ................................... 152 Check-list ............................................................ 153

Chapitre 6
6.1. 6.2.

Les formulaires et transmissions de donnes 155


Quest-ce quun formulaire ? ..................................... 156 Les diffrents widgets ............................................. 158 INPUT TEXT ......................................................... 159 TEXTAREA ........................................................... 161 SELECT .............................................................. 162 INPUT CHECKBOX ................................................. 164 INPUT RADIO ....................................................... 164 INPUT BUTTON ..................................................... 165 INPUT HIDDEN ...................................................... 166 Passer des paramtres un script PHP ......................... 166 La variable $_GET ................................................... 167 Query String ......................................................... 174 La mthode POST .................................................. 177 Le mode register_globals on ....................................... 180 Check-list ............................................................ 181

6.3.

6.4.

Chapitre 7
7.1.

En tte HTTP et authentication

183

7.2. 7.3.

Requtes et rponses ............................................. 184 Extension LiveHTTPHeaders ...................................... 184 La requte ........................................................... 186 La rponse ........................................................... 187 Fonction header() ................................................... 188 Page derreur ....................................................... 190

LE GUIDE COMPLET 5

Sommaire
7.4. 7.5. Authentication ..................................................... 192 En bref ............................................................... 196

Chapitre 8
8.1.

JavaScript, contrle de formulaires et AJAX 197


Prsentation de JavaScript ....................................... 198 Les fonctions ........................................................ 199 Linteraction avec les widgets ..................................... 205 La bibliothque Prototype .......................................... 214 Des vrications simples en PHP ................................ 216 Les expressions rgulires ........................................ 222 Ajax ................................................................... 226 AJAX et Prototype .................................................. 226 change de donnes au format JSON ............................ 229 Check-list ............................................................ 234

8.2. 8.3. 8.4.

8.5.

Chapitre 9
9.1. 9.2. 9.3. 9.4.

Lenvoi dun formulaire par courriel

235

Conguration requise .............................................. 236 Mail Texte ............................................................ 237 Mail HTML ........................................................... 242 Check-list ............................................................ 248

Chapitre 10
10.1.

Lenregistrement dans une base de donnes 249


Les bases de donnes ............................................. 250 Quest ce quun SGBD ? ........................................... 250 Organisation dun SGBD ........................................... 253 Les requtes ......................................................... 254 PHP et MySQL ...................................................... 259 Premires requtes ................................................. 259 Enregistrement dune fiche ........................................ 272 Envoi de chier ..................................................... 277 Modification de la structure dune table .......................... 277 Envoi de fichier ...................................................... 278 Le couteau suisse du dveloppeur web : phpMyAdmin ...... 283 Check-list ............................................................ 289

10.2.

10.3.

10.4. 10.5.

Chapitre 11
11.1. 11.2.

La gestion dune base de donnes

291

11.3. 11.4.

Lauthentication ................................................... 292 La mise jour dune table ......................................... 296 Linstruction input hidden .......................................... 300 La commande UPDATE ............................................ 300 La suppression : DELETE ......................................... 308 La factorisation du code ........................................... 314 La fonction include .................................................. 315

6 LE GUIDE COMPLET

Sommaire
Lamlioration visuelle : les CSS ................................... 325 Recherche et tri au sein dune base .............................. 331 Dfinir la fonction de recherche .................................... 331 Dfinir la fonction de tri ............................................. 334 Check-list ............................................................ 337

11.5.

11.6.

Chapitre 12
12.1.

La gestion des chiers

339

12.2.

12.3.

Manipuler des chiers ............................................. 340 Les fichiers de cache ............................................... 340 Lcriture ............................................................. 342 La lecture ............................................................ 344 Les fichiers modles : templates .................................. 347 Crer des chiers spciaux ....................................... 351 Les fichiers compresss ............................................ 351 Les fichiers Excel .................................................... 356 Les fichiers Flash .................................................... 358 Les fichiers PDF ..................................................... 363 Les fichiers image ................................................... 365 Check-list ............................................................ 382

Chapitre 13
13.1.

La programmation objet

383

13.2.

13.3.

13.4. 13.5. 13.6.

13.7. 13.8. 13.9.

Classes et objets ................................................... 385 Classes ............................................................... 385 Objets ................................................................ 387 Conversion .......................................................... 390 Constructeur et destructeur ....................................... 391 Les mthodes magiques .......................................... 393 __sleep() et __wakeup() ............................................. 393 __toString() .......................................................... 394 Surcharge des accesseurs ......................................... 394 Polymorphisme ..................................................... 398 Principe gnral ..................................................... 398 Visibilit .............................................................. 399 Les interfaces ....................................................... 401 Itrateurs ............................................................ 403 Exceptions .......................................................... 405 Principe gnral ..................................................... 405 La classe Exception ................................................ 407 Rexion ............................................................ 409 Version objet de la gnration de graphique ................... 410 Check-list ............................................................ 416

Chapitre 14
14.1.

XML

417

Le format ............................................................ 418

LE GUIDE COMPLET 7

Sommaire
14.2. SimpleXML .......................................................... 421 Cration .............................................................. 422 Lecture ............................................................... 425 Formats spciaux .................................................. 426 RSS ................................................................... 427 XHTML ............................................................... 434 SVG ................................................................... 435 Check-list ............................................................ 437

14.3.

14.4.

Chapitre 15
15.1.

Les cookies et les sessions

439

15.2. 15.3.

Les cookies ......................................................... 440 Aspects techniques ................................................. 441 Application : la mini-boutique FoxShop .......................... 444 Les sessions ........................................................ 472 Check-list ............................................................ 482

Chapitre 16
16.1.

La gestion de la scurit

483

16.2.

16.3.

16.4. 16.5.

La scurit avec PHP .............................................. 485 Le b-a ba ............................................................. 485 Mise jour de PHP .................................................. 486 Initialiser toutes les variables ...................................... 486 Utiliser les constantes .............................................. 487 Se mfier de la puissance de certaines fonctions ............... 488 Dangers de la fonction mail ........................................ 489 Les cookies et les sessions ........................................ 490 Les transferts de fichiers ........................................... 491 Inclusion de fichier .................................................. 492 Scuriser les bases de donnes .................................. 493 Les injections SQL .................................................. 493 Les Cross Site Scripting ............................................ 494 Scuriser le serveur web .......................................... 496 Les directives PHP .................................................. 497 Les directives Apache .............................................. 500 La scurit HTTPS .................................................. 503 Les outils danalyse ................................................ 503 Check-list ............................................................ 504

Chapitre 17
17.1.

Les trucs et astuces

505

PHP .................................................................. 506 Dfinir autrement une chane de caractres ...................... 506 Raccourcir un if... else... ............................................ 507 Lautre syntaxe des structures de contrle ....................... 508 Raccourcir un simple bloc echo ................................... 509 Donner une valeur par dfaut un paramtre dune fonction .. 510 Transmettre un nombre variable de paramtres une fonction . 511

8 LE GUIDE COMPLET

Sommaire
Utiliser un oprateur de comparaison de type ................... 512 Les attributs __FILE__ et __LINE__ ................................ 513 Les variables variables ............................................. 514 Les oprateurs sur les tableaux ................................... 514 Les techniques doptimisation en PHP ........................... 515 Les fonctions include() et require() ................................. 516 Laffichage tampon : output buffering ............................. 518 Fin de bloc PHP ..................................................... 519 Le paramtre cach de break et continue ........................ 519 Chane de caractres sous forme de tableau de caractres .... 520 Rendre disponible un site wamp sur internet ..................... 521 MySQL ............................................................... 523 Rcuprer un enregistrement de manire alatoire .............. 523 Optimiser ses tables ................................................ 524 Autres optimisations ................................................ 525 HTML et Javascript ................................................ 525 Empcher lautocompltion ....................................... 525 Dfinir le rafrachissement automatique dune page ............ 526

17.2.

17.3.

Chapitre 18
18.1. 18.2. 18.3. 18.4. 18.5. 18.6. 18.7. 18.8. 18.9. 18.10. 18.11.

Les fonctions PHP

527

Les fonctions mathmatiques .................................... 529 Les chanes de caractres ........................................ 538 Les expressions rgulires ........................................ 559 Les tableaux ........................................................ 561 Les fonctions de dates et dheures .............................. 583 Les chiers et les rpertoires ..................................... 588 Linterface avec MySQL ........................................... 611 Les images .......................................................... 622 Les variables ........................................................ 638 La conguration PHP .............................................. 642 Fonctions diverses ................................................. 645

Chapitre 19
19.1.

Annexes

649

19.2.

Webographie ........................................................ 650 PHP ................................................................... 650 MySQL ............................................................... 652 Apache ............................................................... 652 Internet et le Web ................................................... 653 Et les blogs .......................................................... 654 Divers ................................................................ 654 PHP .................................................................. 654 Les oprateurs ...................................................... 654 Les variables prdfinies ........................................... 657 Les mots rservs ................................................... 668 Les diffrences entre PHP 3 et PHP 4 ............................ 669 Les diffrences entre PHP 4 et PHP 5 ............................ 672

LE GUIDE COMPLET 9

Sommaire
19.3. MySQL ............................................................... 673 Les types ............................................................. 673 Les fonctions ........................................................ 674 Les caractres HTML spciaux .................................. 679 Les feuilles de styles : CSS ........................................ 683

19.4. 19.5.

Chapitre 20

Index

693

10 LE GUIDE COMPLET

Ddicace
Laurence et Marie-Castille.

Introduction

Les langages de programmation ...................................................................................... 14 Le PHP .................................................................................................................................... 20 Internet, comment a marche ? ....................................................................................... 31 Check-list ............................................................................................................................... 46

Chapitre 1

Introduction

Tout en tant consacr un langage de programmation aussi pointu quavanc, cet ouvrage reste destin un large public. Quelques connaissances lmentaires dans le domaine du Web (HTML) mises part, aucune comptence informatique particulire nest indispensable la comprhension des diffrents sujets abords au sein du prsent ouvrage. Il est de ce fait particulirement destin aux web designers et aux webmestres, aux tudiants et, plus gnralement, toute personne aspirant aller plus loin dans la cration de sites et dapplications web. Tout au long des chapitres, nous nous attacherons illustrer les diffrents concepts tudis laide dexemples que nous enrichirons au fur et mesure des chapitres. Nous tudierons aussi bien les bases du langage (syntaxe, variables, fonctions) que certains aspects plus avancs (envoi de courriels, manipulation de chiers, interaction avec les bases de donnes, gestion des cookies et sessions, programmation objet). Nous proterons galement de certains chapitres pour dcouvrir certaines technologies adjacentes PHP : le HTML (les formulaires), le SQL (le langage des bases de donnes), le XML (un format universel dchanges de donnes) et le langage Javascript (qui a vu sa rhabilitation rcente avec lmergence du concept de Web 2.0). Dans le cadre de ce premier chapitre, nous nous intresserons tout dabord aux diffrents langages de programmation pour nous concentrer ensuite sur le langage PHP, son histoire, son mode de fonctionnement, ses avantages et ses dfauts. Nous proterons aussi de ce chapitre introductif pour raliser un rapide tour dhorizon du Web et dInternet en gnral.

1.1. Les langages de programmation


PHP est un langage de programmation. Il permet dcrire des programmes, tout comme les mathmatiques permettent de rsoudre des problmes. Trs en vogue actuellement, il est cependant loin dtre le seul dans sa catgorie. Plusieurs centaines de langages ont ainsi vu le jour depuis la naissance de linformatique dans les annes 1950. Parmi les plus connus peuvent tre cits les langages C, C++, C#, Java, Perl, Python, Basic, ActionScript, etc. Un programme informatique est compos de lignes dinstructions ; lensemble de ces lignes forme le code source (ou listing) du
14 LE GUIDE COMPLET

Les langages de programmation

Chapitre 1

programme. Dans la vie courante, les instructions suivantes pourraient tre apparentes un programme :
Listing 1-1 : un programme dans la vie courante 1- insrer la carte 2- composer le code secret 3- renouveler ltape 2 en cas dchec 4- composer le montant 5- appuyer sur le bouton validez 6- retirer les billets 7- rcuprer la carte

Pour un mme objectif, le code source dun programme est diffrent selon le langage utilis.
Listing 1-2 : Programme crit en PHP for ($i = 1; $i <= 10; $i++) { echo "i = $i\n"; } Listing 1-3 : Programme crit en C for (i = 1; i <= 10; i++) { printf("i = %d\n",i); } Listing 1-4 : Programme crit en Java for (i = 1; i <= 10; i++) { System.out.println("i = " + i); } Listing 1-5 : Programme crit en Python for i in range(1,11): print "i = ", i Listing 1-6 : Programme crit en Perl for ($i = 1; $i <= 10; $i++) { print "i = $i\n"; }

Ces exemples prouvent quen dehors de quelques diffrences dordre syntaxique tous ces langages de haut niveau sont extrmement similaires. Depuis les origines de la programmation, les concepteurs de langage de haut niveau se sont systmatiquement emprunts les bonnes ides, tout en mettant de ct les faiblesses et les limitations.
LE GUIDE COMPLET 15

Chapitre 1

Introduction

Certains langages rcents trouvent ainsi leurs origines dans les annes 1960. En analysant minutieusement sa syntaxe, nous pouvons ainsi nous rendre compte que le langage de Microsoft C# (C Sharp) est directement issu dun langage aujourdhui compltement oubli : le BCPL. Vous devriez donc tre en mesure, lissue de cet ouvrage, de lire sans difficult majeure un listing de code crit dans la plupart des langages modernes de haut niveau.

Langages interprts et langages compils


Il serait bien videmment inutile et fastidieux de connatre plusieurs langages si ces derniers proposaient tous les mmes fonctionnalits. Comme vous pouvez vous en douter, ce nest pas du tout le cas : chaque langage dispose de ses particularits, de ses avantages et de ses dfauts. La premire grande diffrence observer entre les diffrents langages cits prcdemment se situe dans leur mode de fonctionnement : certains sont classer parmi les langages interprts et dautres parmi les langages compils.
Tableau 1.1 : Langages interprts et langages compils

Langages interprts PHP Perl Python JavaScript

Langages compils C C++ Java Pascal

Dtails

Rien ntant jamais simple en informatique, vous pourrez effectivement lire quil est possible de compiler du Perl ou du PHP, que les excutables Java et C# sont en fait interprts par des machines virtuelles, que des processeurs Crusoe de Transmeta deviennent des interprteurs de binaires. Ce ne sont toutefois que des dtails, et il est vident quaujourdhui toutes ces notions ont tendance se mler les unes aux autres.

La diffrence entre ces deux types de langages se situe au niveau de leur mode dexcution.
16 LE GUIDE COMPLET

Les langages de programmation

Chapitre 1

Pour excuter un programme crit dans un langage non interprt, il est ncessaire de compiler le code source pour en faire un binaire. Le compilateur est le programme qui se charge de cette opration. Chaque langage dispose ainsi dun compilateur qui lui est propre : celui du C sappelle gcc, celui du Java se nomme javac. lissue de cette phase dite de compilation le binaire pourra tre excut par la machine. Le compilateur sest en ralit charg de convertir toutes les lignes de code dans un langage de bas niveau (lassembleur dans le cas du C), illisible par lhomme mais comprhensible par un processeur.
Listing 1-7 : exemple de code crit en assembleur .data msg: .ascii "Hello, world!\n" len = . - msg .text

.global _start

_start: movl $len,%edx movl $msg,%ecx movl $1,%ebx movl $4,%eax int $0x80 movl $0,%ebx movl $1,%eax int $0x80

Pour excuter un script crit avec un langage interprt, il faut, comme son nom lindique, passer par un interprteur. Cet interprteur lit le code pas pas et le convertit au fur et mesure en instructions pouvant tre traites par le processeur. Quand on parle de PHP, on parle donc la fois du langage et de linterprteur.
Script

Le terme script est souvent utilis lorsque lon souhaite faire rfrence un programme crit dans un langage interprt. On parle ainsi de script PHP ou Perl.

LE GUIDE COMPLET 17

Chapitre 1

Introduction

Voyons rapidement les avantages et les inconvnients de chacun de ces deux modes.

Avantage du langage compil


La conversion en binaire est ralise une fois pour toutes lors de la phase de compilation. La suite Office de Microsoft, par exemple, a t compile une fois, et ce sont des versions binaires que lon trouve sur les talages des grandes surfaces. Un programme compil est donc plus rapide sexcuter quun programme interprt qui, lui, devra tre converti chaque excution.

Inconvnient du langage compil


Le binaire issu de la compilation nest pas excutable universellement . Ainsi, un binaire excutable sur un PC fonctionnant sous Windows ne le sera pas sur un PC sous Linux ou OS2 : il sagit ici dune incompatibilit de systme dexploitation. De la mme manire, un binaire compil sur PC ne pourra pas fonctionner sur Mac ou Sun : il sagit alors dune incompatibilit darchitecture machine. Il est donc facile dimaginer le casse-tte pour des socits souhaitant faire fonctionner et vendre leur logiciel sur le plus grand nombre de plateformes possible.

Avantage du langage interprt


Un programme PHP ntant ni plus ni moins quun simple chier texte contenant des lignes de code, il est interprtable sur tout type de machine ou de systme dexploitation sans que cela ncessite la modication de la moindre virgule : on appelle cela la portabilit . Le march potentiel dun programme crit en PHP est par l mme bien plus vaste que celui dun programme compil qui, gnralement, nest dvelopp que pour un systme dexploitation et une architecture donns.

Inconvnient du langage interprt


En plus de la relative lenteur par rapport au langage compil, il convient de noter un inconvnient de taille pour les personnes souhaitant vendre leur programme : la fourniture du code source. Alors quil est impossible de deviner comment un programme compil a t conu, il est tout fait possible pour une socit cliente ayant achet un

18 LE GUIDE COMPLET

Les langages de programmation

Chapitre 1

programme crit en PHP de voir comment celui-ci a t cod et ainsi de voler les ides et le savoir-faire du concepteur. Autre problme de taille : la ncessit de disposer de linterprteur pour pouvoir excuter un script. Alors que vous pouvez transmettre un binaire par courriel et tre sr quil pourra tre excut chez votre ami, il conviendra pour un script PHP de vrier que cet ami dispose pralablement sur son ordinateur de linterprteur PHP. Or, il peut tre assez gnant dimposer linstallation dun tel environnement pour la simple excution dun programme.
Compilation de PHP

La socit Zend, dont nous allons parler plus loin dans ce chapitre, a dvelopp un outil qui permet de convertir un programme PHP en un chier contenant un code intermdiaire illisible par lhumain, mais lisible par un interprteur PHP (et cela quels que soient larchitecture et le systme dexploitation !). Il ne sagit ni plus ni moins que dun compilateur PHP dguis.

Les domaines dapplication


En plus de cette diffrence de fonctionnement, les langages ont souvent t conus pour des domaines dapplication prcis.
j j j j j

ASP, PHP, CFM : le Web. C : applications systme. Java : applications pour systmes embarqus portables, cartes puce). Perl : administration systme. C++ : applications avec interfaces graphiques.

(tlphones

Bien que tout programme puisse tre crit avec tout langage, certains vous permettront de le dvelopper en 10 lignes, alors que dautres en ncessiteront 300.
Choix du langage

Bien que PHP soit un langage aussi polyvalent quattractif, il ne faut surtout pas tomber dans lexcs qui consisterait vouloir tout raliser en PHP. Dautres langages, pour des problmatiques bien prcises, peuvent se rvler suprieurs PHP. Il est donc toujours intressant de se tenir

LE GUIDE COMPLET 19

Chapitre 1

Introduction

inform et de surveiller les autres technologies et nouveauts (cela tant dautant plus vrai en informatique o les choses voluent beaucoup plus vite quailleurs).

1.2. Le PHP
Le PHP est un langage interprt qui a t conu ds son origine pour le Web. Il est aujourdhui devenu le leader incontest dans ce domaine. Plus de 9 millions de sites lont aujourdhui choisi comme plateforme de dveloppement web.

Les raisons du succs


Elles sont la fois nombreuses et varies.

Rapidit, stabilit, scalabilit, scurit


PHP est le langage de scripting le plus rapide du march. Cest rellement important quand vous devez raliser un site devant recevoir plusieurs centaines de milliers de visiteurs par jour. Plus le script met de temps tre interprt, plus lattente est importante pour linternaute. Or, noubliez jamais que rien nest pire sur le Web que de faire attendre un internaute ! Cette rapidit est dautant plus impressionnante que PHP dispose dautres proprits toutes aussi essentielles.
j j

Stabilit : PHP nest pas bugg et ne plante pas. Scalabilit : quil y ait cent ou un million dinternautes qui viennent sur votre site, PHP continuera excuter vos scripts (certes plus lentement dans le cas dun million de requtes). Scurit : PHP est un systme trs sr dont les rares failles ont toujours t corriges dans la journe.
Scurit et PHP

Il faut bien faire la diffrence entre la scurit de PHP en tant que systme et la scurit dun logiciel crit en PHP. Le fait que PHP soit scuris nimplique pas pour autant quune application crite en PHP soit elle-mme scurise. Un programmeur peut ainsi tout fait laisser dans son code une faille de scurit qui pourra tre exploite par un
20 LE GUIDE COMPLET

Le PHP

Chapitre 1

pirate. Il est donc trs important de prendre de bonnes habitudes en vriant toujours que son code ne contient pas de faiblesse. Le chapitre consacr la scurit devrait vous y aider.

Open Source
Le projet PHP est un projet open source. Lopen source est un mouvement plantaire qui regroupe les meilleurs dveloppeurs mondiaux et qui a pour principe fondateur la mise disposition des sources des logiciels (cest--dire les listings de code qui ont permis de raliser le logiciel). Ainsi, alors que lASP nest dvelopp que par Microsoft, PHP est un projet sur lequel travaillent des centaines dtudiants, de chercheurs et ingnieurs travers le monde. En disposant des sources, tout un chacun peut tudier la manire avec laquelle le langage est conu et peut aussi corriger les ventuels dysfonctionnements (bugs). Cela explique directement que PHP soit un langage extrmement stable ne souffrant que de trs rares bugs ou failles. Appartenant tout le monde et personne en mme temps, les logiciels Open Source ont un norme avantage par rapport leurs cousins propritaires : ils ne peuvent pas disparatre. Si une socit ditrice dun langage dpose le bilan, le langage disparat avec la socit. Pour PHP, cela ne peut arriver. Nimporte quel tudiant dispose des sources et peut reprendre le ambeau. En ces temps de troubles et de difficults pour les diteurs de logiciels, cette notion ne doit pas tre mise de ct. Un autre avantage travailler avec des logiciels open source tel que PHP est davoir sa disposition une norme bibliothque de scripts dont les sources peuvent tre rcupres gratuitement sur le Web. Il devient aujourdhui assez rare de ne pas trouver sur le Web un morceau de code qui ne rpondrait pas exactement vos besoins. Le chapitre Webographie vous indique une srie de sites proposant le tlchargement de scripts PHP.

Fonctionnalits
Grce lopen source, chacun peut ajouter sa pierre ldice, en amliorant ou en dveloppant certaines parties. Le cycle de

LE GUIDE COMPLET 21

Chapitre 1

Introduction

dveloppement de PHP est par consquent trs rapide, et chaque nouvelle version est accompagne de son lot de nouvelles fonctionnalits. PHP contient donc un trs grand nombre dextensions qui permettent par exemple :
j j j j j j

de gnrer des images, des chiers PDF, Flash ; de se connecter des serveurs FTP, LDAP, de mail ; de travailler avec des bases de donnes (MySQL, MS SQL, Oracle, Informix, PostgreSQL) ; de manipuler des chiers XML ; dinteragir avec des Web Services ; de sinterfacer avec des systmes de paiement scuris.

PHP est un langage dune trs grande exibilit. Quelle que soit la complexit du logiciel concevoir, il est trs peu probable de se retrouver limit par PHP. Comme le C, PHP vous permet de tout faire, le plus souvent trs rapidement. Cette ressemblance avec le C ne sarrte dailleurs pas l. PHP dispose en effet dune syntaxe trs proche de celle du C. Quand on sait que le C est un des langages les plus rpandus, cela se rvle un choix tactique : beaucoup de programmeurs ont pu de la sorte passer du C PHP en quelques heures et venir enrichir la communaut de dveloppeurs. Plus un langage dispose de dveloppeurs, plus vous avez de chances dobtenir des rponses dans les forums, de trouver des documents et des exemples sur le Web.

Gratuit
PHP fait partie de cette famille de logiciels que lon qualie de free software, free dans le sens de libre (open source), mais galement dans le sens de gratuit . Bien que PHP soit de loin ce qui se fait de mieux dans le domaine, il est, la diffrence de ses principaux concurrents (ASP, ColdFusion), entirement gratuit. PHP nest pas le seul logiciel gratuit et open source dont nous allons parler dans ce livre : Linux (systme dexploitation), Apache (serveur web), MySQL (moteur de base de donnes) sont dautres logiciels incontournables du monde du Web et sont tout aussi libres et gratuits.

Universel
Linterprteur PHP est aujourdhui disponible sur un trs grand nombre darchitectures (PC, Mac), de systmes dexploitation (Windows, Mac OS X, Linux, Unix, etc.) et de serveurs web (Apache, IIS, AOLserver,
22 LE GUIDE COMPLET

Le PHP

Chapitre 1

Roxen, etc.). Ainsi, si vous changez un jour dhbergeur, il y a de fortes chances que votre application continue de fonctionner.

Apache/Linux
Bien que fonctionnant sur la grande majorit des serveurs web et sur la plupart des systmes dexploitation, PHP est avant tout li au serveur Apache et au systme Linux. Ce sont l les vritables applications phares du monde de lopen source et du Web. Apache est de loin le serveur web le plus utilis au monde. Cest lui qui vous sert les pages des plus gros sites mondiaux (Yahoo!, Google). Linux est quant lui le deuxime systme dexploitation derrire Windows dans le domaine des serveurs web.

Les concurrents
PHP est loin dtre le seul langage de scripting pour le Web. On trouve parmi ses concurrents

Ruby
Ses avantages :
j

Il sagit dun vritable langage objet o tout lment du langage est lui-mme objet. Il ravira les dveloppeurs exigeants au niveau modlisation ainsi que ceux, plus dbutants, souhaitant mettre en place des interfaces graphiques le plus rapidement et simplement possible. La disponibilit de la plateforme RAILS pour raliser des applicatifs web en AJAX est un vritable atout du fait de la trs grande popularit de cet environnement. Gratuit, open source et disponible sur une grande varit de plateformes.

Ses inconvnients :
j

Langage assez rcent, il est encore peu rpandu chez les hbergeurs et risque de mettre encore quelques annes avant dtre accept au sein des grands groupes.

Python
Ses avantages :
LE GUIDE COMPLET 23

Chapitre 1
j j j

Introduction

Ce langage est extrmement bien pens et permet une qualit de dveloppement objet largement suprieure celle du PHP. Gratuit, libre et largement portable. Le langage Python tend de plus en plus remplacer Perl dans le cur des administrateurs systme et voit sa base dutilisateurs stendre de jour en jour.

Ses inconvnients :
j j

La syntaxe du langage fonde sur lindentation peut paratre douteuse certains. Le Web est loin dtre la priorit des concepteurs.

ASP (Microsoft)
Ses avantages :
j

ASP est ce quil y a de mieux lorsque lon souhaite ne travailler quavec des outils Microsoft et tre assur de la compatibilit avec IIS, Front Page, Visual Studio, SQL Server, Access. Les outils clients sont gnralement trs bien raliss, que ce soit pour grer les pages, la base de donnes ou le serveur web. Cela permet un non-ingnieur systme dadministrer une solution web complte.

Ses inconvnients :
j j

ASP souffre de faibles performances et ne peut tre excut quavec IIS sous Windows. Le serveur web IIS, pierre angulaire dune solution Microsoft, nest pas citer en exemple en termes de scurit. Les attaques gravissimes sur des machines disposant de ce logiciel sont communes (voir Red Code, Nimda) et ont parfois paralys des socits entires. Il sagit dun choix onreux dans la mesure o le logiciel est payant tout comme les technologies adjacentes (Visual Studio, Front Page, SQL Server) qui sont vivement recommandes an de rester dans un environnement Microsoft et dviter les incompatibilits. Il sagit ici de la partie merge de liceberg car il convient dajouter ces licences un prix dhbergement et dadministration souvent beaucoup plus lev. Et ne croyez pas faire des conomies en hbergeant en interne car il sagira dans ce

24 LE GUIDE COMPLET

Le PHP

Chapitre 1

cas dinvestir dans une machine disposant dnormes ressources autant au niveau du processeur que de la mmoire.

ASPX, C# (Microsoft)
Ses avantages :
j

la diffrence dASP, les scripts ASPX peuvent maintenant tre excuts sur des serveurs Apache disposant du module libre et gratuit Mono (www.mono-project.com/Main_Page). Les ASPX peuvent tre crits en C# qui est sans nul doute un magnique langage de programmation.

Ses inconvnients sont les mmes que lASP.

CFM (Macromedia-Allaire) : ColdFusion


Ses avantages :
j

Lenvironnement de dveloppement de ColdFusion est ce qui peut se faire de mieux dans le genre. Vous disposez en achetant ce logiciel dun outil central disposant dune interface graphique complte vous permettant de dvelopper votre code, vos pages web, denvoyer vos documents sur un serveur FTP. Le langage a t dvelopp avec la simplicit en ligne de mire. Par consquent, il sagit peut-tre de la meilleure solution pour un public dbutant ne souhaitant pas aller trs loin dans le dveloppement web.

Ses inconvnients :
j

Le langage est plutt lourd, mal conu et nvolue que trs lentement. Ds que lon souhaite aller assez loin dans le dveloppement, les dfauts et les limitations apparaissent trs vite (on pense notamment la gestion assez primaire des expressions rgulires ). Les hbergeurs proposant le ColdFusion ne sont pas nombreux et font souvent payer ce service assez cher. Le serveur web est aussi propritaire et, mme si ses performances sont honorables, elles sont loin dtre aussi bonnes que celles dApache. Comme lASP, cet environnement de dveloppement est payant.

LE GUIDE COMPLET 25

Chapitre 1

Introduction

Perl
Ses avantages :
j

Trs vieux langage, Perl dispose dune bibliothque dextensions extrmement riche (par exemple, cration de chiers Excel la vole, connexion une multitude de serveurs, etc.). Gratuit, open source et disponible sur une grande quantit de plateformes.

Ses inconvnients :
j j

Ce langage na pas t dvelopp dans une optique web et peut donc souffrir dune certaine lourdeur. Linstallation sur une machine cliente est souvent bien plus complique que les systmes vus prcdemment.

Des logiciels en ligne


De plus en plus dapplicatifs sont dvelopps avec ces langages orients web. Comme il est ncessaire dtre connect, on les qualie frquemment de logiciels en ligne (online softwares ou web applications). Les avantages de tels applicatifs sont assez nombreux :
j

j j

Lapplicatif tant centralis, sa mise jour devient extrmement simple (nul besoin de changer quoi que ce soit sur les postes des utilisateurs). Le march est immense. Toutes les personnes disposant dun navigateur web et dune connexion au Net peuvent y accder (quel que soit le systme dexploitation ou larchitecture). Les donnes de la socit sont centralises, tous les employs peuvent y accder de manire collaborative. Seul le serveur web doit tre scuris, ce qui simplie grandement la tche des responsables informatiques. De la mme manire, les sauvegardes deviennent trs simples grer.

Tout naturellement, ces logiciels se sont dvelopps principalement pour le monde de lentreprise : gestion commerciale et nancire, intranet et extranet, commerce lectronique, gestionnaire de planning, de messagerie, dagenda, etc.

26 LE GUIDE COMPLET

Le PHP

Chapitre 1

Microsoft a bien compris que le march du logiciel allait dans ce sens, et cest dans cette optique quil tend pousser sa plateforme de dveloppement .NET. Lavenir ira sans nul doute vers une dcentralisation et une location des logiciels.
Interactions entre langages

Parmi les extensions peu connues de PHP, nous pouvons mentionner le fait que PHP est dsormais capable de rcuprer du code dautres langages et de lexcuter. Plus exactement, PHP est en mesure de charger des objets crits en Java ou en C# et de faire appel aux diffrentes fonctions et mthodes contenues dans ces mmes objets. Cette fonctionnalit est surtout utile dans le monde de lentreprise o dnormes librairies extrmement complexes ont dj t crites (notamment en Java) pour des environnements peu ou pas documents. En permettant ces interactions, PHP trouve sa place au cur des grands chantiers informatiques et commence tre envisag par les SSII souvent soucieuses daller au plus vite, au plus simple et au plus sr.

Lhistoire
Le langage PHP, comme la plupart des grands projets open source, est n dune volont individuelle et isole. Conu au dpart pour rcuprer des informations sur les internautes qui visitaient sa page personnelle, PHP est rest pendant plus dune anne le jouet de son unique concepteur : Rasmus Lerdorf. cette poque, PHP signiait Personal Home Page (on en parlait frquemment sous le nom PHP/FI).

Figure 1.1 : Le logo de PHP

Ce nest donc quen 1995, la suite dune annonce dans les newsgroups, que ce projet est devenu accessible au reste du monde. PHP devenait alors PHP: Hypertext Preprocessor. Trs simple au dbut, le langage a pu, avec laide de la communaut open source, senrichir de nouvelles fonctionnalits, notamment laccessibilit aux bases de donnes.

LE GUIDE COMPLET 27

Chapitre 1

Introduction

Ds cette poque, le projet sinternationalisa, et des dveloppeurs, originaires de Norvge, dIsral, dAllemagne, des tats-Unis, prirent lhabitude de participer rgulirement au dveloppement de PHP. De 15 000 en 1996, le nombre de sites utilisant PHP a atteint 50 000 en 1997. Cest cette priode que le projet est pass sous la direction de Zeev Suraski et Andi Gutmans. Ces deux tudiants israliens dcidrent de rcrire le langage de A Z. Cette nouvelle version devint PHP 3.

Figure 1.2 : volution du nombre de sites qui utilisent PHP

Aprs cet norme bond en avant que fut PHP 3, les dveloppeurs se remirent au travail avec la ferme intention doptimiser le cur de PHP pour obtenir des performances encore meilleures (personne ne se plaignait pourtant des performances de PHP cette poque !). Plutt que dexcuter les instructions une une, il fut dcid de choisir une nouvelle approche : compiler le code, puis lexcuter. Ce travail a eu lieu dans le cadre du Zend Engine, qui est aujourdhui le vritable cur de PHP 4. Cette nouvelle mouture est sortie en 2000. Lintgration du Zend Engine dans le cadre de PHP 4, outre le gain en performances, apporte une plus grande modularit et une meilleure extensibilit. PHP est aussi devenu indpendant de la couche serveur web , ce qui en fait aujourdhui un des systmes les plus compatibles du march. PHP 5, sorti en juin 2004, est bas sur un Zend Engine de nouvelle gnration (version 2). Cette nouvelle version vise principalement combler des lacunes du langage dans les domaines de la programmation objet, des bases de donnes et des services web. En sattaquant ces domaines, PHP se donne une lgitimit accrue dans le monde de lentreprise et peut dautant plus facilement tre envisag pour des

28 LE GUIDE COMPLET

Le PHP

Chapitre 1

projets critiques. PHP 4 reste aujourdhui la version de PHP la plus populaire du fait de sa stabilit extrme et de sa trs large diffusion parmi les hbergeurs. Alors que nous crivons ces lignes, PHP 6 est en phase de dveloppement. Lobjectif principal de cette version sera de rendre PHP parfaitement compatible avec les rouages complexes de lInternationalisation (I18N).

Aujourdhui
Zeev Suraski a fond la socit Zend Technologies (www.zend.com). Cette socit fournit des logiciels payants autour du langage PHP :
j

Zend Encoder rend vos scripts PHP illisibles (ce qui est utile quand lon souhaite vendre ses scripts sans pour autant dvoiler ses connaissances). Zend Accelerator permet dacclrer lexcution des scripts PHP avec un systme de cache (le site officiel indique des gains de rapidit jusqu 300 %). Zend IDE est un outil permettant de dvelopper en PHP de manire plus conviviale.

Figure 1.3 : Lenvironnement de dveloppement propos par Zend

LE GUIDE COMPLET 29

Chapitre 1

Introduction

La socit Zend propose aussi un produit non open source mais gratuit : Zend Optimiser. Il sagit dune librairie qui permet doptimiser la vole votre code au moment o celui-ci est excut.
Argent et open source

Les dollars et lopen source nont jamais fait bon mnage. La russite de cette socit est donc dautant plus remarquable. En vendant des solutions des socits (qui en ont souvent largement les moyens), Zend est en mesure demployer des dveloppeurs qui travaillent 100 % de leur temps sur PHP. Toute la communaut PHP prote ainsi directement du succs et de la bonne sant nancire de la socit Zend.

Le rouleau compresseur PHP est dsormais en marche et nul ne sait o il sarrtera. Des conventions et des confrences ont lieu dsormais tous les mois autour de ce langage ; des milliers de sites, des centaines douvrages, et mme des magazines vendus en kiosques se consacrent maintenant exclusivement PHP. Mme le gouvernement franais sintresse au phnomne et donne des instructions auprs de ses ministres an que leurs sites soient conus sur des solutions Lamp (par exemple SPIP Agora). Le Web est devenu central, aussi bien dans notre vie de tous les jours que dans la vie des entreprises, et PHP est en passe de devenir lun des vecteurs dterminants de son expansion.
Technologies Lamp

Toute personne sintressant au PHP a d croiser dans la littrature le terme Lamp. Ce sigle signie Linux/Apache/MySQL/PHP. Lamp est un environnement complet permettant de faire fonctionner une application web. Il dispose dun systme dexploitation (Linux), dun serveur web (Apache), dun systme de gestion de bases de donnes (MySQL) et dun langage de programmation (PHP). Il sagit aujourdhui, et de loin, de lenvironnement le plus performant, le plus sr et le plus abordable du march.

Finissons ce paragraphe avec deux chiffres qui devraient marquer les esprits : plus de 1 million de serveurs web et presque 20 millions de sites exploitent aujourdhui PHP.

30 LE GUIDE COMPLET

Internet, comment a marche ?

Chapitre 1

1.3. Internet, comment a marche ?


Dans cette partie, nous allons essayer de comprendre comment fonctionnent le Web et Internet en gnral. Une bonne comprhension de cette couche rseau vous permettra de mieux envisager le fonctionnement et limportance de PHP.

Web et autres protocoles


Le Web est un rseau mondial de machines parlant la mme langue. En informatique, cette langue est appele un protocole . Le protocole du Web est lHTTP (Hypertext Transfer Protocol). Le Web nest quun rseau parmi tant dautres, HTTP a en effet de nombreux cousins .
Tableau 1.2 : Quelques protocoles de haut niveau et leur fonction

Protocole FTP IRC NNTP POP SMTP

Signication File Transfer Protocol Internet Relay Chat Network News Transfer Protocol Post Office Protocol Simple Mail Transfer Protocol

Fonction Transfert de chiers Dialogue en direct Envoi, lecture de news Rcupration des courriels Envoi des courriels

Chacun a donc un rle qui lui est propre et de nouveaux rseaux se crent tous les jours pour rpondre aux nouveaux besoins des internautes. Nous avons ainsi vu depuis quelques annes lmergence des rseaux P2P de type BitTorrent qui permettent la recherche et lchange de chiers. Crer un nouveau protocole ne consiste en fait qu dnir une nouvelle langue comprhensible la fois par un client et par un serveur.
Tableau 1.3 : Exemple simpli dune dnition de protocole

Requte client HELLO

Rponse serveur HELLO

LE GUIDE COMPLET 31

Chapitre 1

Introduction

Tableau 1.3 : Exemple simpli dune dnition de protocole

Requte client RECEVOIR toto.txt MESSAGE PAUL bonjour

Rponse serveur Envoyer le chier toto.txt Envoyer le message bonjour lutilisateur PAUL

En ralit, lacceptation dun nouveau protocole en tant que standard est extrmement complique. Tout doit tre parfaitement cel . Les cas les plus bizarres doivent avoir t considrs. La page http://sunsite.dk/ RFC/rfc/rfc2616.html prsente le protocole HTTP version 1.1 dans toute sa richesse et sa complexit. Chaque protocole ncessite une application cliente qui lui est propre. Pour le HTTP, cest un navigateur web ; pour le NNTP, cest un lecteur de news ; pour le FTP, il sagit dun client FTP.

Figure 1.4 : Client FTP listant les chiers disponibles ladresse ftp://ftp.cdrom.com

32 LE GUIDE COMPLET

Internet, comment a marche ?

Chapitre 1

Figure 1.5 : Azureus, logiciel permettant de tlcharger sur le rseau

BitTorrent

Cependant, de plus en plus dapplicatifs permettent davoir accs plusieurs protocoles. Ainsi, le logiciel Outlook Express, de Microsoft, permet de lire des courriels (POP) et des news (NNTP). Les navigateurs, quant eux, permettent souvent davoir accs au protocole FTP. Si nous voulons avoir accs au serveur FTP ayant pour adresse ftp.cdrom.com, il suffit de taper lURL (Uniform Resource Locator) ftp://ftp .cdrom.com.

Figure 1.6 : Un navigateur web accdant au serveur FTP ftp.cdrom.com

LE GUIDE COMPLET 33

Chapitre 1

Introduction

TCP/IP et Internet
Malgr cette profusion de protocoles, une chose ne change pas ; ces rseaux sont tous fonds sur un protocole sous-jacent unique : TCP/IP (Transmission Control Protocol/Internet Protocol). Cest cette combinaison de rseaux bass sur TCP/IP que lon appelle Internet. Le rseau Internet est vraiment llment fondateur qui a permis lmergence du Web, du mail et de tous ces services dont nous ne pourrions plus nous passer aujourdhui. Comme pour beaucoup davances scientiques, cette invention est dorigine militaire. Dans les annes 1960, une quipe de chercheurs plancha sur un systme permettant dassurer la continuit des changes dinformations sensibles (entre des postes stratgiques), et cela mme si certains postes (et donc certaines liaisons) taient dtruits. De cet impratif naquit TCP/IP. Ce protocole permet de dcouper les informations (pages web, courriels, images) en petits paquets et de les acheminer (de les router ) dun point un autre. Lide originale est la suivante : pour arriver la mme destination, tous ces paquets ne sont pas obligs de passer par la mme route. Il est ainsi possible quun paquet passe par lAsie pour aller de la France vers lAngleterre si aucune autre route nest ce moment disponible. Il faut donc imaginer Internet comme un maillage mondial de serveurs interconnects. Cest du fait de cette architecture que lon parle, propos du Web, de toile daraigne .

Figure 1.7 : Quelques interconnexions europennes de la socit Cable and Wireless

34 LE GUIDE COMPLET

Internet, comment a marche ?

Chapitre 1

Et le fournisseur daccs dans tout a ? Quil sagisse de Free, de Wanadoo, dAOL, etc., son rle est de relier votre ordinateur aux autres machines prsentes sur Internet. La ligne tlphonique assume alors la fonction de lien. Votre modem sert faire transiter les donnes informatiques entre Internet et votre ordinateur. Comme les modems classiques sont trs lents, dautres mthodes sont maintenant proposes pour crer un canal entre Internet et vous : le cble (le mme qui vous permet daccder aux chanes de tlvision), les lignes tlphoniques boostes (lADSL), le satellite (pour les plus fortuns), les ondes radio et bientt vos prises lectriques, le WiMax.

Le serveur web
Le Web est donc un protocole applicatif fonctionnant sur un mode client-serveur. Quand linternaute souhaite voir la page information du site monsite.com, situe ladresse (URL) www.monsite.com/info.html, il utilise un navigateur de type Internet Explorer, Netscape, Firefox, Opera, Lynx, Konqueror

Figure 1.8 : Le site kernix.com vu depuis le navigateur ELinks (mode texte)

sous Unix

Le navigateur va ensuite demander au serveur ayant ladresse www .monsite.com de lui transmettre la page ayant pour nom info.html. Essayons de comprendre plus en dtail comment cet change se droule.

LE GUIDE COMPLET 35

Chapitre 1

Introduction

tape 1 : le navigateur envoie une requte


Vous commencez par crire lURL http://www.google.fr/index
.html dans votre navigateur.

Figure 1.9 : Affichage dune URL dans un navigateur

Une fois cette adresse valide, le navigateur va enchaner diffrentes actions. Il commence par regarder quel type de protocole va tre utilis. Si lURL commence par http://, cest le protocole HTTP. En revanche, sil sagit de ftp://, le navigateur devra alors utiliser le protocole FTP. Il doit ensuite dcouvrir o se trouve le serveur web www.google.fr. Pour cela, il va utiliser un autre service du Net : les DNS (Domain Name Server ; des adresses DNS sont systmatiquement fournies par votre fournisseur daccs). Les DNS sont des serveurs qui permettent dassocier un nom de domaine (www.google.fr) une IP (216.239.39.101), un peu comme les pages blanches associent M. Dupont son numro de tlphone 01 02 03 04 05. Cette adresse IP est unique et identie par consquent de manire tout aussi unique le serveur web. Cest donc grce cette adresse IP que votre navigateur va pouvoir reprer le bon serveur sur Internet et entrer en contact avec lui. Comme il sagit, dans ce cas, du protocole HTTP, le navigateur va communiquer avec le serveur HTTP (web) du serveur 216.239.39.101. La requte qui sera faite vise obtenir la page ayant pour nom index.html.
IP de Google

Si vous tapez lURL http://216.239.39.101, vous arrivez sur la mme page, ce qui est dailleurs plutt rassurant.

tape 2 : le serveur web retourne le chier


Le serveur web a donc reu une requte dune machine qui souhaite obtenir le chier index.html. Il va donc chercher sur son disque dur le chier index.html, rcuprer son contenu, puis envoyer ce ux de donnes au navigateur. Il sait o le renvoyer car, ds que vous tes sur Internet, vous disposez vous aussi dune adresse IP visible de lextrieur.
36 LE GUIDE COMPLET

Internet, comment a marche ?

Chapitre 1

Votre adresse IP

Si vous tes reli Internet et que votre systme dexploitation est Windows, vous pouvez connatre votre adresse IP en tapant la commande IPCONFIG (la commande peut tre excute sous DOS ou directement depuis le menu Dmarrer/Excuter). Si, ensuite, vous installez un serveur HTTP (apache, IIS) ou FTP (WS_FTP Serveur) sur votre machine, vous serez en mesure dtre vu depuis lextrieur. Si vous transmettez votre adresse IP un ami, celui-ci pourra se connecter directement votre machine avec un navigateur ou un client FTP. Votre machine joue alors le mme rle quun serveur dhbergement, la diffrence prs que votre liaison nest, dans tous les cas, pas trs rapide. Sachez, par contre, que votre IP nest pas xe. chaque fois que vous vous connectez ou dconnectez, vous changez dIP.

Figure 1.10 : Ladresse IP est ici 192.168.0.203

En revanche, si vous aviez demand lURL www.google.fr/intl/fr/about.html, le serveur serait rentr dans le rpertoire intl, puis dans le rpertoire fr, et il aurait trouv cet endroit le chier about.html. Vous comprenez donc quune URL est compose de plusieurs lments :
j j j

le protocole http:// ; ladresse Internet du serveur, www.google.fr (adresse qui peut donc tre une adresse IP) ; le chemin du chier /intl/fr/about.html.

LE GUIDE COMPLET 37

Chapitre 1

Introduction

Le chemin est similaire un chemin sur votre disque dur (par exemple C:\tmp\message.txt), sauf quil est not sous la norme des chemins Unix : /tmp/message.txt, o la premire barre oblique (/) correspond la racine.
Majuscules ou minuscules dans les URL ?

Pour rpondre cette question, il est ncessaire de diviser le problme en deux. Le nom de domaine (par exemple www.google.fr) dun ct et le chemin daccs au chier (par exemple /index.html) de lautre. Les DNS ntant pas sensibles la casse ( la diffrence majuscule/minuscule), les URL http://google.fr et http://wWW.gOOglE.fR sont donc quivalentes. En ce qui concerne les chemins, le problme est plus compliqu. Si le serveur HTTP fonctionne sous Unix, il sera sensible la casse. Les chemins /index.html et /index.htmL seront donc diffrents. Sil fonctionne, par contre, sous Windows, le serveur ne sera pas sensible cette diffrence. Les serveurs HTTP fonctionnant essentiellement sous Unix/Linux, il est donc prfrable de faire attention la faon dcrire le chemin daccs une page ou un script.

tape 3 : le navigateur traite le chier


Le navigateur reoit donc le contenu du chier index.html. Comme lextension du chier est .html, il sera trait comme un chier HTML (voir Figure 1.11). Le navigateur ne reoit dans un premier temps que le contenu textuel de la page. Il doit donc, avant dafficher la page, rcuprer toutes les images contenues dans celle-ci. Il regarde dans le code, trouve toutes les adresses des images et fait des requtes au serveur web pour les obtenir une par une. Bien videmment, ces sous-requtes sont totalement transparentes pour vous. Vous tes cependant en mesure de les raliser vous-mme : quand le navigateur a besoin de limage de titre, la requte est la suivante : http://www.google.fr/images/title_homepage4.gif. Si vous tapez cette URL dans votre navigateur, vous nobtenez alors, comme prvu, que limage de titre (voir Figure 1.12).

38 LE GUIDE COMPLET

Internet, comment a marche ?

Chapitre 1

Figure 1.11 : Voici le contenu du chier index.html que reoit le navigateur

Figure 1.12 : Requte permettant de nobtenir que limage de titre

LE GUIDE COMPLET 39

Chapitre 1

Introduction

Une fois tous les lments constitutifs de la page rcuprs par le navigateur, celle-ci peut tre affiche.

PHP
Vous avez vu que lorsque le navigateur fait une requte sur un chier HTML ou sur une image le serveur lui retourne le contenu du chier tel quel, sans lui apporter la moindre modication. Quand, par contre, la requte est faite sur un chier disposant dune extension .php, tout se passe diffremment. Si le serveur web est compatible PHP, celui-ci va traiter tous les chiers .php comme des scripts et transmettra par consquent le ux de donnes (le contenu du chier) linterprteur PHP avant de lenvoyer linternaute. Cet interprteur aura donc pour charge dvaluer (dinterprter) le code source PHP et de remplacer les lignes de code par leurs rsultats. Prenons lexemple dun chier test.php contenant le code suivant :
<?php print("bonjour monde"); ?>

Avant dtre transmis linterprteur, le ux de donnes contient encore le code ci-dessus. Une fois le travail de linterprteur termin, le ux interprt ne contient plus que "bonjour monde". Cest prcisment cette phrase "bonjour monde" qui sera transmise et qui apparatra dans votre navigateur. Au niveau du serveur web, PHP tel un ltre modie donc la vole le ux de donnes. Il devient vident quun script crit en PHP qui naurait pas dextension serait considr comme un simple chier texte (ou HTML) et ne serait pas trait en tant que script PHP (son code ne serait pas interprt).

Figure 1.13 : Sans extension, le script est considr comme du simple texte

40 LE GUIDE COMPLET

Internet, comment a marche ?

Chapitre 1

Figure 1.14 : Avec une extension .php, le script est reconnu comme un script PHP ; il est donc interprt

Le script doit avoir une extension particulire pour tre reconnu en tant que script PHP. Lextension la plus rpandue est .php (par exemple test.php). Il est nanmoins possible de rencontrer dautres extensions : .php3 ou .phtml. Lhbergeur prcise gnralement quelle extension doit tre utilise. Si le choix vous est offert, utiliser lextension .php semble plus logique car nous en sommes aujourdhui la version 5 de PHP. De plus, cette extension risque fort de devenir la norme.

Les autres langages du Web


Les personnes intresses par les technologies lies au Web auront pu sapercevoir de la grande quantit de langages qui fourmillent sur la Toile. Nous nous sommes dj arrts sur les langages interprts au niveau serveur tels que PHP, Perl, CFM, ou ASPX. Il existe une autre catgorie de programmes qui, eux, sont excuts au niveau du client (dans le navigateur) : les Javascripts, les applets Java et les animations Flash.

Javascript
Expliquons rapidement la diffrence de fonctionnement entre ces deux modes.
j

Niveau serveur : le script est excut sur le serveur la suite dune requte dun navigateur. Le client reoit ainsi une page prte tre affiche. Niveau client : la page retourne par le serveur web contient du code. Cest au niveau du navigateur que ce code va tre excut.

tudions deux exemples :

LE GUIDE COMPLET 41

Chapitre 1

Introduction

Listing 1-8 : test.php <html> <body> <?php print("test"); ?> </body> </html> Listing 1-9 : test.html <html> <body> <script language=javascript> document.write("test"); </script> </body> </html>

Figure 1.15 : Rsultat obtenu avec test.php ou test.html

Ces deux programmes donnent un rsultat identique, mais sont fondamentalement diffrents. Dans le premier cas, le navigateur reoit une page qui contient dj le mot test, il peut donc lafficher instantanment. Dans le deuxime cas, en revanche, il reoit une page qui contient du code Javascript. Il doit par consquent excuter ce code avant dafficher la page. Un navigateur ne grant pas le Javascript naurait rien affich lcran. Chaque mode a bien videmment ses inconvnients.
j

Au niveau serveur : le fait de devoir interprter le script ds quune requte lui parvient est trs lourd grer pour le serveur et peut conduire des ralentissements au niveau de la livraison des pages. Dans le cas de lexemple ci-dessus, si 10 000 personnes demandent la page test.php, le serveur devra interprter 10 000 fois le script. Si en revanche 10 000 personnes demandent

42 LE GUIDE COMPLET

Internet, comment a marche ?

Chapitre 1

la page test.html, le serveur se contente denvoyer 10 000 fois la page et les 10 000 excutions se feront chez les clients. Ce mode permet de rpartir la charge de travail et de navoir aucun ralentissement. Dans le cas ci-dessus, les deux versions se valent, mais imaginez un script cens chercher et afficher la 100 000e dcimale du chiffre pi ! Au niveau client : le Javascript est un langage certes normalis, mais qui est gr de faon plus ou moins performante, avec plus ou moins de fonctionnalits selon les navigateurs. Il est ainsi trs difficile de rendre un applicatif Javascript excutable sur tout type de systme.
Incompatibilits entre navigateurs

Bien que des normes soient dictes rgulirement par le W3C pour faire voluer le Web, nous pouvons hlas ! dplorer le fait que les diffrents navigateurs ne les suivent pas scrupuleusement. Microsoft notamment, avec Internet Explorer, a particulirement compliqu la vie des dveloppeurs web en leur imposant dcrire des codes sortant de la norme an de rester compatible avec son navigateur vedette. Lmergence de Firefox et plus gnralement du monde du libre (free software) commence nanmoins marquer les esprits et Microsoft devrait avec son futur Internet Explorer 7 gagner en compatibilit (Javascript, CSS, DOM).

Java
Il est important, avant de clore ce chapitre, de sintresser quelques instants Java. Dvelopp par la socit Sun Microsystem, initialement pour des composants embarqus, ce langage a fait leffet dune bombe lors de sa sortie. Le principe tait relativement simple et rvolutionnaire : crer un langage qui permette de tirer prot des avantages du langage interprt et du langage compil. Au lieu de compiler des sources Java directement en un binaire propre un type de processeur, la compilation se fait dans un langage intermdiaire (bytecode), qui doit tre interprt, par la suite, par une machine virtuelle. Linterprtation est alors facilite et correspond plus une conversion. Il fut trs vite vident que Java aurait son rle jouer sur le Web, o foisonnaient une multitude de systmes (Mac, PC, Windows, Unix, etc.), et ce fut par lintermdiaire des applets quil se t connatre du grand public. Une applet java est un programme Java qui sexcute dans un navigateur. la diffrence du Javascript, il est possible, en Java, de
LE GUIDE COMPLET 43

Chapitre 1

Introduction

construire des applications disposant dinterface graphique complexe. Des applets de tableurs, de dessins, de chats rent ainsi leur apparition sur le Web la stupfaction gnrale.

Figure 1.16 : Un logiciel de chat dans un navigateur web

la plus grande joie des internautes, les applets Java permirent aussi larrive des jeux sur le Web.

Figure 1.17 : Spaceball : jeu crit en Java, fonctionnant sur tout type de

plateforme

44 LE GUIDE COMPLET

Internet, comment a marche ?

Chapitre 1

Hlas, les applets sont des programmes qui demandent beaucoup de ressources machine (processeur, mmoire) ! Elles ncessitent en outre la prsence dune machine virtuelle Java et sont gnralement lentes charger. Toute la politique de Sun fut donc de transfrer la technologie Java vers le niveau serveur avec les servlets. Avec certaines extensions, le serveur Apache (via son cousin Tomcat) est dsormais en mesure dinterprter du Java aussi facilement que du code PHP.

Animation Flash
Le Flash est un format dvelopp par la socit Macromedia qui permet de crer des animations sur le Web. Alors quil sagissait au dpart dun outil essentiellement graphique destin aux designers web, Macromedia a vite compris quil disposait dune vritable bombe et quil pouvait en faire un vritable environnement de dveloppement pour le Web. Lenvironnement Flash MX permet dsormais de raliser des interfaces graphiques compltes, dinteragir avec des services web, de manipuler les chiers XML et de dvelopper des applicatifs en utilisant le langage interne aussi puissant que complet quest ActionScript.
FLA et SWF

Deux formats de chiers sont lis au Flash : le FLA qui peut tre compar au chier source et le SWF qui correspond lexcutable. Si vous souhaitez apporter des modications, vous devez donc disposer du FLA pour louvrir dans Flash MX. Au contraire, pour excuter lanimation au sein dun navigateur, le SWF vous sera ncessaire.

Flash a lavantage davoir un rendu identique sur tous les navigateurs la condition, certes trs restrictive, que lordinateur dispose du plug-in Flash. Lorsque lon sait que Macromedia est un concurrent de Microsoft (diteur de lincontournable Windows) et que les distributions Linux rechignent installer des logiciels non libres, nous ne sommes pas prs de disposer du plug-in Flash prinstall sur nos machines. Le caractre propritaire de Flash lheure o les formats de chiers tendent tous souvrir risque galement de freiner ladoption de cette technologie parmi les socits ditrices de logiciels en ligne.

LE GUIDE COMPLET 45

Chapitre 1

Introduction

Figure 1.18 : Outil de cration de diagrammes intgralement ralise en Flash

1.4. Check-list
j j j j j j j

PHP nest quun langage de programmation parmi dautre. PHP fait partie des langages interprts. Linterprtation des scripts PHP est ralise le plus souvent au niveau du serveur web dont le meilleur reprsentant est Apache. PHP est particulirement adapt aux dveloppements web. PHP fonctionne sur une multitude de plateformes. PHP est libre et gratuit. Le Web est une des dimensions dInternet au mme titre que les courriels ou le P2P.

46 LE GUIDE COMPLET

Lenvironnement de travail
WampServer .......................................................................................................................... 48 Paramtrage de PHP ........................................................................................................... 60 Check-list ............................................................................................................................... 64

Chapitre 2

Lenvironnement de travail

Lobjectif est ici de mettre en place sur votre machine un environnement de travail permettant de tester les exemples prsents dans la suite de louvrage. lissue de ce chapitre, vous disposerez dun serveur web capable dinterprter des scripts PHP, dun systme de gestion de bases de donnes (MySQL) et dun outil permettant dinteragir avec ce dernier : phpMyAdmin.

2.1. WampServer
Bien quApache, MySQL, et PHP puissent tre installs sparment sous Windows, le choix se portera ici sur un outil capable dautomatiser lintgralit de ce processus.

Installation
Wamp Server peut tre tlcharg sur le site www.wampserver.com sous la rubrique Downloads.

1 Double-cliquez sur larchive que vous venez de tlcharger


De nombreuses modications ont t apportes la version 2 de Wamp Server. Les crateurs conseillent par consquent aux personnes disposant dj dune version de Wamp Server sur leur machine, de sauvegarder leurs dveloppements, de dsinstaller.lancienne version et enn dinstaller la toute nouvelle.
Compatibilit du code

Les dveloppements (PHP, MySQL) raliss sur une version antrieure de Wamp Server ont 99 chances sur 100 de fonctionner sur une version plus rcente de Wamp Server. Les projets PHP et MySQL apportent en effet une importance norme au fait de maintenir la compatibilit des dveloppements dune version lautre.

Figure 2.1 : Avertissement

48 LE GUIDE COMPLET

WampServer

Chapitre 2

2 La fentre dinstallation se lance et vous prsente votre version de Wamp.


Cette version est sans aucun rapport avec celle des outils quelle contient (que ce soit Apache, PHP ou MySQL).

Figure 2.2 : linstallation de Wamp Server 2

Lcran suivant permet daccepter la licence.

Figure 2.3 : Acceptez

3 Prcisez le rpertoire qui contiendra lensemble des composants ainsi que vos sources.

LE GUIDE COMPLET 49

Chapitre 2

Lenvironnement de travail

Ce rpertoire reprsentera approximativement 100 Mo de donnes. Nhsitez pas slectionner un autre disque si vous sentez que lespace libre de votre partition C: est trop juste. Un changement demplacement dans un deuxime temps serait beaucoup plus compliqu.

Figure 2.4 : Indiquez le rpertoire

Lcran suivant permet dobtenir des raccourcis sur le bureau pour lancer Wamp Server. Il nest pas ncessaire de cocher ces options dans la mesure o il restera possible de dmarrer Wamp Server en passant par le menu Dmarrer.

Figure 2.5 : Raccourcis

50 LE GUIDE COMPLET

WampServer

Chapitre 2

Ltape suivante rsume vos diffrents choix dinstallation.

4 Il est encore temps de les modier en revenant en arrire par le bouton < Back.

Figure 2.6 : Rsum de linstallation

La prochaine tape correspond linstallation physique des composants sur votre machine. Pas loin de 2000 chiers sont installs dans le rpertoire C:\wamp.

Figure 2.7 : En cours

LE GUIDE COMPLET 51

Chapitre 2

Lenvironnement de travail

5 Dnissez le navigateur qui sera utilis pour ouvrir ces pages.


Nous vous conseillons dutiliser le navigateur Firefox.

Figure 2.8 : Emplacement de Firefox

6 Indiquez votre adresse email ainsi que le nom de votre serveur denvoi de mails. Ce serveur, dit SMTP, est diffrent pour chaque fournisseur daccs Internet. Il peut par exemple prendre les valeurs suivantes : smtp.free.fr, smtp.wanadoo.fr, smtp.noos.fr, smtp.clubinternet.fr, etc.

Figure 2.9 : Serveur SMTP

Ltape nale vous conrme que linstallation sest bien droule et vous propose de dmarrer sans plus attendre le Wamp Server.

52 LE GUIDE COMPLET

WampServer

Chapitre 2

Figure 2.10 : Installation termine

Premiers pas
lissue de ces tapes, Apache, MySQL et PHP sont installs sur votre machine. Vous pouvez le vrier en ralisant une premire requte sur le domaine associ votre machine : http://localhost.

Figure 2.11 : tout fonctionne merveilleusement, Apache retourne la premire page web

LE GUIDE COMPLET 53

Chapitre 2

Lenvironnement de travail

La page affiche correspond au chier index.php situ dans C:\wamp\www. Vous pouvez de la mme manire faire appel votre propre page en plaant le chier test.html dans ce mme rpertoire et en y faisant appel de la manire suivante : http://localhost/test .html.
Listing 2-1 : c:\wamp\www\test.html <hr/>bonjour monde<hr/>

Figure 2.12 : Les pages sont galement accessibles

Le dmarrage de Wamp a enrichi votre System Tray dune petite icne voquant un compteur de vitesse.

54 LE GUIDE COMPLET

WampServer

Chapitre 2

Cette icne peut prendre diffrentes couleurs en fonction de ltat des serveurs.
j Marron j j

: aucun service nest dmarr. Jaune : un seul service est dmarr. Blanche : les deux services sont dmarrs.

Figure 2.13 : Wamp est dmarr, tout est OK

Le gestionnaire de tches de Windows conrme galement que les programmes Apache (httpd.exe) et MySQL (mysqld-net.exe) rsident bien en mmoire. La colonne Util. mmoire permet de quantier la mmoire utilise par ces services :
j 2 x Apache.exe j 1 x mysqld-nt.exe j

: 25 Mo. : 12 Mo. 1 x wampmanager.exe : 4 Mo.

Figure 2.14 : Gestionnaire de tches Windows

LE GUIDE COMPLET 55

Chapitre 2

Lenvironnement de travail

Si vous avez choisi de ne pas lancer Wamp Server automatiquement au dmarrage, vous pouvez tout moment le faire par le menu Dmarrer/Tous les programmes/WampServer/Start WampServer.

Figure 2.15 : Menu daccs

Le menu de Wamp
En cliquant avec le bouton gauche de la souris sur licne de Wamp, vous affichez un petit menu droulant.

Figure 2.16 : Actions accessibles depuis le menu Wamp

Ce menu permet :
j

douvrir directement des pages, notamment la page daccueil et lapplication phpMyAdmin ;

56 LE GUIDE COMPLET

WampServer

Chapitre 2

Figure 2.17 : phpMyAdmin j

douvrir le rpertoire www qui va contenir vos futurs scripts ;

Figure 2.18 : Le rpertoire racine de du serveur web j

de lire les chiers LOG dApache, de MySQL et de PHP ;

LE GUIDE COMPLET 57

Chapitre 2

Lenvironnement de travail

Figure 2.19 : Un exemple de chier LOG : mysql_error.log j

dditer leur chier de conguration ;

Figure 2.20 : Un exemple de chier de conguration : httpd.conf j

de grer les extensions PHP ;

58 LE GUIDE COMPLET

WampServer

Chapitre 2

Figure 2.21 : Chargement, suppression dextensions PHP j

darrter, de dmarrer et de redmarrer Apache et MySQL.

Figure 2.22 : Menu dApache

Lditeur Notepad++
Les diteurs de code PHP pullulent sur le Net. Un site web leur est mme consacr : www.php-editors.com/review.

LE GUIDE COMPLET 59

Chapitre 2

Lenvironnement de travail

Chacun dispose bien videmment de ses propres avantages et inconvnients. Notre choix se portera sur Notepad++ qui apparat particulirement adapt aux besoins du dveloppeur PHP.
j j j j

Il est gratuit. Il est rapide. Il colorise le code. Il rduit les blocs de code (fonctions, class, structures de contrle).

Figure 2.23 : dition dun script PHP avec Notepad++

Cet diteur peut tre tlcharg ladresse http://notepad-plus.sourceforge.net/fr/site.htm.

2.2. Paramtrage de PHP


Au moment de sa mise en uvre, PHP prend en compte un certain nombre de directives de conguration. Ces dernires, places dans le chier php.ini, permettent de paramtrer :
j j

le parseur PHP ; la scurit ;

60 LE GUIDE COMPLET

Paramtrage de PHP
j j j

Chapitre 2

les rapports derreur et les chiers LOG ; la compatibilit avec les versions prcdentes ; les extensions.

Sous Windows, ce chier peut tre ouvert via licne Wamp Server au sein du menu PHP.

Figure 2.24 : Laccs aux chiers de conguration

Le chier se situe physiquement dans le rpertoire


C:\wamp\bin\apache\apacheX.X.X\bin.
Tableau 2.1 : Paramtres de conguration de PHP dans php.ini

Paramtre

Valeur Boolen : On ou Off Boolen String

Signication Autorise louverture de chiers distants Autorise les balises ASP de type

allow_url_fopen asp_tags date.timezone

<% %>

Prcise la zone gographique de la machine (par exemple "Europe/Paris") Permet de prciser le type de chier retourn par dfaut par PHP (par exemple "text/html") Permet de prciser lencodage par dfaut des caractres (par exemple "iso88591") Autorise laffichage des erreurs Dnit le dossier racine

default_mimetype

String

default_charset

String

display_errors doc_root

Boolen String

LE GUIDE COMPLET 61

Chapitre 2

Lenvironnement de travail

Tableau 2.1 : Paramtres de conguration de PHP dans php.ini

Paramtre

Valeur Boolen String

Signication Permet dinterdire lusage de linterprteur PHP Permet dindiquer le rpertoire contenant les extensions (par exemple "c:/wamp/php/ext") Dnit le chier dans lequel les erreurs seront logges Dnit le niveau daffichage des erreurs Autorise ou non le transfert (upload) de chiers Dnit les rpertoires dans lesquels les fonctions require() et include() vont chercher les chiers (par exemple, sous Windows, .;c:\wamp\www\boutique ; sous Linux, .:/var/web/html/boutique) Indique si les erreurs des scripts doivent tre enregistres dans le chier LOG du serveur Autorise lchappement automatique des caractres , ", \ et NUL Dnit le temps maximal dexcution dun script (en secondes) Dnit la mmoire maximale que peut utiliser un script (par exemple 8M) Restreint louverture des chiers un rpertoire spcique Indique si les variables EGPCS doivent tre initialises en tant que variables globales

engine extension_dir

error_log error_reporting file_uploads include_path

String Entier Boolen String

log_errors

Boolen

magic_quotes_gpc

Boolen

max_execution _time memory_limit

Entier

Entier

open_basedir register_globals

String Boolen

62 LE GUIDE COMPLET

Paramtrage de PHP

Chapitre 2

Tableau 2.1 : Paramtres de conguration de PHP dans php.ini

Paramtre

Valeur Boolen

Signication Permet de passer en mode scuris et de vrier que le propritaire dun script est le mme que celui du chier accd Rpertoire contenant les binaires pouvant tre excuts en mode scuris Permet de vrier que le groupe du propritaire dun script est le mme que celui du chier accd Rpertoire de stockage des sessions Nom du cookie de session (par exemple PHPSESSID) Dure de vie du cookie de la session ; la valeur 0 (par dfaut) signie que la session sera dtruite avec la fermeture du navigateur Autorise les balises raccourcies

safe_mode

safe_mode_exec _dir safe_mode_gid

String

Boolen

session.save _path session.name session.cookie _lifetime

String String Entier

short_open_tag upload_tmp_dir

Boolen String

<? ?>

Prcise le rpertoire qui sera utilis pour stocker temporairement les chiers uploads Prcise la taille maximale des chiers uploads (par exemple 4M) Dnit lordre dans lequel PHP va initialiser ses variables globales ; la valeur "EGPCS" correspond lordre suivant : $_ENV, $_GET, $_POST, $_COOKIE, $_SESSION Permet PHP 5 de se comporter comme PHP 4 au cur du systme PHP Permet de compresser la vole lensemble des donnes affiches par PHP

upload_max _filesize variables_order

Entier String

zend.ze1 _compatibility _mode zlib.output _compression

Boolen

Boolen

LE GUIDE COMPLET 63

Chapitre 2

Lenvironnement de travail

Toute modication apporte au chier php.ini doit tre accompagne du redmarrage du serveur HTTP.
Le chier httpd.conf

Ces valeurs peuvent galement tre prcises au sein du chier de conguration dApache : httpd.conf. Il est mme possible, en utilisant la directive Virtualhost, dinitialiser spciquement les diffrents sites prsents sur la machine. Il pourrait ainsi tre possible dautoriser lupload de chiers pour un site, et de linterdire pour un autre.
<VirtualHost *:80> ServerName DocumentRoot php_admin_flag php_admin_flag </VirtualHost> www.site.com /var/web/site engine file_uploads on off

2.3. Check-list
j j j j

Wamp Server est un logiciel permettant dinstaller trs facilement sous Windows les logiciels Apache, MySQL et PHP. Loutil phpMyAdmin, lui-mme crit en PHP, permet de crer et de grer les bases de donnes. Le chier php.ini contient les directives de conguration de PHP. Une modication de ce chier impose le redmarrage du serveur Apache.

64 LE GUIDE COMPLET

Les fondamentaux

Structure dun programme ................................................................................................. 67 Les commentaires ................................................................................................................ 72 Les variables .......................................................................................................................... 74 Les constantes ...................................................................................................................... 78 Les types de donnes ......................................................................................................... 80 Les structures de contrle ................................................................................................. 86 Organisation du code .......................................................................................................... 99 Check-list ............................................................................................................................. 113

Chapitre 3

Les fondamentaux

Nous nous intresserons dans ce chapitre la syntaxe du PHP ainsi quaux diffrents lments qui composent ce langage : les variables, les types de donnes, les fonctions et enn les structures de contrle. Ces lments correspondent aux briques fondamentales qui permettront par la suite de raliser des applications de plus grande envergure. Une bonne comprhension de ce chapitre est donc indispensable pour pouvoir passer sereinement aux chapitres suivants. Avant dentrer dans le vif du sujet, il est important de xer un certain nombre de conventions. Vous avez lu prcdemment que PHP est un langage de programmation interprt. En ce sens, un script crit en PHP ncessite un autre composant pour tre excut : linterprteur PHP. Par dfaut, les systmes dexploitation les plus rpandus (Windows, Mac OS) ne disposent pas de tels interprteurs. Il existe donc deux possibilits pour faire fonctionner un programme crit en PHP :
j j

utiliser lenvironnement mis en place dans le chapitre prcdent ; le placer chez un hbergeur prenant en charge PHP.

Nous allons considrer dans les prochains chapitres que vous travaillez sur votre propre machine. Comme nous lavons vu dans le premier chapitre, toute machine dispose dun nom par dfaut : ici, localhost. Ce serveur aura donc pour adresse http://localhost. Ainsi, quand une mention sera faite dun script test1.php, cela impliquera que vous aurez cr un chier portant le nom test1.php, que vous laurez plac dans le rpertoire prvu cet effet et que vous aurez renseign ladresse dans votre navigateur http://localhost/test1.php pour lexcuter. Une adresse de type http://localhost/chap03/test2.php signierait quant elle que vous avez cr un rpertoire chap03 dans le rpertoire principal et que vous y avez plac le chier test2.php. Vous constaterez galement le choix du navigateur web Firefox pour illustrer les exemples. En lespace de quelques annes, ce navigateur a pris jusqu 30 % de parts de march Internet Explorer. Ses avantages sont nombreux et varis :
j j j j

respect des standard (passs, prsents et futurs) ; avances technologiques (XUL, CANVAS, SVG) ; outils utiles aux dveloppeurs web (affichage du code source, console Javascript) ; gratuit, scurit, et rapidit ;

66 LE GUIDE COMPLET

Structure dun programme


j j

Chapitre 3

mises jour frquentes et automatiques ; nombreuses extensions.


Firefox en franais

Firefox peut tre tlcharg en langue franaise sur le site www


.mozilla-europe.org/fr/

3.1. Structure dun programme


Un script crit en PHP correspond un chier texte contenant des lignes de code (instructions). Vous savez depuis le premier chapitre que ce chier texte doit avoir une extension de type .php pour pouvoir tre valu. Les lignes de codes contenues dans un script PHP doivent tre englobes entre les balises <?php et ?> : elles forment alors un bloc de code.
Les balises <% et %>

Il est possible de rencontrer les balises douverture et de fermeture <% et %>. Cette notation nest cependant pas trs rpandue et devrait tre abandonne avec PHP6.

crivons, en suivant ce principe, notre premier programme PHP : test.php, un classique du genre.
Listing 3-1 : Votre premier programme PHP <?php print("bonjour monde"); ?>

Il sagit du programme le plus simple que lon puisse imaginer. La premire ligne, <?php, indique linterprteur que les lignes qui vont suivre doivent tre traites comme du code PHP et quelles doivent donc tre interprtes. La deuxime ligne, print("bonjour monde");, est une instruction qui commande linterprteur dafficher lcran la phrase "bonjour monde". En PHP, chaque instruction doit tre ponctue dun pointvirgule (;). Au sein du bloc de code, les instructions sont excutes les unes aprs les autres.

LE GUIDE COMPLET 67

Chapitre 3

Les fondamentaux

Lexpression print() correspond ce que lon appelle en programmation une fonction . Le rle de cette fonction est dafficher la donne qui lui est adresse en paramtre. Par dfaut, PHP est livr avec un grand nombre de fonctions qui sont dcrites pour la plupart dans le chapitre Les fonctions PHP . Ce sont ces fonctions qui permettent, notamment, de travailler sur les nombres, les chanes de caractres (mots, phrases), les tableaux, daccder aux bases de donnes, de gnrer des images, etc. Enn, la dernire ligne (?>) de ce script indique linterprteur que les lignes qui suivent ne sont plus interprter. Elles peuvent donc tre affiches telles quelles.

Figure 3.1 : Le rsultat de votre premier programme

Si vous voulez maintenant afficher deux messages, placez deux instructions dans le bloc de code :
Listing 3-2 : Votre script contient deux instructions <?php print("instruction 1"); print("instruction 2"); ?>

Figure 3.2 :

Rsultat

68 LE GUIDE COMPLET

Structure dun programme

Chapitre 3

Le rsultat peut vous surprendre, les deux phrases se trouvant en effet sur la mme ligne. En y rchissant bien, cest cependant tout fait normal. La premire instruction affiche la phrase "instruction 1" et la deuxime affiche "instruction 2". Votre navigateur va donc recevoir un chier contenant "instruction 1instruction 2" et lafficher tel quel. Si vous souhaitez avoir deux lignes diffrentes, rien de plus simple : ajoutez la balise HTML <br/> qui permet de raliser un saut de ligne :
Listing 3-3 : Deux instructions <?php print("instruction 1<br/>"); print("instruction 2"); ?>

La page que le navigateur reoit contient alors la ligne "instruction 1<br/>instruction 2", ce qui vous permet de sparer les deux lignes.

Figure 3.3 : Le rsultat correspond aux attentes

Lexpression phpinfo() est une autre fonction interne du PHP. Elle a pour rle de donner des informations sur le PHP utilis pour faire fonctionner votre script :
j j j j

version du PHP ; version des diffrents modules installs ; type de serveur web ; donnes systme disponibles

Listing 3-4 : Informations sur la version de PHP <?php phpinfo(); ?>

LE GUIDE COMPLET 69

Chapitre 3

Les fondamentaux

Figure 3.4 : Informations retournes par la fonction phpinfo()

Comme vous le voyez, les fonctions ont des rles trs varis. Une simple fonction peut raliser des tches plus ou moins complexes.
Le chier test.php

Plutt que de crer pour chacun des petits exemples un nouveau chier (test1.php, test2.php, etc.), le chier test.php sera rutilis chaque fois.

Au sein dun mme script, les blocs de code peuvent tre multiples et du code HTML peut sy intercaler. Toute zone non comprise entre les balises <?php et ?> est considre comme du HTML (ou tout du moins comme du texte brut). Elle est par consquent directement retourne :

70 LE GUIDE COMPLET

Structure dun programme


Listing 3-5 : PHP + HTML <?php print("premier bloc PHP"); ?> <hr> partie <b>HTML</b> <hr> <?php print("deuxime bloc <i>PHP</i>"); ?>

Chapitre 3

Figure 3.5 : Du PHP et du HTML au sein du mme script

Au sein de ce script, les deux blocs suivants correspondent du code PHP :


<?php print("premier bloc PHP"); ?> <?php print("deuxime bloc <i>PHP</i>"); ?>

Ces blocs seront remplacs par le rsultat de leur interprtation. La partie suivante correspond quant elle du simple code HTML qui est retourn tel quel par le serveur.
<hr> partie <b>HTML</b> <hr>

Vous pouvez remarquer que dans le deuxime bloc de code sont affiches des donnes qui contiennent des balises HTML permettant la mise en italique dun texte (<i>PHP</i>). Cest non seulement tout fait autoris, mais de plus trs courant en PHP.
LE GUIDE COMPLET 71

Chapitre 3

Les fondamentaux

HTML et PHP

Il serait tout fait envisageable quun chier .php ne contienne que du HTML. La page serait retourne sans aucune modication. Lintrt est cependant bien mince car vous ajoutez, dans ce cas, une tape entre le serveur web et vous. En effet, bien que la page ne contienne aucun bloc dinstructions, linterprteur sera quand mme mis contribution.

En affichant les sources de la page, vous obtenez la preuve que le navigateur a bien reu le rsultat de linterprtation du code par PHP et que la partie HTML na pas t modie.

Figure 3.6 : Sources

Figure 3.7 : Les instructions PHP ont bien t interprtes

3.2. Les commentaires


Un bloc de code peut contenir des commentaires. Ces derniers peuvent tre ajouts au code de diffrentes manires :

72 LE GUIDE COMPLET

Les commentaires
Listing 3-6 : Diffrentes syntaxes permettant dinsrer des commentaires <?php /* commentaires hrits du C */ // commentaires hrits // du C++ # commentaires hrits # du SHELL

Chapitre 3

print("code comment"); // commentaire de fin de ligne ?>

Ajouter des commentaires ne ralentit en rien lexcution de votre code. Au moment de linterprtation, PHP va tout simplement supprimer ces zones commentes.

Figure 3.8 : Les parties commentes napparaissent pas

Poussons le vice un peu plus loin en gnrant un commentaire HTML laide dun script PHP. Les commentaires HTML doivent tre placs entre <! et > :
Listing 3-7 : Commentaire HTML <?php print("voici un commentaire HTML : "); print("<!-- message comment -->"); ?>

LE GUIDE COMPLET 73

Chapitre 3

Les fondamentaux

Figure 3.9 : Code avec commentaires

Bien quinvisible dans le navigateur, le commentaire HTML est cependant bien prsent dans les sources de la page.

Figure 3.10 : Sources

3.3. Les variables


Quel que soit le langage de programmation, llment principal dun programme est la variable. Une variable est un lment qui peut prendre diffrentes valeurs au cours de lexcution dun programme. En PHP, les noms des variables sont prcds du caractre $ : $abc correspond la variable abc.
$abc est ici le nom de la variable, ne pas confondre avec ce que contient la variable ($abc peut par exemple contenir la valeur 3).

Prcisment, pour donner la valeur 3 la variable $abc, crivez laffectation suivante :


74 LE GUIDE COMPLET

Les variables
Listing 3-8 : Affectation de la valeur 3 la variable $abc $abc = 3;

Chapitre 3

Notation des exemples

Pour de tout petits exemples, comme celui-ci, ne correspondant en fait qu une sous-partie de script, les balises <?php et ?> ne sont pas notes. Si vous voulez tester ce morceau de code, il convient bien videmment de les ajouter.

Le contenu dune variable peut tre obtenu en y faisant simplement rfrence :


Listing 3-9 : Affectation de diffrentes valeurs valeur de la variable abc = <?php print($abc); ?> <br/>valeur de la variable abc = <?php $abc = 3; print($abc) ?> <br/>valeur de la variable abc = <?php $abc = 12; print($abc) ?>

Figure 3.11 : Diffrentes affectations de variables

LE GUIDE COMPLET 75

Chapitre 3

Les fondamentaux

Vous constatez quavant quune valeur ne soit affecte la variable, celle-ci nexiste pas. Elle peut ensuite prendre diffrentes valeurs lors de lexcution du script. Il faut aussi noter que la valeur dune variable est conserve dun bloc de code lautre. La valeur dune variable peut tre affecte tout naturellement une autre variable avec loprateur daffectation = :
Listing 3-10 : La variable $abc contient la valeur de $d (2) lissue de laffectation <?php $abc = 1; $d = 2; $abc = $d; ?>

Il existe diffrents moyens permettant daffecter une valeur une variable :


j j j

soit directement : $abc = 2;; soit en lui faisant recevoir le rsultat dune opration : $abc = 1 + 3;; soit en lui faisant recevoir le rsultat dune fonction : $abc = pow(2,4); (cest--dire la puissance 4 de 2).

Listing 3-11 : Diffrents types daffectations 1- abc = <?php $abc = 2; print($abc); ?> <br/>2- abc = <?php $abc = 3 * 2; print($abc) ?> <br/>3- abc = <?php $abc = $abc + 1; print($abc) ?> <br/>4- abc = <?php
76 LE GUIDE COMPLET

Les variables
$abc = pow(2,4); print($abc) ?> <br/>5- abc = <?php $abc = pow(2,4) - 7; print($abc) ?>

Chapitre 3

Figure 3.12 : Diffrents types daffectations

Linstruction $abc = $abc + 1 indique que la variable $abc est gale la valeur de la variable $abc plus 1. Il est possible dcrire plus succinctement cette affectation : $abc++. Loprateur ++ derrire une variable incrmente cette variable et inversement, loprateur dcrmente la valeur.
abc = <?php $abc = 4; $abc--; print($abc); ?>

Certains noms de variables sont interdits, reportez-vous aux Annexes pour obtenir plus de prcisions sur ce sujet. Il existe une notation alternative et plus complexe qui permet davoir accs aux variables : ${nom_de_la_variable}.
$x = 0; ${x} = 10; // assigne la valeur 10 la variable x print(${x}); // affiche : 10

LE GUIDE COMPLET 77

Chapitre 3

Les fondamentaux

print($x); // affiche : 10 $x = 5; // assigne 5 la variable x print(${"x"}); // affiche : 5 $y = "x"; print(${$y}); // affiche 5 car $x vaut 5

Ces deux notations sont donc compltement quivalentes ; la deuxime peut cependant se rvler trs utile lorsque vous devez crer ou rcuprer des variables lorthographe non standard ou des variables dont le nom est lui-mme variable . Linstruction suivante est tout fait valable, malgr la prsence dun espace dans le nom de la variable :
${"ma variable"} = "bonjour monde";

Majuscules et minuscules

Le nom des variables est sensible la casse (case sensitive). Cela signie que PHP fait une diffrence entre majuscules et minuscules. Une variable $a sera donc diffrente de la variable $A et pourra donc cohabiter avec la premire en disposant de sa propre valeur.

3.4. Les constantes


Les constantes peuvent tre assimiles des variables dont le contenu ne peut tre pas modi durant lexcution du programme. La dclaration dune constante fait appel la fonction define() dont le premier argument correspond au nom de la constante, et le second, sa valeur.
Listing 3-12 : Cration de la constante VERSION_SITE define("VERSION_SITE","v3.1");

la diffrence des variables, les constantes nont pas tre prcdes du caractre $.
Listing 3-13 : Utilisation de constantes au sein dun site <?php define("NOM_SITE","Cool Site"); print(NOM_SITE); define("VERSION_SITE",3.1); $a = VERSION_SITE + 1; ?>

78 LE GUIDE COMPLET

Les constantes

Chapitre 3

PHP dispose dun certain nombre de constantes dnies par dfaut. La constante PHP_VERSION contient par exemple la version de linterprteur PHP.
Listing 3-14 : Utilisation dune constante par dfaut <?php print("Version de PHP : "); print(PHP_VERSION); ?>

Figure 3.13 : Version de PHP

Lexcution du script suivant vous permet dobtenir la liste de toutes les constantes dnies par dfaut par PHP.
Listing 3-15 : Plus de 700 constantes dfinies par PHP <pre> <?php print_r(get_defined_constants()); ?> </pre>

Figure 3.14 : Plus de 700 constantes

LE GUIDE COMPLET 79

Chapitre 3

Les fondamentaux

Norme dcriture

Les constantes sont gnralement crites en majuscule an de les diffrencier des variables. Ce standard est partag par une grande majorit des langages de programmation.

3.5. Les types de donnes


En informatique, les donnes sont souvent types, en ce sens quelles contiennent une certaine catgorie dinformation. Il existe globalement deux principaux types de donnes : les variables contenant des chiffres et les variables contenant des lettres. Les tableaux, qui correspondent galement un type de donne, sont prsents dans un chapitre suivant. PHP rend les choses extrmement simples au niveau des types car il nimpose pas dassocier explicitement un type une variable (dans la plupart des autres langages, les variables doivent tre associes un type ds leur initialisation au dbut du programme). Si vous affectez 3 $abc, celle-ci devient de facto de type numrique. Si en revanche vous lui affectez la phrase "bonjour monde", elle devient ce que lon appelle une chane de caractres (souvent appele string). Arrtons-nous quelque temps sur ces deux principaux types de donnes.

Les donnes numriques


Vous trouvez, parmi les donnes numriques, les nombres entiers (2, 4, 233, 12) et les nombres ottants (0.5, 23.8, 123.4).
criture des nombres ottants

Notez que le caractre sparant la partie entire de la partie dcimale est le point. En utilisant une virgule, vous gnrez une erreur. Il sagit de la norme anglo-saxonne qui est utilise par tous les langages de programmation.

80 LE GUIDE COMPLET

Les types de donnes

Chapitre 3

Il existe un certain nombre doprateurs mathmatiques qui peuvent tre utiliss avec les numriques :
Tableau 3.1 : Les diffrents oprateurs mathmatiques

Oprateur

Rle Laddition La soustraction La multiplication La division Le modulo

+ * / %

Voyez lutilisation de tous ces oprateurs dans un mme exemple :


Listing 3-16 : Diffrents oprateurs mathmatiques <?php $a = 10 ; $b = 5 ; $c = 2; $x $x $x $x $x // // ?> = $a + $b; // la variable $x contient 15 = $x - $c ; // $x vaut 13 = $x * $x ; // $x vaut 169 = ($a / $b) + $c; // $x vaut 4 = 11 % $a ; $x vaut 1, le modulo correspond au reste de la division 11 / 10

Lordre de priorit des oprateurs doit tre respect : les oprations * /


% sont traites avant les oprations + .

Lexpression 10 2 * 4 vaut ainsi 2 et non 32. La multiplication est en effet ralise avant la soustraction. Quand PHP doit interprter la ligne $abc = 16 12 / 6 * 5 + 1;, il value lexpression de la manire suivante :
16 - 2 * 5 + 1 16 - 10 + 1 6 + 1 7

LE GUIDE COMPLET 81

Chapitre 3

Les fondamentaux

Il peut donc tre prfrable dutiliser des parenthses pour limiter les risques :
$abc = 16 - ( ( 12 / 6 ) * 5 ) + 1 ;

An de gagner du temps, des formes compactes existent pour certaines oprations. Ainsi, $abc = $abc + 2 ; est quivalent $abc += 2 ; De la mme manire, les raccourcis suivants sont tout fait valides : =, *=, /= et %=. Il existe un type de numrique part : les boolens. Seules deux valeurs boolennes existent : true (vrai), false (faux).
<?php $var = true ; // $var contient la valeur boolenne true ?>

Il est courant que la valeur 0 soit quivalente false et que la valeur 1 soit quivalente true. Cet abus peut cependant se rvler dangereux lors de certains tests. Nous y ferons dailleurs mention plus loin.

Les chanes de caractres


Une chane de caractres (souvent appele string) doit tre dlimite par des guillemets (") ou des primes ().

Les guillemets et les primes


Lorsque les caractres de dlimitation sont des guillemets ("), la chane de caractres peut contenir des caractres ainsi que des variables. La variable est alors remplace par son contenu.
Listing 3-17 : Une variable dans une chane de caractres <?php $n = 2; $s = "valeur de la variable n = $n"; print($s); // affiche : "valeur de la variable n = 2" ?>

Quand les primes () sont utilises comme caractres de dlimitation, les variables ne sont plus remplaces par leur contenu :
<?php $n = 2; $s = valeur de la variable n = $n;

82 LE GUIDE COMPLET

Les types de donnes

Chapitre 3

print($s); // affiche : valeur de la variable n = $n ?>

Bien utiliser les signes

En utilisant la prime (), PHP sait quil na pas remplacer la prsence dune ventuelle variable par son contenu. Il affiche directement et sans traitement la chane de caractres. Il est donc prfrable, pour optimiser votre code, dutiliser les guillemets quand une chane est vierge de toute variable. Par exemple, bonjour monde est prfrable "bonjour monde".

Laffichage dune chane de caractres peut galement tre ralis avec la fonction echo(). Les syntaxes suivantes pourront tre trouves indiffremment dans la littrature :
j j j j

echo "bonjour"; echo("bonjour"); print("bonjour"); print "bonjour";

Syntaxe spciale de echo echo permet lutilisation dune syntaxe spciale : echo $var1, $var2; pour afficher la $var1 puis $var2. Aucune limitation nexiste

au niveau du nombre de variables afficher.

chappement de caractres
Une question peut alors se poser : comment une chane de caractres peut contenir le guillemet (") quand ses dlimiteurs sont prcisment des guillemets ? Il est dans ce cas ncessaire dutiliser un caractre dit dchappement :
\. Ce caractre est nomm barre oblique inverse ou antislash (galement backslash). Pour obtenir la phrase bonjour " monde, il est ncessaire dcrire "bonjour \" monde". Le principe est le mme pour la prime () avec des strings dlimites par des primes :

LE GUIDE COMPLET 83

Chapitre 3

Les fondamentaux

Listing 3-18 : chappement de caractres print("bonjour \" monde"); // affiche : bonjour " monde print(bonjour \ monde); // affiche : bonjour monde print(bonjour \" monde); // affiche : bonjour \" monde

Les caractres (\) et ($) ont aussi besoin dtre prcds dune barre oblique inverse pour tre affichs dans une chane entre guillemets :
$i = 2 ; print("\\ \$i vaut $i"); // affiche : "\ $i vaut 2"

Loprateur de concatnation
Il existe un oprateur pour les chanes de caractres : loprateur de concatnation. Il permet de runir deux chanes : $str = $str1 . $str2 ; et signie que la variable $str contient la variable $str1 suivie de $str2.
Listing 3-19 : Loprateur de concatnation <?php $var1 = "ui"; $var2 = "le temps est " . "beau aujourdh" . $var1; print($var2); // affiche : "le temps est beau aujourdhui" print("cou" . cou); // affiche : "coucou" ?>

La version raccourcie existe aussi : .=.


$abc = $abc . " coucou" ; est lquivalent de $abc .= " coucou";.

Loprateur de concatnation est galement trs utile pour amliorer la lisibilit dune chane de caractres trs longue.
Listing 3-20 : $var1 et $var2 sont rigoureusement identiques <?php $var1 = "Les 7 pchs capitaux sont : la paresse, lorgueil, la gourmandise, la luxure, lavarice, la colre, lenvie."; $var2 = "Les 7 pchs capitaux sont : ". "la paresse, lorgueil, la gourmandise, la luxure, ". "lavarice, la colre, lenvie."; ?>

En informatique, les chanes de caractres sont souvent appeles string. Vous trouverez donc souvent dans les exemples suivants la variable $str pour dnir une variable de type chane de caractres.
84 LE GUIDE COMPLET

Les types de donnes

Chapitre 3

Appellation des variables

Il est important, en programmation, de donner des noms pertinents aux variables. Quand vous voulez quune variable contienne le nom dune ville, il est prfrable de nommer la variable $ville plutt que $x. Nhsitez donc pas donner des noms longs : $portefeuille_client est prfrable $prtfcl, mme sil peut paratre rbarbatif dcrire une variable aussi longue. Comme nous lavons prcdemment dit, votre code devra peut-tre tre repris aprs plusieurs mois, et pas obligatoirement par vous !

Le type NULL
Ce type, compos dun seul lment (NULL), permet dindiquer quune variable na pas de valeur.
Listing 3-21 : Une fois utilise, la variable $str est passe NULL <?php $str = "coucou"; print($str); $str = NULL; ?>

Changement de type
PHP a ceci de sympathique quil permet aux variables de changer de type si vous leur affectez des donnes de types diffrents au cours du programme :
Listing 3-22 : Changement de type <?php $abc = "1"; // $abc est une string contenant la chane "1" $abc += 2; // $abc est maintenant un numrique contenant la valeur 3 ?>

Dans cet exemple, la variable est dabord une chane de caractres contenant la chane "1". Aprs lopration dincrmentation, elle devient de type numrique et contient la valeur 3. PHP propose galement une opration de transtypage pour convertir les types de donnes. Cette opration, qui porte galement le nom de cast , utilise la syntaxe suivante :

LE GUIDE COMPLET 85

Chapitre 3
$s $n $b $n $b $b $f = = = = = = =

Les fondamentaux

(string) 1; // $s contient maintenant la chane "1" (int) $s; // $n contient 1 (bool) $n; // $b contient TRUE (int) 1.8; // $n contient 1 (bool) -3; // $b contient TRUE (bool) 0; // $b contient FALSE (float) " 1.45 "; // $f contient 1.45

Autres types

Le transtypage fonctionne galement avec les autres types de donnes tudis dans la suite de louvrage : les tableaux (array) et les objets (object).

Au nal, PHP permet de ne pas avoir se tracasser avec les problmes de typage.

3.6. Les structures de contrle


Tous ces exemples sexcutaient jusqu maintenant linairement, ligne aprs ligne. Cependant, comme dans la vie courante, il est rare que les choses se passent aussi simplement : nous ralisons certaines choses uniquement dans certains cas et, dans dautres circonstances, nous rptons les mmes choses plusieurs fois. Lquivalent informatique de ces vnements est la structure de contrle. Vous disposez, avec PHP, de toutes les structures de contrle standard. Celles-ci sont gnralement regroupes en deux catgories Les conditions :
SI test est vrai ALORS FAIRE action1 SINON FAIRE action2 FAIRE DANS LE CAS 1 action1, DANS LE CAS 2 action 2 etc.

Les boucles :
FAIRE action TANT QUE test est vrai TANT QUE test est vrai ALORS FAIRE action POUR TOUS LES CAS SUIVANTS FAIRE action

86 LE GUIDE COMPLET

Les structures de contrle

Chapitre 3

Les conditions
Nous prsenterons dans cette partie les expressions if else, if
elseif else et switch case.

IF ELSE
Lquivalent de SI test est vrai ALORS FAIRE action1 SINON FAIRE action2 est linstruction if else (if signie si et else signie ou bien ). crivez un petit programme qui affiche "i est plus grand que 5" si la variable $i est plus grande que 5 et la phrase "i est plus petit que 5" dans le cas contraire.
Listing 3-23 : Le premier test <?php $i = 4; if ($i > 5) print("i est plus grand que 5"); else print("i est plus petit que 5"); ?>

Dans ce cas, "i est plus petit que 5" apparat lcran car vous avez initialis la variable $i 4. Les tests sont raliss avec des oprateurs de comparaison.
Tableau 3.2 : Les oprateurs de comparaison

Oprateur

Rsultat Vrai si $a est gal $b Vrai si $a est gal $b et si ces deux variables sont de mme type Vrai si $a est diffrent de $b Vrai si $a est diffrent de $b (en type ou en valeur) Vrai si $a est suprieur $b

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

LE GUIDE COMPLET 87

Chapitre 3

Les fondamentaux
Tableau 3.2 : Les oprateurs de comparaison

Oprateur

Rsultat Vrai si $a est infrieur $b Vrai si $a est suprieur ou gal $b Vrai si $a est infrieur ou gal $b

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

Il est important de comprendre que ces oprateurs renvoient une valeur boolenne, false ou true, suivant le rsultat de la comparaison. Le test est en fait ralis sur cette valeur de retour. crire if ($a > $b) est en fait la mme chose qucrire if (($a > $b) == true).
if ($i)

Lexpression if ($i) est identique if ($i != NULL). Cette version condense est trs souvent utilise en informatique.

Dans cet exemple, une seule action est ralise, dans un cas (if) comme dans lautre (else). Si plusieurs actions doivent tre ralises, celles-ci sont groupes entre des balises { } pour former un groupe dinstructions. Modiez votre script an quil affiche deux lignes :
<?php $i = 4; if ($i > 5) { print("nous sommes dans le IF ... "); print("i est plus grand que 5"); } else { print("nous sommes dans le ELSE ... "); print("i est plus petit que 5"); } ?>

88 LE GUIDE COMPLET

Les structures de contrle

Chapitre 3

Les balises { }

Alors quelles sont facultatives quand il ny a quune instruction, elles deviennent obligatoires ds quil y en a au moins deux.

Les tests peuvent se faire aussi bien sur des numriques :


if ($prix == 3.5)

que sur des chanes de caractres :


if ($prenom == "paul")

Attention, cependant, ne pas se mprendre sur les oprateurs de supriorit et dinfriorit avec des chanes de caractres ! Ainsi, le test if ($code > "9AEXB3") nest pas un test sur les longueurs respectives des deux chanes. Il sagit plutt de comparer une une les valeurs ASCII des caractres composant les deux chanes. Chaque caractre possde en informatique un code ASCII. Celui du caractre a est par exemple 97 et celui de 9 est 57 (la fonction ord() peut tre utilise pour trouver la valeur ASCII dun caractre : ord("A") retourne 98). De ce fait, "abc" est suprieur "9AEXB3" (car ord(a) est suprieur ord(9)) et "def" est suprieur "dc" (car ord(e) est suprieur ord(c)). Pour linstant, les tests tudis sont simples car vous ne testez quune seule valeur. Si vous devez crire le test suivant :
SI la personne a plus de 18 ans ALORS crire "homme majeur" SI elle est de sexe masculin

vous crirez, dans ltat de vos connaissances actuelles :


<?php $age = 22; $sexe = "masculin"; if ($age > 18) { if ($sexe == "masculin") print("homme majeur"); } ?>

LE GUIDE COMPLET 89

Chapitre 3

Les fondamentaux

La faon logique dexprimer ce test est :


SI la personne a plus de 18 ans ET quelle est de sexe masculin ALORS crire "homme majeur"

Il sagit l dune double condition. Loprateur (&&) peut tre utilis pour signier loprateur ET :
<?php $age = 22; $sexe = "masculin"; if (($age > 18) && ($sexe == "masculin")) print("homme majeur"); // affiche bien "homme majeur" // car : (22 > 18) ET (masculin == masculin) ?>

Loprateur (&&) est appel un oprateur logique . Il en existe dautres qui vont vous permettre de raliser des tests plus ardus.
Tableau 3.3 : Oprateurs logiques

Oprateur

Rsultat Vrai si $a ET $b sont vraies Vrai si $a ET $b sont vraies (identique and) Vrai si $a OU $b sont vraies Vrai si $a OU $b sont vraies (identique or) Vrai si $a OU $b sont vraies, mais pas les deux Vrai si $a est fausse

$a and $b $a && $b $a or $b $a || $b $a xor $b ! $a

partir de ces oprateurs logiques, il est possible dcrire le test suivant :


SI la variable $a OU la variable $b est suprieure 4, ET que la variable $c nest pas infrieure ou gale 2 ALORS crire OK

qui devient :
if ((($a > 4) or ($b > 4)) and !($c <= 2)) print("OK");

90 LE GUIDE COMPLET

Les structures de contrle

Chapitre 3

Il est souvent possible de simplier une expression : !($c <= 2) quivaut ($c > 2). En effet, dire que $c nest pas infrieur ou gal 2 est une faon complexe de dire que $c est suprieur 2. Il est nanmoins prfrable gnralement, au dbut, de transcrire terme terme une condition plutt que dessayer de la simplier outrance. Un bon rexe consiste aussi insister sur les parenthses an de regrouper ensemble les conditions interdpendantes. Les priorits, comme pour les oprateurs mathmatiques, peuvent faire des ravages. Le test suivant :
($b > 3) || ($c > 3) && ($c < 10)

ne signie pas :
$b OU $c suprieures 3 ET $c infrieure 10

mais :
$b suprieure 3 OU $c comprise entre 3 ET 10

Dans cette mesure, il est prfrable dcrire en utilisant une paire de parenthses supplmentaires pour ne rien risquer :
($b > 3) || (($c > 3) && ($c < 10))

Les annexes contiennent un tableau prsentant lordre de priorit des diffrents oprateurs.

IF ELSEIF
Essayez maintenant dcrire un autre test :
si la couleur "primaire" est rouge, jaune ou bleue, crire

si la couleur est noire, crire "noire" si la couleur est blanche, crire "blanche" sinon crire "mlange"

Votre premire proposition pourrait tre celle-ci :


if (($couleur=="rouge") || ($couleur=="jaune") || ($couleur=="bleue")) print("primaire");

LE GUIDE COMPLET 91

Chapitre 3

Les fondamentaux

if ($couleur == "noire") print("noire"); if ($couleur == "blanche") print("blanche"); else print("mlange"); }

Celle-ci serait videmment compltement errone car, si vous supposez que la couleur est rouge, deux messages seraient alors affichs : "primaire" et "mlange". Vous tes donc oblig demboter les if else :
if (($couleur=="rouge") || ($couleur=="jaune") || ($couleur=="bleue")) print("primaire"); else { if ($couleur == "noire") print("noire"); else if ($couleur == "blanche") print("blanche"); else print("mlange"); }

Il sagit en fait dun SI SINON SI SINON SI SINON. PHP propose, pour ce genre de cas, la mthode suivante : if elseif elseif else.
<?php if (($couleur=="rouge") || ($couleur=="jaune") || ($couleur=="bleue")) print("primaire"); elseif ($couleur == "noire") print("noire"); elseif ($couleur == "blanche") print("blanche"); else print("mlange"); ?>

SWITCH
Supposez dsormais que vous deviez crire le test suivant :
si la couleur est rouge, crire "R"

92 LE GUIDE COMPLET

Les structures de contrle si la couleur est bleue, crire "B" si la couleur est jaune, crire "J" sinon crire "?"

Chapitre 3

Dans ce cas, il est dommage dutiliser un if elseif. Imaginez, en effet, que la couleur soit jaune : il faudrait alors tester si la couleur est rouge, puis tester si la couleur est bleue et enn tester si la couleur est jaune. Dans ce type de cas, o laction raliser ne dpend que de la valeur dune variable, il est prfrable dutiliser le switch :
switch ($couleur) { case "rouge": print("R"); break; case "bleue": print("B"); break; case "jaune": print("J"); break; default: print("?"); break; }

Il peut y avoir autant de case que ncessaire, mais il ne peut y avoir quun seul default (il nest cependant pas obligatoire). Un case peut contenir plusieurs instructions ; il faut alors les placer entre un case et un break :
switch ($couleur) { case "rouge": print("couleur : "); print("R"); break; case "bleue": etc.

Les boucles
Un des principaux avantages de linformatique, en gnral, est de permettre dautomatiser des tches fastidieuses. Imaginez que vous vouliez crire tous les entiers infrieurs 5.
LE GUIDE COMPLET 93

Chapitre 3

Les fondamentaux

Il serait dommage de devoir crire :


print("0<br/>"); print("1<br/>"); print("2<br/>"); print("3<br/>"); print("4<br/>");

Linformatique a cr, pour ce genre de besoin, la notion de boucle.

WHILE
WHILE est la boucle qui permet dcrire ceci : TANT QUE test vrai FAIRE action

partir de l, il devient vident pour cet exemple que le test va tre ralis sur une variable ($i < 5) et que laction va consister lafficher et lincrmenter :
$i = 0; while ($i < 5) { print("$i<br/>"); $i++; } print("<br/>fin de la boucle");

Que se passe t-il au niveau de linterprteur PHP : la variable $i prend la valeur 0 nous entrons dans la boucle est-ce que $i < 5 ? oui : le bloc dexpressions du while est alors excut affichage de $i (0) et augmentation de 1 de la valeur de $i nous remontons alors au niveau du test du while $i est-elle infrieure 5 ? oui (elle vaut 1), alors on excute le bloc affichage de $i (1) et incrmentation de $i nous continuons ainsi jusquau moment o nous passons la valeur de $i 5 nous remontons alors au niveau du test, $i nest plus strictement infrieure 5

94 LE GUIDE COMPLET

Les structures de contrle

Chapitre 3

nous sortons alors de la boucle et passons linstruction suivant le bloc du while, cest--dire laffichage de "fin de la boucle"
Le danger du while

Faites attention, quand vous travaillez avec une boucle while, ne pas vous retrouver dans une boucle innie. Cela aurait t le cas, si vous aviez oubli la ligne $i++. En effet, la variable aurait gard la valeur 0 et la boucle while aurait affich "0" indniment.

Comme pour les conditions, le test peut tre complexe :


$i = 1; while (($n != 121) && ($i < 100)) { $n = $i * $i; print("i = $i , n= $n<br/>"); $i++; }

Figure 3.15 :

Boucle while

Dans cet exemple, la condition darrt de la boucle est double : la variable $n doit tre diffrente de 121 et la variable $i doit tre infrieure 100.

DO WHILE
Une variante existe au while : le do while. Il ne sagit plus dun tant que faire, mais dun faire tant que. Dans ce cas, le code de la boucle est donc au moins excut une fois :

LE GUIDE COMPLET 95

Chapitre 3

Les fondamentaux

$i = 6; do { print($i); } while ($i < 5);

Bien que $i contienne la valeur 6 et que le test soit $i < 5, le code est bien excut une fois.

FOR
La syntaxe de la boucle for est la suivante :
for (expression 1; expression 2; expression 3)
j j j

expression 1 est linstruction initiale excute avant la

premire itration ; expression 2 est le test ralis au dbut pour chaque itration ; expression 3 est linstruction excute la n de chaque itration.

Ainsi, lquivalent de cette boucle while :


$i = 0; while ($i <= 10) { print("$i <br/>"); $i++; }

est la boucle for suivante :


for ($i = 0; $i <= 10; $i++) { print("$i <br/>"); }

Vous souhaitez maintenant crire les nombres pairs infrieurs 50 :


for ($i = 0; $i <= 50; $i = $i + 2) { print("$i <br/>"); }

La boucle for permet donc de condenser les principaux lments dune boucle sur une seule et mme ligne.

96 LE GUIDE COMPLET

Les structures de contrle

Chapitre 3

Toutes les parties de la boucle for peuvent tre vides. Ainsi, les deux boucles suivantes sont quivalentes :
Listing 3-24 : Version 1 for ($i = 0; $i <= 10; $i++) { print("$i <br/>"); } Listing 3-25 : Version 2 $i = 0; for (;$i <= 10;) { print("$i <br/>"); $i++; }

Lintrt de cette notation alambique est cependant assez mince.

BREAK et CONTINUE
Il est parfois ncessaire de terminer une boucle en plein milieu de son excution ; linstruction break est alors utilise. La boucle suivante permet darrter lexcution du for ds que la variable dincrmentation passe la valeur 7.
Listing 3-26 : Le break nous permet de sortir de la boucle for ($i=0;$i<=10;$i++) { if ($i==7) { print("<i>i contient 7, nous sortons de la boucle.</i>"); print("<br/><br/>"); break; } print("$i<br/>"); } print("<b>fin de la boucle.</b>"); (voir Figure 3.16)

Le cousin du break est le continue. Il permet de forcer le passage litration suivante nimporte quel niveau dune boucle. Linstruction continue permet dans lexemple suivant de sauter laffichage de la valeur 7 :

LE GUIDE COMPLET 97

Chapitre 3

Les fondamentaux

Figure 3.16 : Sortie en plein milieu de boucle

Listing 3-27 : Nous sautons le traitement de la valeur 7 for ($i=0;$i<=10;$i++) { if ($i==7) { print("<i>i contient 7, passage litration suivante.</i>"); print("<br/>"); continue; } print("$i<br/>"); } print("<br/><b>fin de la boucle.</b>");

Figure 3.17 : Instruction continue

98 LE GUIDE COMPLET

Organisation du code

Chapitre 3

Ces deux instructions peuvent aussi bien tre utilises dans le cadre dun for, dun while ou dun switch.

3.7. Organisation du code


PHP propose diffrentes mthodes pour organiser vos dveloppements : la dnition de fonctions utilisateur et linclusion de chiers. Ces mthodes visent avant tout :
j j

amliorer la lisibilit de vos sources ; viter la duplication de code. Les objets, qui permettent galement de mieux architecturer votre code, sont prsents dans un chapitre part.

Les fonctions
Vous savez dsormais que PHP permet de faire appel des fonctions. Les exemples prcdents vous ont ainsi permis dillustrer lutilisation de la fonction print() dont le rle est dafficher les donnes qui lui sont transmises. La plupart des fonctions reoivent des paramtres et retournent une valeur qui en dpend : on parle d arguments dune fonction . Par exemple, la fonction print() prend comme paramtre une chane de caractres ou un chiffre. Sa signature est donc celle-ci : print($str). La fonction de puissance prend quant elle, deux arguments, savoir le nombre et la puissance laquelle il doit tre lev : pow($n,$p).
$resultat = pow(2,4); // $resultat contient 16 // qui correspond bien 2 exposant 4

Ces deux fonctions, comme plusieurs centaines dautres, sont incluses par dfaut dans PHP. Vous pouvez y faire appel nimporte quel moment dans votre code. En plus de cette bibliothque de fonctions, PHP vous permet galement de dnir vos propres fonctions.

LE GUIDE COMPLET 99

Chapitre 3

Les fondamentaux

Dnir une fonction


Supposez que vous vouliez quune fonction renvoie le double dune valeur. Il faut tout dabord lui donner un nom, double(), et dcider de combien darguments elle a besoin ; a priori, un seul. La syntaxe pour dclarer une fonction en PHP est la suivante :
function double($n) { $resultat = $n * 2; return $resultat; }

Nommer largument $n nest pas du tout obligatoire. Vous auriez tout fait pu crire la fonction ainsi :
function double($nimportequoi) { $resultat = $nimportequoi * 2; return $resultat; }

Il est cependant souvent intressant de donner un nom dargument en rapport avec le type de largument. Ainsi, si la fonction ncessite comme paramtre un boolen, il peut tre judicieux de choisir $bool ; et sil sagit une chane de caractres, $str ou $ch peuvent tre des bons choix. Dans la majorit des cas, votre fonction retournera une valeur. Ceci est ralis avec linstruction return :
return $resultat;

Linstruction return

Linstruction return met n la fonction en renvoyant un rsultat relatif la donne qui lui est passe en paramtre. Une fonction contenant des conditions peut tout fait avoir diffrentes instructions return.

Une fois votre fonction dclare dans votre script PHP, vous pouvez lappeler de nimporte quel endroit et autant de fois que vous le voulez :
function double($n) { $resultat = $n * 2; return $resultat; }

100 LE GUIDE COMPLET

Organisation du code

Chapitre 3

$a = 2; $b = double($a); print("le double de $a est $b"); // affiche : "le double de 2 est 4"

crivons notre propre version de la fonction de calcul de puissance : pow(). Vous ne pouvez pas lappeler pow() car il est interdit dutiliser le nom dune fonction dj existante. Nommons-la puissance :
function puissance($n,$p) { $resultat = $n; $i = 1; while ($i < $p) { $resultat *= $n; $i++; } return $resultat; } print(puissance(2,4)); // affiche comme prvu 16

tudions maintenant un exemple dans lequel les fonctions rendent un vritable service. Le script suivant permet un comptable de calculer le bonus de deux commerciaux selon une formule assez complexe :
si le CA est suprieur 300 : bonus = (CA + 100) / 8.4 sinon bonus = (CA + 80) / 7.6 $ca_marcel = 350; $ca_julien = 150; if ($ca_marcel > 300) $bonus_marcel = ($ca_marcel + 100) / 8.4; else $bonus_marcel = ($ca_marcel + 80) / 7.6; print("Bonus de Marcel : ".$bonus_marcel."<br/>"); if ($ca_julien > 300) $bonus_julien = ($ca_julien + 100) / 8.4; else $bonus_julien = ($ca_julien + 80) / 7.6; print("Bonus de Julien : ".$bonus_julien."<br/>");

LE GUIDE COMPLET 101

Chapitre 3

Les fondamentaux

Premire remarque la vue de ce code : vous avez crit deux fois le mme extrait de code :
if ($ca > 300) $bonus = ($ca + 100) / 8.4; else $bonus = ($ca + 80) / 7.6;

Cest doublement regrettable ! Tout dabord, il est extrmement fastidieux de taper du code (nous sommes tous daccord sur ce point) et il est donc inutile de perdre son temps crire plusieurs fois la mme chose. Imaginez ensuite que vous vouliez modier le taux 8,4 par 8,3. Il vous faudra non seulement le faire diffrents endroits, mais, qui plus est, il conviendra de noublier aucune mise jour. Cest prcisment pour viter ces difficults quil est bon de crer la fonction calc_bonus() qui calcule le bonus dun commercial en fonction de son CA :
function calc_bonus($prenom,$ca) { if ($ca > 300) $bonus = ($ca + 100) / 8.4; else $bonus = ($ca + 80) / 7.6; print("Bonus de ".$prenom." : ".$bonus."<br/>"); return $bonus; }

Le code devient donc :


function calc_bonus($prenom,$ca) { if ($ca > 300) $bonus = ($ca + 100) / 8.4; else $bonus = ($ca + 80) / 7.6; print("Bonus de ".$prenom." : ".$bonus."<br/>"); return $bonus; } calc_bonus("marcel",350); calc_bonus("julien",150);

Cette modication a aussi permis de rendre plus clair et plus lisible votre code, ce qui nest pas ngligeable.
Commentaires

Les commentaires sont autoriss au sein mme de la dnition dune fonction.

102 LE GUIDE COMPLET

Organisation du code

Chapitre 3

Valeurs par dfaut


Nous avons vu que la syntaxe pour dclarer une fonction est la suivante :
function nom_fonction($param1,$parma2) { bloc_de_code; }

Il est possible de donner des valeurs par dfaut aux paramtres de la fonction en la dclarant ainsi :
function nom_fonction($param1 = "valeur_par_dfaut") { bloc_de_code; }

crivez une fonction affiche_retour() et appelez-la de deux faons diffrentes :


<?php function affiche_retour($url = "/") { echo "<a href=$url>retour</a><br/>"; } // version 1 : nous utilisons le paramtre par dfaut echo "merci de votre visite<br/>"; affiche_retour(); //version 2 : nous passons la valeur du paramtre echo "merci de votre visite<br/>"; affiche_retour("/"); ?>

Attention, si la fonction possde plusieurs paramtres, seul le dernier pourra prendre une valeur par dfaut !
<?php function affiche_retour($url,$nomlien = "retour") { echo "<a href=$url>retour</a><br/>"; } //version 2 : valeur par dfaut pour le deuxime paramtre echo "merci de votre visite<br/>"; affiche_retour("/");

LE GUIDE COMPLET 103

Chapitre 3

Les fondamentaux

//version 2 : nous passons les valeurs des 2 paramtres echo "merci de votre visite<br/>"; affiche_retour("/","back"); ?>

Rcursivit
La factorielle de la valeur 5 se calcule ainsi :
facto(5) = 5 * 4 * 3 * 2 * 1

Une dnition possible de facto(n) est la suivante :


facto(n) = n * n-1 * n-2 * ... * 3 * 2 * 1

Il est aussi possible de donner une dnition rcursive de la fonction factorielle :


facto(n) = n * facto(n-1) avec facto(1) = 1

En effet, prenez n = 5 et dveloppez :


facto(5) facto(4) facto(3) facto(2) facto(1) = = = = = 5 4 3 2 1 * facto(4) * facto(3) * facto(2) * facto(1) (daprs la dfinition)

Si vous remontez maintenant avec tous vos rsultats intermdiaires, vous obtenez :
facto(2) facto(3) facto(4) facto(5) = = = = 2 3 4 5 * * * * 1 2 * 1 3 * 2 * 1 4 * 3 * 2 * 1

Vous parvenez donc bien au rsultat escompt. Cette technique de programmation, o une fonction se rappelle elle-mme, sappelle la rcursivit . Il est possible en PHP dutiliser cette technique. crivez la fonction factorielle tout dabord classiquement :
function facto($n) { for ($resultat = 1; $n > 1; $n--) { $resultat *= $n; } return $resultat; } print(facto(5));

104 LE GUIDE COMPLET

Organisation du code

Chapitre 3

Boucle for

Vous pouvez vous apercevoir que lindice $n diminue au sein de la boucle : $n.

crivez maintenant la version rcursive de la mme manire que la formule rcursive vue prcdemment :
function facto($n) { if ($n == 1) return 1; else return $n * facto($n-1); } print(facto(5));

En appelant facto(5), la fonction va se rappeler elle-mme jusqu facto(1), o elle va retourner la valeur 1. partir de l, elle va faire le chemin inverse et remonter avec les valeurs intermdiaires. Modiez un peu le programme an quil affiche les tapes intermdiaires :
<?php function facto($n) { print "facto de $n<br/>"; if ($n == 1) { print "<br/>facto 1 = 1<br/><br/>"; return 1; } else { $r = $n * facto($n-1); print "> $r<br/>"; return $r; } } $n = 5; print("<hr>factorielle de $n = " . facto($n)); ?>

LE GUIDE COMPLET 105

Chapitre 3

Les fondamentaux

Figure 3.18 : Factorielle

Le parcours dun rpertoire crit de faon rcursive est propos dans le chapitre consacr aux fonctions PHP dans la prsentation de opendir(). Cette technique est loin dtre indispensable en programmation. Tout code rcursif peut tre exprim de manire itrative avec de simples boucles for. Nanmoins, dans certains cas, une version rcursive peut se rvler beaucoup plus simple coder.

Variables globales
Observez lexemple suivant :
function aff() { $i = $i + 1; print($i); } for ($i = 1; $i <= 5; $i++) { print("[$i] "); aff(); print("<br/>"); }

106 LE GUIDE COMPLET

Organisation du code

Chapitre 3

Figure 3.19 : Fonction aff()

Lvnement quil faut noter, dans cet exemple, est que la variable $i de la fonction, dune part, et celle du script, dautre part, ne semblent pas tre relies entre elles, alors quelles ont le mme nom. Quand vous tes la deuxime itration de votre boucle for et que $i vaut 2, vous pouvez supposer que la fonction aff() affiche 3 ($i + 1) lcran et non 1. Ce nest pas le cas et ce comportement est tout fait normal. Les variables incluses dans une fonction sont locales par rapport la fonction et nont rien voir avec les ventuelles variables de mme nom prsentes dans le corps du script. Il est cependant possible, depuis une fonction, davoir accs aux variables du script en dclarant dans la fonction les variables dont vous avez besoin en tant que globales .
global $var1, $var2 ....;

Modiez la fonction aff() an de lui faire utiliser la variable $i contenue dans le script :
<?php function aff() { global $i; $i = $i + 1; print($i); } for ($i = 1; $i <= 5; $i++) { print("[$i] "); aff(); print("<br/>"); } ?>

LE GUIDE COMPLET 107

Chapitre 3

Les fondamentaux

Figure 3.20 : Exemple de fonction utilisant une variable globale

Le rsultat na plus rien voir. Droulez les deux premires itrations du script tape par tape
j

Premire itration :
entre dans la boucle for : $i est initialis 1 affichage de $i : 1 appel de la fonction aff() rcupration la variable $i du script qui vaut 1 incrmentation de 1, $i vaut maintenant 2 affiche de $i : 2

Deuxime itration :
incrment la valeur de $i qui vaut maintenant 3 affichage de $i : 3 appel de la fonction aff() rcupration de $i : 3 $i passe 4 affichage de $i : 4, etc.

Voyez maintenant si la modication suivante vous surprend :


<?php function aff($i) { $i = $i + 1;

108 LE GUIDE COMPLET

Organisation du code
print($i); } for ($i = 1; $i <= 5; $i++) { print("[$i] "); aff($i); print("<br/>"); } ?>

Chapitre 3

Figure 3.21 : Rsultat

Dans ce cas, aff utilise bien la valeur de la variable $i du script, mais ne modie pas sa valeur au sein du script. Rien de plus logique car aff reoit en paramtre la valeur de $i, quelle stocke dans une variable locale : $i. Il ne sagit en aucun cas dune variable globale. Il faut donc retenir que les paramtres des fonctions sont des variables locales la fonction comme les autres.

Inclusion de chier
Un script PHP peut tout moment faire appel dautres scripts par lintermdiaire de la fonction include(). Variables et fonctions sont partages par lensemble des scripts inclus. Cette technique est extrmement intressante pour charger un chier de conguration ou pour construire votre interface graphique en y incluant par exemple systmatiquement un en-tte et un pied de page. La modication dun de ces chiers inclus est tout de suite rpercute dans lensemble du site. Cette fonction prend en argument le chemin du script inclure qui peut tre transmis de faon relative ou absolue.
LE GUIDE COMPLET 109

Chapitre 3

Les fondamentaux

Un chemin absolu correspond au chemin depuis la racine du serveur. Pour inclure le script entete.php prsent dans le rpertoire www/interface de Wamp, le chemin absolu correspond "c:/wamp/www/interface /entete.php". Un chemin relatif correspond quant lui au chemin depuis celui du script appel :
j j

include("entete.php") inclut un script prsent dans le

mme rpertoire que le script appel ;


include("interface/entete.php") inclut un script prsent

dans le rpertoire interface qui est lui-mme prsent dans le rpertoire contenant le script appel ; include("../entete.php") permet dappeler un script situ dans le rpertoire parent de celui du script appel.
Inclusion dinclusion

Si un chier inclus inclut lui-mme un autre chier, le rpertoire de rfrence pour les chemins reste quoi quil arrive celui du script appel.

Le chemin relatif est gnralement prfrable car non dpendant de lenvironnement de dveloppement. Une application dveloppe en relatif sous Windows peut tout fait fonctionner dans un environnement Linux. Lexemple suivant met en uvre la fonction include() pour construire une structure de page compose dun en-tte, dun contenu et dun pied de page. Le titre du site est contenu dans un chier de conguration.
Listing 3-28 : entete.php <html> <title> <?php print($titre); ?> </title> <body> <h1> <?php print($titre); ?>
110 LE GUIDE COMPLET

Organisation du code
</h1> <hr/> Listing 3-29 : piedpage.php <hr/> <center> <i>contact - copyright - propos de <?php print($titre); ?> </i> </center> </body> </html> Listing 3-30 : config.php <?php $titre = "Cool Site"; ?> Listing 3-31 : test.php <?php include("interface/config.php"); include("interface/entete.php"); print("Bienvenue"); include("interface/piedpage.php"); ?>

Chapitre 3

Figure 3.22 : Modle de page avec en-tte et pied de page

LE GUIDE COMPLET 111

Chapitre 3

Les fondamentaux

La fonction include() peut galement retourner une valeur si le code inclus utilise la fonction return(). Cette faon doprer est trs utile pour savoir si lexcution du code inclus sest bien droule.
Listing 3-32 : Vrification de la valeur retoune par la fonction include() if (include("script.php") == false) { die("Erreur"); }

Extension du script inclus

PHP interprte tous les scripts inclus quelle que soit leur extension. Il est ainsi courrant dutiliser lextension .inc ou .inc.php pour nommer les chiers inclus et les distinguer des scripts accessibles directement . Ce nest cependant ni une norme ni une obligation.

PHP propose trois autres fonctions trs proches dinclude() :


Tableau 3.4 : Fonctions cousines de include()

Nom de la fonction

Utilisation Le chier nest inclus que sil ne la pas t auparavant. Cette fonction arrte le script si elle nest pas parvenue inclure le chier pass en argument. La fonction include() se contente quant elle dafficher un avertissement et poursuit lexcution du script. Le chier nest inclus que sil ne la pas t auparavant.

include_once() require()

require_once()

Avec lexprience, vous constaterez que les chiers inclus sont souvent regroups dans une mme arborescence. Il peut donc apparatre superu de spcier systmatiquement le chemin complet du script inclure. PHP a prvu cela et permet de spcier un certain nombre de rpertoires dans lesquels linterprteur essayera de trouver les chiers inclure. Cette directive, include_path, contient une liste de rpertoires spars par un ; sous Windows et par un : sous Linux / Unix. Cette directive (comme un certain nombre dautres) peut tre modie soit directement dans le chier de conguration php.ini soit laide des fonctions ini_get() et ini_set() qui permettent de rcuprer la valeur dune

112 LE GUIDE COMPLET

Check-list

Chapitre 3

directive pour la premire et de la modier pour la seconde. Lexemple ci-dessus peut ainsi tre modi de la faon suivante :
Listing 3-33 : Modification de la directive include_path afin de simplifier les inclusions <?php $tmp = ini_get("include_path").";interface"; ini_set("include_path",$tmp); include("config.php"); include("entete.php"); print("Bienvenue"); include("piedpage.php"); ?>

Inclusion de chiers distants

La fonction include() autorise linclusion de chiers distants. Linstruction include("http://www.google.com") est par consquent tout fait valide. Veillez toutefois contrler que la directive de conguration allow_url_fopen soit bien On.

3.8. Check-list
j j j j j

j j j

PHP est un langage procdural. Les variables sont prcdes dun $. Un point-virgule doit tre prsent la n de chaque instruction. Un groupe dinstructions PHP doit tre entour des balises <?php et ?>. PHP nimpose pas le typage de variables en dbut de programme. Les types sont toutefois prsents et comptent, parmi les plus importants, les numriques et les chanes de caractres. Les structures de contrle permettent de restreindre lexcution dinstructions certains cas bien spciques. Les boucles permettent lexcution rptitive de certaines instructions. Les fonctions permettent disoler des groupes dinstructions qui auraient t sinon rpts dans le code. En plus des fonctions internes PHP, le dveloppeur peut crer ses propres fonctions.

LE GUIDE COMPLET 113

Chapitre 3
j j

Les fondamentaux

Les fonctions peuvent avoir accs aux variables du programme laide du mot-cl global. Comme les fonctions, les chiers inclus permettent de mieux organiser votre code.

114 LE GUIDE COMPLET

Les tableaux

Prsentation ........................................................................................................................ 116 Parcours dun tableau ...................................................................................................... 121 Les fonctions ....................................................................................................................... 125 Les oprateurs sur les tableaux ..................................................................................... 136 Check-list ............................................................................................................................. 137

Chapitre 4

Les tableaux

Les variables tudies jusqu prsent permettaient de ne stocker quune seule et mme valeur, quil sagisse dune chane de caractres, dun numrique ou dun boolen. PHP propose galement un type spcial de donne donnant la possibilit une variable de contenir une liste dlments. Ces variables sont appeles tableaux et sont associes au type array. Les tableaux peuvent tre assimils des classeurs disposant dun nombre variable demplacements pour stocker de linformation. On parle, pour qualier ces emplacements, de cellules dun tableau. Ce chapitre va nous permettre de nous familiariser avec ce type de variable en prsentant les oprations de cration et de manipulation de tableaux. Nous tudierons galement les diffrents oprateurs ainsi quun certain nombre de fonctions spciques aux tableaux.

4.1. Prsentation
Deux mthodes permettent de crer et dinitialiser un tableau. La premire consiste utiliser la fonction array() en lui passant directement en argument la liste des lments du tableau. La cration dun tableau $couleur contenant les lments "rouge", "vert", "bleu" utilise la syntaxe suivante :
Listing 4-1 : Cration dun tableau $couleur $couleur = array("rouge", "vert", "bleu");

Lautre mthode consiste utiliser la fonction array() sans argument an de dclarer la variable en tant que tableau puis lui ajouter des lments. Lajout dune cellule utilise la syntaxe $couleur[].
Listing 4-2 : Cration du tableau $couleur en lui ajoutant 3 cellules $couleur = array(); $couleur[] = "rouge"; $couleur[] = "vert"; $couleur[] = "bleu";

Les deux mthodes peuvent tre cumules. Dans lexemple suivant, le tableau $couleur est cr avec deux cellules initiales puis se voit complt par trois cellules complmentaires.

116 LE GUIDE COMPLET

Prsentation
Listing 4-3 : $couleur contient cinq cellules $couleur = array("rouge","vert"); $couleur[] = "bleu"; $couleur[] = "jaune"; $couleur[] = "orange";

Chapitre 4

Figure 4.1 : Tableau contenant cinq cellules

Maintenant que nous sommes en mesure de crer des tableaux, ltape suivante consiste pouvoir faire rfrence une cellule dun tableau en particulier. Nous allons pour cela prsenter les deux grandes familles de tableaux : les tableaux scalaires et les tableaux associatifs.

Les tableaux scalaires


Dans le cadre dun tableau scalaire, chaque lment du tableau est accessible par son numro unique denregistrement, aussi appel index ou indice. Par convention, le premier lment dun tableau a pour index 0. $couleur[0] correspond donc la premire valeur du tableau, cest-dire "rouge".
Listing 4-4 : Accder un lment dun tableau $couleur = array("rouge", "vert", "bleu"); print("deuxime lment du tableau : $couleur[1]"); // affiche : "deuxime lment du tableau : vert"

La modication dun lment de tableau se fait en affectant une nouvelle valeur directement llment en question :
Listing 4-5 : Modifier une valeur dun tableau $couleur = array("rouge", "vert", "bleu"); // modification du premier lment du tableau couleur : // il ne contiendra plus "rouge" mais "jaune" $couleur[0] = "jaune";

LE GUIDE COMPLET 117

Chapitre 4

Les tableaux

Lassociation dune valeur une cellule dont lindice nexiste pas permet de crer cette cellule :
$couleur = array("rouge", "vert", "bleu"); // ajoute la couleur orange au tableau couleur qui //contenait 3 valeurs $couleur[3] = "orange"; print("$couleur[3]") ; // affiche le quatrime lment du // tableau : orange

Ordre des indices

PHP ne vous impose pas de suivre un ordre rigoureux dans le choix des indices du tableau. Lexemple suivant est par exemple tout fait valide :
$couleur = array(); $couleur[0] = "bleu"; $couleur[2] = "jaune"; $couleur[4] = "orange";

charge pour vous de trouver une logique tout cela !

Les tableaux associatifs


Dans le cadre dun tableau associatif, chaque cellule du tableau est identie non plus par un indice numrique mais par une cl de type chane de caractres. Cette cl, par nature, doit tre unique an de permettre de slectionner chaque lment du tableau. La cration dun tableau associatif utilise la syntaxe suivante :
array(cle1 => valeur1, cle2 => valeur2)

La cration dun tableau $personne dont les caractristiques seraient le nom, le prnom et lge peut tre ralise de la manire suivante :
$personne = array("nom"=>"Dupont","prenom"=>"Paul","age"=>23);

La syntaxe $personne["nom"] permet quant elle daccder la valeur de la cellule identie par la cl nom. Lassignation dune valeur une cellule fonctionne comme pour les tableaux scalaires, en remplaant lindice par la cl : $personne["age"] = 34.

118 LE GUIDE COMPLET

Prsentation

Chapitre 4

Si la cl nexiste pas, une nouvelle cellule est alors automatiquement cre.


Listing 4-6 : Le tableau contient dsormais quatre cellules $tab = array("nom"=>"Dupont","prenom"=>"Paul","age"=>23); $tab["ville"] = "Paris";

Majuscules et minuscules pour les cls

Les cls sont sensibles la casse. Ainsi $personne[nom] et $personne[Nom] feront rfrence deux cellules distinctes.

La dnition dun tableau sur plusieurs lignes favorise souvent la lecture et la comprhension des sources.
Listing 4-7 : Dfinition dun tableau sur plusieurs lignes $tab = array("nom" => "Dupont", "prenom" => "Paul", "age" => 23);

Les tableaux multidimensionnels


Les diffrents tableaux prsents prcdemment sont des tableaux une dimension. Un index seul (ou une cl seule) donne la possibilit daccder nimporte quel lment du tableau. PHP vous permet galement de crer des tableaux multidimensionnels. Un tableau de dimension 2 par exemple peut tre envisag comme un chiquier. Deux informations sont ncessaires pour accder une case donne du tableau : labscisse et lordonne. Pour accder llment dabscisse 3 et dordonne 5 du tableau $echiquier, la syntaxe utiliser est la suivante $echiquier[3][5]. Des tableaux multidimensionnels scalaires et associatifs peuvent galement tre crs. Illustrons cela laide dun exemple et crons le tableau $tab :
Listing 4-8 : Cration dun tableau 2 dimensions $tab = array( 0 => array("prenom"=>"pe", "nom"=>"wood","age"=>12), 1 => array("prenom"=>"fc", "nom"=>"bosque","age"=>11) );

LE GUIDE COMPLET 119

Chapitre 4

Les tableaux

Ce tableau contient deux individus, chacun disposant dun prnom, dun nom et dun ge. Il est important ici de comprendre que chaque lment du tableau est lui-mme compos dun autre tableau. Le schma suivant permet de mieux visualiser la structure interne de $tab :

Figure 4.2 : Tableau multidimensionnel

Pour augmenter $tab dun nouvel individu, nous lui ajoutons une cellule qui, en loccurrence, est elle-mme un tableau :
Listing 4-9 : Ajout dune cellule $tab $tab[] = array("prenom"=>"jp", "nom"=>"siob", "age"=>13);

Figure 4.3 : tat du tableau multidimensionnel aprs lajout dun nouvel individu

Pour

accder

au

prnom

du

troisime

individu,

crivez :

$tab[2]["nom"]. Noubliez pas en effet que le premier lment a pour index 0.

120 LE GUIDE COMPLET

Parcours dun tableau

Chapitre 4

Affichage complexe

Faire rfrence la cellule dun tableau scalaire au sein dune chane de caractres est tout fait autoris :
print("premier lment : $tab[0]");

Il en va tout autrement pour les tableaux scalaires et les tableaux multidimensionnels qui imposent une syntaxe dite complexe . Deux accolades viennent alors entourer la rfrence la cellule :
print("lment nom : {$tab[nom]}"); print("lment nom : {$tab[2]["nom"]}");

La solution alternative consistant utiliser loprateur de concatnation est bien videmment toujours autorise :
print("lment nom : " . $tab[2][nom]);

4.2. Parcours dun tableau


Diverses mthodes permettent de parcourir lensemble des valeurs dun tableau.

Boucle foreach
PHP propose une catgorie de boucle for spcialement ddie aux tableaux : la boucle foreach. Une boucle foreach pourrait tre traduite de la manire suivante :
POUR chaque lment contenu dans le tableau FAIRE

La syntaxe suivante permet dafficher lensemble des lments dun tableau :


Listing 4-10 : Affichage des lments dun tableau scalaire $tab = array ("a", "b", "c", "d"); foreach ($tab as $val) { print("$val<br/>"); }

chaque itration de la boucle, foreach associe la valeur de llment du tableau en cours la variable $val puis dplace son pointeur interne sur llment suivant. Le nom de la variable est bien videmment libre.

LE GUIDE COMPLET 121

Chapitre 4

Les tableaux

Sil sagit dun tableau associatif, la syntaxe est lgrement diffrente an de permettre la rcupration de la cl associe.
Listing 4-11 : Affichage des lments dun tableau associatif $tab = array("prenom" => "paul", "nom" => "dupont"); foreach ($tab as $cle => $valeur) { print("$cle = $valeur<br/>"); }

Figure 4.4 : Boucle foreach

criture cl/valeur pour un tableau scalaire

Lcriture foreach ($tab as $cle => $valeur) est galement possible pour les tableaux scalaires. La variable $cle contiendra alors lindice (numrique) de llment.

Lutilisation dune boucle while pour balayer un tableau est assez courante (surtout parmi les dveloppeurs issus du langage C). Lide est ici de parcourir le tableau tant quil contient un lment :
Listing 4-12 : Parcours dun tableau laide de la boucle while $tab = array("a", "b", "c", "d"); $i = 0; while ($tab[$i]) { print($tab[$i]."<br/>"); $i++; }

Cette mthode trouve cependant sa limite avec un tableau $tab qui contiendrait les valeurs suivantes : "a", "b", false, "c".

122 LE GUIDE COMPLET

Parcours dun tableau

Chapitre 4

Le while sarrtera en effet la troisime cellule lorsque $tab[$i] contiendra la valeur false. Une boucle foreach en revanche afficherait bien les quatre lments.
break et continue

Les instructions break et continue peuvent galement tre utilises dans le cadre dun foreach.

Utilisation du pointeur interne


En plus des lments quil contient, un tableau dispose galement dun pointeur interne sur llment courant. Le pointeur est plac par dfaut sur le premier lment du tableau et peut tre dplac laide dune multitude de fonctions.
Tableau 4.1 : Fonctions permettant de manipuler le pointeur interne dun

tableau Fonction Rle Place le pointeur au dbut du tableau et retourne la valeur du premier lment Dplace le pointeur sur llment suivant et retourne sa valeur Dplace le pointeur sur llment prcdent et retourne sa valeur Retourne la cl de llment courant Retourne un tableau contenant la paire cl/valeur de llment courant Retourne la valeur de llment courant Place le pointeur sur le dernier lment de la liste et retourne sa valeur

reset() next() prev() key() each() current() end()

Listing 4-13 : Dplacement du pointeur interne dun tableau $tab = array("rouge","vert","bleu","jaune"); echo end($tab)."<br/>"; echo prev($tab)."<br/>"; echo key($tab)."<br/>"; echo reset($tab)."<br/>"; echo current($tab)."<br/>"; print_r(each($tab))."<br/>";

LE GUIDE COMPLET 123

Chapitre 4

Les tableaux

Figure 4.5 : Exemple de dplacement de pointeur

Fonction end()

Cette fonction peut retourner la valeur null si le pointeur interne est dj au bout du tableau ou si le dernier lment contient lui-mme la valeur null. La boucle foreach reste donc le meilleur moyen de parcourir un tableau de faon sre.

Utilisation des rfrences


Lassignation dune variable une autre variable ne signie en aucun cas que les deux variables sont identiques mais bien que leur valeur un instant t sont les mmes.
Listing 4-14 : Assignation simple, les 2 variables sont indpendantes $a = 2; $b = $a; // $a et $b contiennent 2 $a = 1; // $a contient 1 et $b contient toujours 2

PHP dispose toutefois dune syntaxe permettant de lier de faon forte deux variables. Il sagit de la notion de rfrence. Loprateur & devant une variable permet de donner accs non pas sa valeur mais une rfrence elle-mme. Toute modication dune variable modiera alors lautre.
Listing 4-15 : $b est un alias de $a $a = 2; $b = &$a; // $b nest quune rfrence $a $a = 1; // $a contient 1 et $b contient galement 1

124 LE GUIDE COMPLET

Les fonctions

Chapitre 4

Cette syntaxe est particulirement intressante dans le cadre dun foreach pour pouvoir modier une une toutes les valeurs dun tableau. Chaque itration de la boucle donne accs non pas la valeur de llment mais une rfrence cet lment permettant de modier sa valeur.
Listing 4-16 : Chaque itration donne accs une rfrence $tab = array("bleu", "blanc", "rouge"); foreach ($tab as &$value) { $value = "{".$value."}"; }

Figure 4.6 : Tous les lments du tableau ont bien t modis

4.3. Les fonctions


Plus de 70 fonctions consacres aux tableaux sont mises la disposition du programmeur PHP. Ces fonctions, aussi souples que puissantes, sont sans conteste une des grandes forces de ce langage. Une liste plus complte de fonctions de manipulations de tableaux est propose la n de cet ouvrage.

Suppression dune cellule


La fonction unset() utilise pour supprimer une variable sert galement supprimer des cellules dun tableau.
Listing 4-17 : Suppression de la deuxime cellule du tableau $tab = array("a","b","c"); unset($tab[1]);
LE GUIDE COMPLET 125

Chapitre 4

Les tableaux

Figure 4.7 : tat du tableau aprs la suppression

La logique est exactement multidimensionnels.

la

mme

pour

des

tableaux

Listing 4-18 : Suppression du prnom associ Mr Wood $tab = array( 0 => array("prenom"=>"pe", "nom"=>"wood","age"=>12), 1 => array("prenom"=>"fc", "nom"=>"bosque","age"=>11) ); unset($tab[0][prenom]);

Figure 4.8 : Seul le prnom du premier individu a t supprim

Affichage dun tableau


La fonction print_r() permet dafficher un tableau dune manire lisible. Crons un tableau complexe an de visualiser lintrt de cette fonction :
Listing 4-19 : Affichage dun tableau complexe $tab = array( 0 => array("a","b",array("d","e","f")), 1 => "i", 2 => array("j","k"=>array("l"=>array("m","o"),"p")) ); print_r($tab);

Figure 4.9 : Utilisation de print_r() pour afficher le contenu de $tab

126 LE GUIDE COMPLET

Les fonctions

Chapitre 4

Nous constatons que cet affichage rvle le contenu du tableau sans faciliter rellement la lecture du tableau. Notre erreur est ici de ne pas entourer le print_r() des balises <pre> et </pre>. Ces balises permettent en effet de conserver laffichage des retours chariots et des espaces au sein dun contenu HTML.
Listing 4-20 : Balises <pre> et </pre> autour de la fonction print_r() $tab = array( 0 => array("a","b",array("d","e","f")), 1 => "i", 2 => array("j","k"=>array("l"=>array("m","o"),"p")) ); print("<pre>"); print_r($tab); print("</pre>");

Figure 4.10 : Amlioration de laffichage du print_r() laide des balises <pre> et </pre>

Taille dun tableau


La taille dun tableau peut tre obtenue avec la fonction count(). Cette taille correspond au nombre dlments quun tableau contient, quil soit scalaire ou associatif.
$tab = array(); $n = count($tab); print($n); // affiche : 0 $tab = array(1,2); $n = count($tab); print($n); // affiche : 2 $tab = array("a"=>"b"); $n = count($tab); print($n); // affiche : 1 $tab = array("a"=>array(1,2,3),"b"=>array(4,5,6)); $n = count($tab); print($n); // affiche : 2

La fonction count() peut galement retourner la taille dun tableau multidimensionnel si la valeur 1 est passe en second paramtre.
LE GUIDE COMPLET 127

Chapitre 4

Les tableaux

$tab = array("a"=>"b"); $n = count($tab,1); print($n); // affiche : 1 $tab = array("a"=>array(1,2,3),"b"=>array(4,5,6)); $n = count($tab,1); print($n); // affiche : 8

Le dernier exemple affiche 8 car il sagit dun tableau contenant 2 cellules qui elles-mmes contiennent chacune trois cellules : 2+3+3 = 8.
Fonction sizeof()

La fonction sizeof() peut galement tre utilise pour obtenir la taille dun tableau. Cette fonction ne correspond cependant qu un alias de la fonction count() qui est, de ce fait, recommande.

Conversion chanes / tableaux


Une liste dlments est rgulirement reprsente en informatique par une chane de caractres contenant ces mmes lments spars par une virgule, un point-virgule, une tabulation ou tout autre caractre de sparation.
Listing 4-21 : Variable contenant une liste de prnoms $liste = "patrick,pascal,veronique,benedicte,gonzague,olivier";

Ce type de reprsentation est extrmement pratique pour stocker une liste dans un chier de conguration ou lors dune transmission de donne mais se rvle trs peu manipulable au sein dun script PHP. Dans une telle situation, la reprsentation en tableau est largement prfrable. La fonction explode() permet de convertir une liste reprsente par une chane de caractres en un tableau. Le premier argument de la fonction correspond au caractre de sparation et le second la chane elle-mme. Llment de sparation est souvent constitu par un caractre unique mais peut galement correspondre une chane de caractres telle que : ",,", "##", etc.
Listing 4-22 : Conversion dune chane en un tableau $liste = "patrick,pascal,veronique,benedicte,gonzague,olivier"; print($liste); $tab = explode(",",$liste); print("<pre>"); print_r($tab); print("</pre>");

128 LE GUIDE COMPLET

Les fonctions

Chapitre 4

Figure 4.11 : Reprsentation dune liste sous la forme dune chane puis dun tableau

La situation consistant devoir assigner diffrentes variables les valeurs dun tableau retourn par explode() est assez courante.
Listing 4-23 : Association dlments dun tableau des variables $date = "2004/10/23"; $tab = explode("/", $date); $annee = $tab[0]; $mois = $tab[1]; $jour = $tab[2];

PHP permet de rduire cette syntaxe avec la fonction list(). Cette dernire se charge dassigner les valeurs dun tableau plusieurs variables en une seule ligne.
Listing 4-24 : Assignation de 3 variables en une seule ligne $date = "2004/10/23"; list($annee, $mois, $jour) = explode("/", $date);

Abus de langage list() nest pas vritablement une fonction; il sagit plus exactement

dun lment constitutif du langage PHP.

Lopration inverse dexplode() permettant de passer dun tableau une chane est ralise par la fonction implode() dont les deux arguments sont le caractre dunion et le tableau.
Listing 4-25 : Conversion dun tableau en chane de caractres $tab = array("patrick","pascal","veronique","benedicte", "gonzague","olivier"); print("<pre>"); print_r($tab); print("</pre>"); $liste = implode(" ; ",$tab); print($liste);

LE GUIDE COMPLET 129

Chapitre 4

Les tableaux

Figure 4.12 : Trois caractres sont ici utiliss pour unir les lments du tableau au sein de la chane

Adjonction, soustraction dlments


Certaines fonctions permettent dajouter ou denlever des lments en dbut ou n de tableau.
Tableau 4.2 : Fonctions permettant dajouter et denlever des lments dun

tableau Nom de la fonction Rle Retourne le premier lment du tableau et le supprime Retourne le dernier lment du tableau et le supprime

array_shift() array_pop()

array_unshift() Ajoute un ou plusieurs lments au dbut du tableau array_push()


Ajoute un ou plusieurs lments la n du tableau

Illustrons ces diffrentes fonctions laide dun exemple :


Listing 4-26 : Evolution du contenu dun tableau $tab = array("rouge","jaune","vert"); print("<pre>"); print("<b>Tableau initial :</b><br/>"); print_r($tab); $elem = array_shift($tab); print("<br/><b>Aprs array_shift() :</b><br/>"); print_r($tab); $elem = array_pop($tab); print("<br/><b>Aprs array_pop() :</b><br/>"); print_r($tab); array_unshift($tab,"orange"); print("<br/><b>Aprs array_unshift() :</b><br/>"); print_r($tab);

130 LE GUIDE COMPLET

Les fonctions
array_push($tab,"marron","gris"); print("<br/><b>Aprs array_push() :</b><br/>"); print_r($tab); print("</pre>");

Chapitre 4

Figure 4.13 : Affichage du contenu du tableau pour chaque tape

Tri
Les fonctions de tri sont nombreuses et permettent de prendre en compte la quasi-totalit des situations dans lesquelles vous pouvez vous trouver.

sort()
Cette fonction permet de trier un tableau en fonction de ses valeurs.
$tab = array("vert","bleu","jaune"); sort($tab);

Figure 4.14 : Tri du tableau $tab

LE GUIDE COMPLET 131

Chapitre 4

Les tableaux

Si le tableau est associatif, les cls sont alors supprimes.


$tab = array("nom"=>"dupont","age"=>"21","prenom"=>"alexandre"); sort($tab);

Figure 4.15 : Le tableau est tri mais les cls ont disparu

asort()
Cette fonction permet de conserver lassociation cl/valeur lissue du tri. Le tri porte sur les valeurs du tableau.
$tab = array("nom"=>"dupont","age"=>"21","prenom"=>"alexandre"); asort($tab);

Figure 4.16 : Les cls restent associes leur valeur

ksort()
Le tri seffectue cette fois sur les cls, tout en maintenant lassociation avec les valeurs.
$tab = array("nom"=>"dupont","age"=>"21","prenom"=>"alexandre"); ksort($tab);

Figure 4.17 : Tri sur les cls

132 LE GUIDE COMPLET

Les fonctions

Chapitre 4

natsort()
Les comparaisons sur les chanes de caractres sont ralises caractre par caractre. Ainsi la chane "ab" est plus petite que "ac" car le caractre b est plus petit que c. De la mme manire, "ab" est plus petit que "aaa" car la premire chane ne dispose pas de troisime caractre. Ce mode de classement peut poser problme pour des valeurs contenant des chiffres. Dans un tel cas en effet, la chane "fichier10.jpg" devient infrieure "fichier2.jpg". La fonction natsort() est prvue pour ce type de situation et ralise un tri dit naturel .
$tab1 = $tab2 = array("fichier100.jpg","fichier2.jpg", "fichier21.jpg","fichier1.jpg"); sort($tab1); print("<b>SORT</b><hr/>"); print("<pre>"); print_r($tab1); print("</pre>"); natsort($tab2); print("<br/><b>NATSORT</b><hr/>"); print("<pre>"); print_r($tab2); print("</pre>");

Figure 4.18 : Diffrence entre un tri standard et un tri naturel

Tri en ordre inverse


La plupart des fonctions prsentes ci-dessus disposent dune fonction cousine permettant de raliser un tri en ordre inverse. Ces fonctions

LE GUIDE COMPLET 133

Chapitre 4

Les tableaux

contiennent un caractre r supplmentaire dans leur nom : arsort(), krsort(), rsort().

Prsence dune valeur dans un tableau


La fonction in_array() permet de vrier quune valeur donne est bien prsente au sein dun tableau. Le premier argument de la fonction correspond la valeur recherche et le second au tableau dans lequel la recherche est ralise.
Listing 4-27 : Vrification de la prsence dune valeur dans un tableau $tab = array("thomas","henry"); if (in_array("thomas",$tab)) { print("Le prnom Thomas a t trouv"); } else { print("Le prnom Thomas na pas t trouv"); }

Une fonction existe galement pour vrier la prsence dune cl au sein dun tableau associatif array_key_exists().
$tab = array("prenom"=>"thomas","nom"=>"henry"); if (array_key_exists("nom",$tab)) { print("Le nom est dfini"); } else { print("Le nom nest pas dfini"); }

Srialisation
La srialisation est une opration permettant de passer de la reprsentation binaire dune donne une reprsentation textuelle. La fonction serialize() prend en argument un tableau et retourne une chane de caractres le reprsentant dans sa version srialise.
Listing 4-28 : Exemple dutilisation de serialize() $tableau = array("couleur" => array("rouge", "jaune"), 1 => 2); print("<b>Affichage avec print_r()</b> :<br/>"); print("<pre>"); print_r($tableau);

134 LE GUIDE COMPLET

Les fonctions
print("</pre>"); print("<hr/>");

Chapitre 4

$tableau_s = serialize($tableau); print("<b>Version srialise</b> :<br/><br/>".$tableau_s);

Figure 4.19 : Deux reprsentations du tableau $tableau

Lobjectif, ici, nest certainement pas danalyser la syntaxe de la version srialise mais plutt de comprendre que cette reprsentation peut tout fait tre place au sein dun chier texte ou dune base de donnes. Au lieu dune prsentation textuelle bancale de type CSV pour enregistrer le contenu dun tableau, la reprsentation srialise possde le triple avantage dtre norme, optimise et de disposer dune fonction de conversion inverse : unserialize(). Lexemple suivant illustre lopration de dsrialisation. La donne contenue dans la variable $str pourrait tout fait provenir du contenu dun chier ou dune requte SQL sur une base de donne.
Listing 4-29 : Illustration de la fonction unserialize() $str = a:2:{i:0;s:1:"a";i:1;s:1:"b";}; $tableau = unserialize($str); print("<pre>"); print_r($tableau); print("</pre>");

LE GUIDE COMPLET 135

Chapitre 4

Les tableaux

Figure 4.20 : Opration de dsrialisation

4.4. Les oprateurs sur les tableaux


Bien quextrmement puissants, les oprateurs sur les tableaux sont assez peu connus.
Tableau 4.3 : Oprateurs sur les tableaux

Oprateur

Rsultat Union de $a et de $b Renvoie true si $a et $b sont composs des mmes paires cl/valeur ; les tableaux sont alors dits gaux Comme ==, avec des vrications supplmentaires sur lordre et le type des donnes ; les tableaux sont alors dits identiques Renvoie true si $a et $b ne sont pas gaux Renvoie true si $a et $b ne sont pas gaux Renvoie true si $a et $b ne sont pas identiques

$a + $b $a == $b

$a === $b

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

Illustrons ces oprateurs de quelques exemples et commenons par loprateur dunion. Loprateur dunion possde ceci de spcial que les cls qui seraient prsentes dans $a et $b ne sont pas rcrites.
$a = array("couleur1"=>"rouge","couleur2"=>"vert"); $b = array("couleur1"=>"jaune","noir","vert"); print_r($a+$b);

136 LE GUIDE COMPLET

Check-list

Chapitre 4

Figure 4.21 : Union de $a et $b

Arrtons-nous maintenant sur les oprateurs de comparaisons an de mieux comprendre les diffrences entre identiques et gaux.
Tableau 4.4 : Diffrents tests de comparaison de tableaux

Tableau 1

Tableau 2

gaux ? NON OUI OUI NON NON

Identiques ? NON NON OUI NON NON

array(1,2) array(1,2) array(1,2) array(1,2) array(1,2)

array(1,2,3) array(1,2) array(0=>1,1=>1) array(3=>1,4=>1) array(2,1)

4.5. Check-list
j j j

Le type associ aux tableaux est array. Les tableaux scalaires et associatifs correspondent aux deux grandes familles de tableaux. PHP est un des langages les plus souples pour la gestion des tableaux : il nest pas demand de prciser un nombre de cellules la cration, chaque cellule peut contenir des donnes de types diffrents.

LE GUIDE COMPLET 137

Dates et heures

La notion de timestamp ................................................................................................... 140 Formatage dune date ...................................................................................................... 146 Contrle de validit dune date ...................................................................................... 152 Check-list ............................................................................................................................. 153

Chapitre 5

Dates et heures

Les chapitres prcdents ont permis de prsenter les principaux types de donnes intgrs de faon native PHP savoir : les chanes de caractres (String), les entiers (Integer), les nombres ottants (Float), les boolens (Boolean) ainsi que les tableaux (Array). Ntant pas un langage purement objet, PHP nintgre pas un type spcique pour le traitement des dates. Le dveloppeur dispose en revanche dune quantit importante de fonctions permettant de raliser les oprations les plus diverses.

5.1. La notion de timestamp


Un timestamp correspond une reprsentation numrique dune date. Il sagit du nombre de secondes coules entre cette date et le premier janvier 1970. La fonction time() retourne le timestamp actuel.
Listing 5-1 : Affichage du timestamp actuel echo time()." secondes se sont coules depuis le 1er janvier 1970";

Figure 5.1 : Affichage dun timestamp

Lactualisation de la page permet de constater que cette valeur est bien mise jour toutes les secondes.
Timestamp et MySQL

Un timestamp MySQL est diffrent de son homologue PHP. MySQL propose cependant la mthode UNIX_TIMESTAMP() pour obtenir un timestamp compatible PHP.

140 LE GUIDE COMPLET

La notion de timestamp

Chapitre 5

Cration dun timestamp


Lobtention dun timestamp autre que celui courant repose sur le fonction mktime(). Cette fonction prend 6 arguments au format numrique :

1 2 3 4 5 6

heure, minute, seconde, mois, jour, anne.

Le timestamp du 12 janvier 2008 peut tre calcul avec linstruction


mktime(0, 0, 0, 1, 12, 2008).

Une particularit bien pratique de mktime() rside dans sa facult accepter la valeur 0 pour le jour. La valeur retourne reprsente alors le timestamp du dernier jour du mois prcdent. Cette ruse permet de ne pas avoir se proccuper du fait que le mois contienne 28, 29, 30 ou 31 jours.
Listing 5-2 : 2 critures quivalentes pour le 31 janvier 2008 echo mktime(0, 0, 0, 2, 0, 2008)."<br/>"; echo mktime(0, 0, 0, 1, 31, 2008);

Figure 5.2 : Les valeurs sont bien identiques

Un timestamp correspondant une quantit de secondes, lopration consistant ajouter le nombre de secondes dans une journe un timestamp permet dobtenir le timestamp du lendemain.

LE GUIDE COMPLET 141

Chapitre 5

Dates et heures

Listing 5-3 : 2 critures quivalentes pour le 10 octobre 2008 echo mktime(0, 0, 0, 10, 10, 2008)."<br/>"; echo mktime(0, 0, 0, 10, 9, 2008) + (60 * 60 * 24);

Figure 5.3 : Le 10 octobre correspond bien au 9 octobre plus une journe

Conversion
Quelle provienne dun formulaire ou dune base de donnes, un paramtre reprsentant une date sera le plus souvent transmis un script sous la forme dune chane de caractres. Le standard de notation le plus rpandu correspond la notation anglo-saxonne de la forme : yyyy/mm/dd. Le 12 janvier 2008 est not "2008/01/12". Plutt que de passer par un dcoupage fastidieux avec explode(), PHP propose la fonction magique strtotime(). Cette dernire prend en argument une chane de caractres reprsentant la date et retourne le timestamp quivalent.
Listing 5-4 : Utilisation de strtotime() echo "timestamp correspondant au 12 Janvier 2008 : ".strtotime("2008/01/12");

Figure 5.4 : Utilisation de strtotime()

La date peut tre complte avec une dimension horaire en utilisant la reprsentation suivante : "yyyy/mm/dd hh:mm:ss". Minuit et une
142 LE GUIDE COMPLET

La notion de timestamp

Chapitre 5

minute le 12 janvier 2008 est reprsente par la chane "2008/01/12 00:001:00". La fonction strtotime() accepte galement ce format en argument.
Listing 5-5 : Prsence dun horaire echo "timestamp correspondant minuit et une minute le 12 Janvier 2008 : "; echo strtotime("2008/01/12 00:01:00");

Nous constatons que 60 secondes sparent bien le timestamp du "2008/12/01 00:00:00" et celui du "2008/12/01 00:01:00".

Figure 5.5 : 60 secondes de plus

La fonction strtotime() accepte galement des dates formates en anglais courant.


Listing 5-6 : Deux critures quivalentes echo strtotime("2008/03/16")."<br/>"; echo strtotime("16 march 2008")."<br/>";

Plus intressant encore, strtotime() peut interprter certaines expressions complexes telles que :
j j j

"+7 days" : timestamp dans 7 jours, "+1 week" : timestamp dans une semaine, "+6 days 24 hours" : timestamp dans 6 jours et 24 heures.

Listing 5-7 : Utilisation dexpressions complexes avec strtotime() echo strtotime("+7 days")."<br/>"; echo strtotime("+1 week")."<br/>"; echo strtotime("+6 days 24 hours ")."<br/>";

LE GUIDE COMPLET 143

Chapitre 5

Dates et heures

Figure 5.6 : Les 3 expressions sont bien identiques

Comparaison de dates
La reprsentation timestamp est essentielle pour pouvoir raliser une comparaison entre deux dates. Lexemple suivant illustre le danger de comparer directement deux dates de la forme "2008/2/7" et "2008/12/7".
Listing 5-8 : Comparaison directe entre deux dates au format chane de caractres $date1 = "2008/3/7"; $date2 = "2008/12/7"; if ($date1 < $date2) { print("Le ".$date1." prcde le ".$date2); } else { print("Le ".$date1." succde au ".$date2); }

Figure 5.7 : Rsultat erron

PHP indique donc que le 7 mars 2008 succde au 7 dcembre 2008 ! Le code ASCII du caractre 3 (51) tant suprieur celui du caractre

144 LE GUIDE COMPLET

La notion de timestamp

Chapitre 5

1 (49), ce rsultat est par consquent tout fait cohrent du point de

vue logique informatique. Une solution ce problme consiste crire les dates de faons compltes an de comparer le caractre 1 avec 0 (48).
Listing 5-9 : Nouvelle comparaison $date1 = "2008/03/07"; $date2 = "2008/12/07"; if ($date1 < $date2) { print("Le ".$date1." prcde le ".$date2); } else { print("Le ".$date1." succde au ".$date2); }

Figure 5.8 : Rsultat dsormais valide

Cette solution nest cependant pas optimale dans la mesure o nul ne peut garantir que les dates reues au sein du script seront au bon format. La vritable solution consiste comparer non pas des chanes de caractres mais des timestamps.
Listing 5-10 : Comparaison de timestamps $date1 = "2008/3/7"; $date2 = "2008/12/7"; if (strtotime($date1) < strtotime($date2)) { print("Le ".$date1." prcde le ".$date2); } else { print("Le ".$date1." succde au ".$date2); }

LE GUIDE COMPLET 145

Chapitre 5

Dates et heures

Figure 5.9 : Rsultat dsormais valide avec une comparaison de timestamps

5.2. Formatage dune date


La fonction date() permet dobtenir une multitude de reprsentations dun timestamp. Le premier argument de cette fonction correspond un format daffichage et le second un timestamp. Le timestamp actuel est utilis en cas dabsence dun second argument. Le format est une simple chane de caractres pouvant inclure certaines lettres qui seront automatiquement remplaces par une valeur associe. La lettre N par exemple reprsente le numro du jour de la semaine (entre 1 et 7).
Listing 5-11 : Affichage du nom du jour actuel $jours = array("lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"); $numero_jour = date("N"); echo "nous sommes un ".$jours[$numero_jour - 1];

Associe mktime(), la fonction date() permet de savoir quel jour tombait le 1er janvier 2000.
Listing 5-12 : Le 1er janvier 2000 $jours = array("lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"); $ts = mktime(0, 0, 0, 1, 1, 2000); $numero_jour = date("N", $ts); echo "le 1er janvier 2000 tombait un ".$jours[$numero_jour - 1];

Le format peut contenir plusieurs caractres de substitution. Le format "Ymd" permet par exemple dobtenir le trinme anne, mois, jour sans caractre despacement.
146 LE GUIDE COMPLET

Formatage dune date

Chapitre 5

Figure 5.10 : Il sagissait dun samedi

Listing 5-13 : Plusieurs caractres de substitution au sein dun mme format echo date("Ymd"); // affiche 20080311

Les lettres non reconnues (telles que /) au sein du format sont affiches telles quelles.
Listing 5-14 : Le caractre / nest pas substitu echo date("Y/m/d"); // affiche 2008/03/11
Tableau 5.1 : Caractres de substitution

Caractre

Description matine ou aprs midi matin ou aprs midi (majuscule) heure Internet Swatch date au format ISO 8601 jour du mois, sur deux chiffres (ventuellement avec un zro) jour de la semaine, en trois lettres (et en anglais) identiant du fuseau horaire mois, textuel, version longue, en anglais heure, sur 12 heures, sans les zros initiaux heure, sur 24 heures, sans les zros initiaux

Exemple/Valeur

a A B c d

"am" ou "pm" "AM" ou "PM"


De 000 999

"20040212T15:19:21 +00:00" "01" "31"

D e F g G

"Fri" (pour vendredi) "UTC", "GMT" etc. "January" (pour janvier) "1" "12" "0" "23"

LE GUIDE COMPLET 147

Chapitre 5

Dates et heures
Tableau 5.1 : Caractres de substitution

Caractre

Description heure, au format 12 h heure, au format 24 h minutes indique si lheure dt est active jour du mois sans les zros initiaux jour de la semaine en anglais (version longue) indique si lanne est bissextile mois mois, en trois lettres et en anglais mois sans les zros initiaux diffrence dheures avec Greenwich (en heures) format de date RFC 822 secondes suffixe ordinal dun nombre, en anglais, sur deux lettres nombre de jours dans le mois donn fuseau horaire de la machine millisecondes secondes depuis lpoque Unix (1er Janvier 1970) jour de la semaine, numrique numro de la semaine dans lanne

Exemple/Valeur

h H i I (i
majuscule)

"01" "12" "00" "23" "00" "59" "0" ou "1" "1" "31" "Friday" (pour vendredi) "0" ou "1" "01" "12" "Apr" (pour avril) "1" "12" +0200 "Thu, 21 Dec 2000 16:01:07 +0200" "00" "59" "th", "nd" "28" "31" "MET"

j l (L
minuscule)

L m M n O r s S t T u U w W

"0" (dimanche) "6"


(samedi)

"1" "52"

148 LE GUIDE COMPLET

Formatage dune date


Tableau 5.1 : Caractres de substitution

Chapitre 5

Caractre

Description anne quatre chiffres anne deux chiffres jour de lanne dcalage horaire en secondes (dcalage louest est ngatif, lest, positif)

Exemple/Valeur

Y y z Z

"1999" "99" "0" "366" " 43200" "43200"

Echappement de caractres
Les caractres composant le format peuvent tre "chapps" an dempcher la substitution.
Listing 5-15 : Affichage sans chappement echo date("date : c");

Figure 5.11 : Toutes les lettres ont t substitues

Listing 5-16 : Echappement des caractres ne devant pas tre substitus echo date("\d\a\t\e : c");

Figure 5.12 : Les lettres chappes apparaissent (presque) bien

Toutes les lettres chappes apparaissent bien lexception de la lettre t. Ce comportement est cohrent avec le chapitre consacr aux chanes de caractres; la squence \t constitue en effet un caractre spcial au

LE GUIDE COMPLET 149

Chapitre 5

Dates et heures

sein dune chane entre doubles guillemets. La fonction date() ne reoit pas les caractres \ et t mais un caractre de tabulation.

Figure 5.13 : La squence \t est bien substitue par une tabulation

La solution ce problme consiste simplement utiliser la prime pour dnir le format et viter ainsi les substitutions de haut niveau ralises par linterprteur.
Listing 5-17 : Utilisation de la prime echo date(\d\a\t\e : c);

Figure 5.14 : Laffichage est dsormais dle au format

Constantes
Certains formats standard de dates sont prdnis dans le cadre de constantes.
Listing 5-18 : Formats standards proposs par PHP echo "DATE_ATOM ".date(DATE_ATOM)."<br/>"; echo "DATE_COOKIE ".date(DATE_COOKIE)."<br/>"; echo "DATE_ISO8601 ".date(DATE_ISO8601)."<br/>"; echo "DATE_RFC822 ".date(DATE_RFC822)."<br/>"; echo "DATE_RFC850 ".date(DATE_RFC850)."<br/>"; echo "DATE_RFC1036 ".date(DATE_RFC1036)."<br/>"; echo "DATE_RFC1123 ".date(DATE_RFC1123)."<br/>"; echo "DATE_RFC2822 ".date(DATE_RFC2822)."<br/>"; echo "DATE_RFC3339 ".date(DATE_RFC3339)."<br/>"; echo "DATE_RSS ".date(DATE_RSS)."<br/>"; echo "DATE_W3C ".date(DATE_W3C)."<br/>";

150 LE GUIDE COMPLET

Formatage dune date

Chapitre 5

Figure 5.15 : Diffrents formats de date

Ces constantes correspondent trs simplement des chanes de caractres contenant des caractres substituables dans le cadre de la fonction date().
Listing 5-19 : Contenu des constantes echo "DATE_ATOM : ".DATE_ATOM."<br/>"; echo "DATE_COOKIE : ".DATE_COOKIE."<br/>"; echo "DATE_ISO8601 : ".DATE_ISO8601."<br/>"; echo "DATE_RFC822 : ".DATE_RFC822."<br/>"; echo "DATE_RFC850 : ".DATE_RFC850."<br/>"; echo "DATE_RFC1036 : ".DATE_RFC1036."<br/>"; echo "DATE_RFC1123 : ".DATE_RFC1123."<br/>"; echo "DATE_RFC2822 : ".DATE_RFC2822."<br/>"; echo "DATE_RFC3339 : ".DATE_RFC3339."<br/>"; echo "DATE_RSS : ".DATE_RSS."<br/>"; echo "DATE_W3C : ".DATE_W3C."<br/>";

Figure 5.16 : Dtail des formats

LE GUIDE COMPLET 151

Chapitre 5

Dates et heures

5.3. Contrle de validit dune date


Le contrle de validit dune date est un problme courant sur le web dans la mesure o les internautes ont en gnral la possibilit de renseigner directement ce type dinformation. Dtecter que le 2003/12/32 (32 dcembre 2003) est invalide nest pas un problme trs compliqu pour un dveloppeur sachant utilis la fonction explode(). Savoir que le 2007/02/29 (29 fvrier 2007) nexiste pas est en revanche un problme beaucoup plus subtil. La question revient en effet savoir si lanne 2007 est elle bissextile. La premire solution au problme consiste utiliser la fonction
strtotime() pour obtenir un timestamp et ensuite la fonction date()

pour raliser lopration inverse.


Listing 5-20 : Double conversion echo date("Y/m/d", strtotime("2007/02/29"));

Figure 5.17 : 2007/02/29 est converti en 2007/03/01

La fonction strtotime() a automatiquement converti le 29 fvrier 2007 en 1er mars 2007. Une simple comparaison permet ainsi de vrier si la date est valide ou non.
Listing 5-21 : Dfinition dune fonction de vrification de date function verif_date($date) { $s = date("Y/m/d", strtotime($date)); return $date == $s ? 1 : 0; } echo "2007/02/29 : ".verif_date("2007/02/29")."<br/>\n"; echo "2008/02/29 : ".verif_date("2008/02/29")."<br/>\n"; echo "2008/01/34 : ".verif_date("2008/01/34")."<br/>\n";

152 LE GUIDE COMPLET

Check-list

Chapitre 5

Figure 5.18 : Les dates invalides sont bien dtectes

Cette mthode a linconvnient de reposer sur une comparaison de chanes de caractres et expose des erreurs telles que celles vues plus haut. La vritable solution ce problme consiste utiliser la fonction checkdate() dont le rle est prcisment de vrier si une date est valide ou pas. Cette fonction prend trois arguments : le mois, le jour et lanne. La fonction verif_date() peut ainsi tre rcrite de la manire suivante:
Listing 5-22 : Utilisation de la fonction checkdate() function verif_date($date) { list($annee, $mois, $jour) = explode("/", $date); return checkdate($mois, $jour, $annee); }

5.4. Check-list
j j

Le timestamp correspond au nombre de secondes depuis le 1er janvier 1970. Une reprsentation de type timestamp est toujours prfrable pour raliser des oprations au sein dun code.

LE GUIDE COMPLET 153

Les formulaires et transmissions de donnes


Quest-ce quun formulaire ? .......................................................................................... 156 Les diffrents widgets ....................................................................................................... 158 Passer des paramtres un script PHP ...................................................................... 166 Check-list ............................................................................................................................. 181

Chapitre 6

Les formulaires et transmissions de donnes

Nous nous intresserons, dans le cadre de ce chapitre, aux formulaires HTML. Cette notion est absolument primordiale lors du dveloppement dun applicatif sur le Web. Ce sont en effet ces formulaires qui vont permettre aux internautes de vous transmettre des informations. Vous tudierez donc la technique permettant de rcuprer et de traiter au sein dun script PHP des donnes issues dun formulaire. Nous nous arrterons sur tous les types dlments qui peuvent composer de tels formulaires : zones de texte, cases choix multiples, menus droulants, etc.

6.1. Quest-ce quun formulaire ?


Un formulaire peut tre envisag comme un questionnaire permettant aux internautes de transmettre de linformation.

Figure 6.1 : Exemple de formulaire

Figure 6.2 : Formulaire plus complet et stylis

156 LE GUIDE COMPLET

Quest-ce quun formulaire ?

Chapitre 6

Aprs la validation du formulaire, les donnes renseignes par linternaute sont transmises un script cible. Ce dernier peut aussi bien tre crit en PHP quen ASP, en Perl, en Python, etc. Le traitement des donnes au sein du script pourra alors consister en un envoi de courriel, un enregistrement dans une base de donnes, la suppression dun chier, laffichage dune nouvelle page ou toute autre action pouvant tre ralise par le script. Au niveau structurel, un formulaire est compos de champs. Le premier exemple vous propose un formulaire contenant deux champs : nom et prenom. Au niveau HTML, un formulaire se construit ainsi :
j j j

ouverture du formulaire avec la balise <form> ; dnition des champs rattachs ce formulaire (champs textes, menus, cases cocher, etc.) ; fermeture du formulaire avec la balise </form>.

Il est bien sr possible de proposer plusieurs formulaires par page en multipliant les couples <form> </form>.

Figure 6.3 : Deux formulaires

Le code HTML correspondant ce dernier formulaire est le suivant :

LE GUIDE COMPLET 157

Chapitre 6

Les formulaires et transmissions de donnes

Listing 6-1 : deux formulaires sur la mme page <html> <body> <h1>formulaire 1</h1> <form> <label>nom :</label> <input type="text" /><br/> <label>prenom :<label> <input type="text" /><br/> <input type="submit" /> </form> <hr/> <h1>formulaire 2</h1> <form> <label>email :<label> <input type="text" /><br/> <input type="submit" /> </form> </body> </html>

Seuls les lments directement lis un formulaire sont transmis par le bouton Envoyer du formulaire en question. En validant le deuxime formulaire, seul le champ email serait transmis au serveur.

6.2. Les diffrents widgets


Les champs dun formulaire peuvent prendre diffrentes formes. On trouve par exemple des zones de texte, des menus, des cases cocher, etc. En terme technique, ces champs sont appels des widgets. Un widget permet de transmettre une information. Chaque widget possde pour cela un nom auquel est associe une valeur.

Figure 6.4 : Le champ texte

158 LE GUIDE COMPLET

Les diffrents widgets

Chapitre 6

Le code correspondant au champ texte est le suivant :


<input type="text" name="pays" />

Une fois le formulaire valid par linternaute, le script cible reoit une variable pays contenant la valeur Angleterre. Arrtons-nous sur les diffrents widgets qui peuvent composer un formulaire.

INPUT TEXT

Figure 6.5 : Widget text

<input type="text" name="nom" />

Un widget peut tre accompagn dun certain nombre dattributs le plus souvent facultatifs. Lattribut value par exemple vous permet dinitialiser le champ texte une valeur donne.
<input type="text" name="nom" value="Dupont" />

La dimension
Il est possible de forcer la dimension du champ avec lattribut size.
<input type="text" size="50" />

Figure 6.6 : Widget text de taille 50

LE GUIDE COMPLET 159

Chapitre 6

Les formulaires et transmissions de donnes

La taille maximale
Lattribut maxlength permet de limiter le nombre de caractres qui peuvent tre renseigns.
<input type="text" maxlength="4" />

Figure 6.7 : Avec une taille maximale de 4, il est impossible de taper "angleterre"

Cet attribut peut tre intressant pour interdire par exemple des identiants de plus de n caractres.

La lecture seule
Lattribut readonly permet dinterdire la modication du contenu du widget.
<input type="text" value="donne protge" readonly="true" />

Cette proprit est disponible pour lensemble des widgets prsents ci-aprs.

Le mot de passe : password


Quand vous souhaitez faire taper un mot de passe un internaute, il vaut mieux prfrer le type password au type text car les donnes tapes napparaissent pas en clair.
<input type="password" name="motdepasse" />

Figure 6.8 : Avec le type "password", les donnes sont caches

160 LE GUIDE COMPLET

Les diffrents widgets

Chapitre 6

XHTML

En HTML standard, les deux lignes suivantes sont quivalentes :


<input type="text"> <input type=text>

Cependant, la premire est compatible avec le format XHTML qui risque de devenir le nouveau standard du Web. Il peut donc tre bon, ds maintenant, de prendre de bonnes habitudes. Une autre obligation du XHTML est de fermer les balises orphelines :
<br /> <img src="pict.gif" /> <input type="text" />

Cela ne demande pas beaucoup de travail, ne change rien lapparence de votre site et vous assure une compatibilit avec les futurs navigateurs.

TEXTAREA
<textarea name="nom"></texarea>

Le widget textarea correspond une zone de texte multiligne. Les donnes transmises par ce champ sont contenues entre les deux balises : <textarea> et </textarea>.
<textarea name="test">ligne 1 ligne 2 </textarea>

Figure 6.9 : Textarea

Les attributs rows et cols


Le premier permet de xer le nombre de lignes et le second le nombre de colonnes. Voici un textarea de 8 lignes sur 50 colonnes.
<textarea name="test" rows="8" cols="50"></textarea>

LE GUIDE COMPLET 161

Chapitre 6

Les formulaires et transmissions de donnes

Lattribut wrap
Lattribut wrap permet de dnir le comportement dun textarea lorsquune phrase est trop longue pour tenir en entier dans le widget.
j j

Avec wrap="off", un ascenseur horizontal apparat et il est ncessaire de le faire dler pour voir la n de la phrase. Avec wrap="soft", la phrase tient sur plusieurs lignes.

Figure 6.10 : Textarea avec et sans wrap

SELECT
<select name="test"> <option value="1">-- premier choix --</option> <option value="2">-- deuxime choix --</option> </select>

Figure 6.11 : Le menu droulant

162 LE GUIDE COMPLET

Les diffrents widgets

Chapitre 6

Le widget select permet de construire des menus droulants. Le nom de la donne est contenu dans la balise <select> et la valeur dans <option>. Seule la valeur slectionne sera transmise.

La prslection
Il est possible dinitialiser le menu sur un autre choix que le premier. Il faut alors ajouter le mot-cl selected dans loption souhaite :
<select name="test"> <option value="1">-- premier choix --</option> <option value="2" selected="true">-- deuxime choix --</option> </select>

Figure 6.12 : Le menu est initialis sur le deuxime choix

Le menu choix multiples


Le mot-cl multiple permet de transformer le menu droulant en menu choix multiples. Lattribut associ size permet de dnir la hauteur du select.
<select name="test[]" <option value="1">-<option value="2">-<option value="3">-</select> multiple="true" size="3"> premier choix --</option> deuxime choix --</option> troisime choix --</option>

Figure 6.13 : Menu choix multiple

LE GUIDE COMPLET 163

Chapitre 6

Les formulaires et transmissions de donnes

La encore il est possible dutiliser selected pour prslectionner plusieurs valeurs.

INPUT CHECKBOX
<input type="checkbox" name="nom" value="val" />

Ce widget permet de raliser des cases choix multiples.


choix 1 <input type="checkbox" name="choix[]" value="1" /> choix 2 <input type="checkbox" name="choix[]" value="2" /> choix 3 <input type="checkbox" name="choix[]" value="3" />

Figure 6.14 : Les cases cocher

Seules les valeurs des cases coches seront transmises. Il est possible dinitialiser la case avec le mot-cl checked.
choix 1 <input type="checkbox" name="choix[]" value="1" /> choix 2 <input type="checkbox" name="choix[]" value="2" checked="true" /> choix 3 <input type="checkbox" name="choix[]" value="3" />

INPUT RADIO
<input type="checkbox" name="nom" value="val" />

la diffrence des checkboxes, les cases de lattribut input radio sont choix unique :
choix 1 <input type="radio" name="choix[]" value="1" /> choix 2 <input type="radio" name="choix[]" value="2" /> choix 3 <input type="radio" name="choix[]" value="3" />

164 LE GUIDE COMPLET

Les diffrents widgets

Chapitre 6

Figure 6.15 : Les boutons radios

Pour en faire des cases choix unique, il convient de faire attention bien spcier le mme nom pour tous les attributs input. Avec des noms diffrents, il devient possible de toutes les slectionner.
choix 1 <input type="radio" name="choix1" value="1" /> choix 2 <input type="radio" name="choix2" value="2" /> choix 3 <input type="radio" name="choix3" value="3" />

Figure 6.16 : Des attributs input avec des noms diffrents ne sexcluent pas

Le mot-cl checked est aussi valide avec ce widget.

INPUT BUTTON
<input type="button" name="nom" value="val" />

Il sagit du widget "bouton". Lintitul du bouton est contenu dans value :


<input type="button" name="test" value="ceci est un bouton" />

LE GUIDE COMPLET 165

Chapitre 6

Les formulaires et transmissions de donnes

Figure 6.17 : Le bouton

Il existe deux boutons spciaux.


j

submit : cest en cliquant sur un bouton de ce type que vous

dclenchez lenvoi du formulaire.


<input type="submit" value="envoyer le formulaire" />
j

reset : ce bouton permet deffacer toutes les informations contenues dans le formulaire.
<input type="reset" value="effacer les informations" />

Une image comme bouton denvoi

Il est possible de remplacer un bouton submit par une image. La syntaxe est alors :
<input type="image" src="image.gif" />.

INPUT HIDDEN
<input type="hidden" name="nom" value="val" />

Il sagit dun widget invisible. Lintrt, me demanderez-vous ? Stocker une information que vous voulez transmettre avec le formulaire, mais qui na pas lieu dtre prsente linternaute.

6.3. Passer des paramtres un script PHP


Maintenant que vous tes en mesure de construire vos propres formulaires, dcouvrez les diffrents moyens de transmettre ces informations un script PHP qui pourra alors les traiter.
166 LE GUIDE COMPLET

Passer des paramtres un script PHP

Chapitre 6

La variable $_GET
La balise <form> dispose galement dun certain nombre dattributs optionnels. Le premier que vous allez tudier est action. Il permet de prciser quel script sera appel une fois le bouton submit du formulaire valid. Si vous souhaitez transmettre les informations du formulaire au script
script.php, vous devez crire :
<form action="script.php">

form sans action

Si vous ne prcisez pas la proprit action, le formulaire senvoie les informations lui-mme. Vous verrez plus loin quil peut tre intressant de regrouper la fois le formulaire et le traitement du formulaire au sein dun mme chier.

Un script situ sur un autre site peut galement tre appel via cet attribut action. Lexemple suivant appelle le moteur de recherche Google en lui transmettant le mot-cl correspondant votre recherche :
Listing 6-2 : Appel direct du moteur de recherche Google <form action="http://www.google.fr/search"> <input type="text" name="q" /> <input type="submit" value="nouvelle recherche" /> </form>

Figure 6.18 : Formulaire permettant dappeler le moteur de recherche

Google

LE GUIDE COMPLET 167

Chapitre 6

Les formulaires et transmissions de donnes

En validant le formulaire avec le mot-cl "PHP", vous basculez sur le site de Google et vous obtenez le rsultat de la recherche :

Figure 6.19 : Rsultat de la recherche

Utilisation de ressources

Le Web est de plus en plus rglement. Les grandes heures dInternet libre sont derrire nous. Le fait dutiliser des ressources dun autre serveur, comme vous venez de le faire, nest pas toujours trs apprci.

Crez maintenant deux chiers en y plaant un formulaire (form.html) et un script PHP (script.php) et faites pointer le formulaire sur le script :
Listing 6-3 : form.html <form action="script.php"> <input type="text" name="x" /> <input type="submit" value="envoyer" /> </form> Listing 6-4 : script.php <?php print("valeur de x : "); ?>

En validant votre formulaire, le script affiche le message "bonjour monde". Cest certes sympathique, mais vous ne prenez pas en compte linformation qui a t transmise. PHP rend la rcupration des paramtres transmis extrmement simple. Le principe consiste passer par la variable prdnie $_GET qui contient un tableau associatif dont chaque mot-cl correspond au nom

168 LE GUIDE COMPLET

Passer des paramtres un script PHP

Chapitre 6

(attribut name) du widget. Dans le cas prsent, $_GET[x] contient la valeur de votre champ texte.
Listing 6-5 : votre script affiche maintenant la valeur qui lui a t transmise print("valeur de x : "+$_GET[x]);

La variable $_GET est dun type particulier qui lui permet dtre directement accessible au sein de fonctions sans passer par global. Le terme utilis pour la qualier est super-global .
Listing 6-6 : script.php <?php function affiche_param() { print("valeur de x : "+$_GET[x]); } affiche_param(); ?>

Le principe est le mme, quil y ait un ou plusieurs champs et quel que soit le type du champ. Ralisez un formulaire plus complexe permettant de travailler avec diffrents widgets :
Listing 6-7 : un formulaire plus complet <html> <body> <form action="script.php"> <label>Titre du film</label> <input type="text" name="titre" /><br/> <label>Genre</label> <select name="genre"> <option value="policier">POLICIER</option> <option value="sf">SCIENCE FICTION</option> </select><br/> <label>Description</label> <textarea name="description"></textarea><br/> <label>Film en couleur</label> <input type="radio" name="couleur" value="1" /> oui <input type="radio" name="couleur" value="non" /> non <br/>

LE GUIDE COMPLET 169

Chapitre 6

Les formulaires et transmissions de donnes

<br/> <input type="submit" value="envoyer" /> </form> </body> </html>

Figure 6.20 : Formulaire complet

Modiez le script script.php an dafficher toutes les donnes transmises par votre formulaire :
Listing 6-8 : script.php <?php print("<b>Titre</b> : ".$_GET[titre]."<br/>"); print("<b>Genre</b> : ".$_GET[genre]."<br/>"); print("<b>Description</b> : ".$_GET[description]."<br/>"); print("<b>Couleur ?</b> : ".$_GET[couleur]."<br/>"); ?>

Figure 6.21 : Affichage des donnes

170 LE GUIDE COMPLET

Passer des paramtres un script PHP

Chapitre 6

Ouverture dans une autre fentre

Il est possible en HTML douvrir un lien dans une autre fentre avec lattribut target :
<a href="http://www.google.fr" target="_blank">google</a>.

Cela fonctionne de la mme manire avec les formulaires :


<form action="script.php" target="_blank">.

Votre formulaire nest compos pour linstant que de widgets choix unique. Vous avez cependant pu lire plus haut quil existe des widgets permettant de slectionner plusieurs valeurs : les attributs multilignes checkbox et select. Lassociation une variable/plusieurs valeurs vous conduit naturellement aux tableaux ! La technique permettant dindiquer PHP dinitialiser un tableau plutt quune variable simple consiste mettre des crochets au sein de lattribut name : vous crirez name="val[]" plutt que name="val". Modiez form.html an dy intgrer des widgets choix multiples.
Listing 6-9 : formulaire avec des champs choix multiples <html> <body> <form action="script.php"> <label>Titre du film</label> <input type="text" name="titre" /><br/> <label>Genre</label> <select name="genre[]"multiple="yes" size="3"> <option value="policier">POLICIER</option> <option value="sf">SCIENCE FICTION</option> <option value="culte">CULTE</option> </select><br/> <label>Description</label> <textarea name="description"></textarea><br/> <label>Film en couleur</label> <input type="radio" name="couleur" value="1" /> oui <input type="radio" name="couleur" value="non" /> non <br/>

LE GUIDE COMPLET 171

Chapitre 6

Les formulaires et transmissions de donnes

<label>Pays</label> <select name="pays"> <option value="fr">FRANCE</option> <option value="us">USA</option> <option value="gb">ANGLETERRE</option> </select><br/> <label>Sous titre</label> <input type="checkbox" name="soustitre[]" value="fr" /> franais <input type="checkbox" name="soustitre[]" value="gb" /> anglais <input type="checkbox" name="soustitre[]" value="es" /> espagnol <br/> <br/> <input type="submit" value="envoyer" /> </form> </body> </html>

Figure 6.22 : Formulaire avec des champs choix multiples

Affichez le contenu de la variable $_GET an de comprendre comment PHP organise la rception des donnes. Utilisez pour cela la fonction print_r() qui, comme vous lavez vu prcdemment, permet dafficher le contenu dun tableau.

172 LE GUIDE COMPLET

Passer des paramtres un script PHP


Listing 6-10 : affichage de $_GET <pre> <?php print_r($_GET); ?> </pre>

Chapitre 6

Figure 6.23 : Contenu de la variable $_GET

Le texte plac entre les balises <pre> et </pre> est affich en tant que texte brut. Cela permet, dans le cadre de la fonction print_r(), de conserver les sauts de ligne et lindentation.

Balise <pre>

Vous obtenez la conrmation que les lments $_GET[genre] et $_GET[soustitre] contiennent bien des tableaux. Il convient donc de trouver un moyen de les afficher au sein de votre script script.php. La fonction join() qui convertit un tableau en chane de caractres pourrait tout fait convenir. Rappelons en effet son utilisation laide dun exemple :

LE GUIDE COMPLET 173

Chapitre 6

Les formulaires et transmissions de donnes

$ar = array(a,b,c); $str = join(,,$ar); print($str);

Ce morceau de code affichera : a,b,c. Votre script devient donc :


Listing 6-11 : affichage des champs multivaleurs <?php print("<b>Titre</b> : ".$_GET[titre]."<br/>"); $str_genre = join(,,$_GET[genre]); print("<b>Genre</b> : ".$str_genre."<br/>"); print("<b>Description</b> : ".$_GET[description]."<br/>"); print("<b>Couleur</b> : ".$_GET[couleur]."<br/>"); print("<b>Pays</b> : ".$_GET[pays]."<br/>"); $str_soustitre = join(,,$_GET[soustitre]); print("<b>Sous titres</b> : ".$str_soustitre."<br/>"); ?>

Figure 6.24 : Affichage des valeurs

Query String
Arrtons-nous un instant sur ladresse (URL) affiche en haut du navigateur dans la barre de navigation :
Figure 6.25 : Affichage dune URL

174 LE GUIDE COMPLET

Passer des paramtres un script PHP

Chapitre 6

Vous constatez que le formulaire appelle bien script.php et quil lui transmet en plus une longue chane de caractres assez trange :
http://localhost/script.php?titre=Blade+runner&genre 5B%5D=sf&genre%5B%5D=culte&description=Excellent &couleur=1&pays=us&soustitre%5B%5D=fr&soustitre %5B%5D=gb&soustitre5B5D=es.

La caractristique principale de la mthode GET est prcisment de transmettre les paramtres du formulaire au sein mme de lURL. Cette chane de paramtres (dont le nom technique est Query String) est spare du nom du script par le caractre ?. Le codage permettant de la composer se rvle assez facile :
nom1=valeur1&nom2=valeur2&nom3=valeur3nomN=valeurN

o nom correspond lattribut name du widget et valeur correspond la valeur renseigne, slectionne ou coche par linternaute. LURL suivante conrme la chose car vous y trouvez bien
description=Excellent. En revanche, le caractre + dans titre=Blade+runner montre que les valeurs subissent elles-mmes

un autre codage. Il sagit de lURL dencodage qui transforme par exemple les espaces en signes +, les crochets ([) en %5B, les signes = en %3D, les en %E9, etc. La fonction PHP urlencode() se charge de cette opration fastidieuse en retournant une chane urlencode partir dune chane en clair .
$str = urlencode("a = & 123"); // $str contient a+%3D+%E9+%26+123

URL encodage de lattribut

la fois les noms et les valeurs doivent tre encods dans lURL !

Vous comprenez quil est maintenant possible de transmettre des donnes votre script sans passer par le formulaire. Imaginez que vous vouliez transmettre le lm suivant :
Tableau 6.1 : Film Manhattan

Caractristiques Titre

Valeur

Manhattan

LE GUIDE COMPLET 175

Chapitre 6

Les formulaires et transmissions de donnes


Tableau 6.1 : Film Manhattan

Caractristiques Genre Description Couleur Pays Sous titres

Valeur

culte magnifique 0 us fr, gb

crivez maintenant le script url.php charg de construire un lien permettant de transmettre script.php les donnes lies au lm Manhattan.
Listing 6-12 : transmission de donnes au sein de lURL <?php $url $url $url $url $url $url $url $url = http://localhost/script.php?; .= urlencode("titre").=.urlencode("Manhattan").&; .= urlencode("genre[]").=.urlencode("culte").&; .= urlencode("description").=.urlencode("magnifique").&; .= urlencode("couleur").=.urlencode("0").&; .= urlencode("pays").=.urlencode("us").&; .= urlencode("soustitre[]").=.urlencode("fr").&; .= urlencode("soustitre[]").=.urlencode("gb");

print("<a href=".$url.">Film Manhattan</a>"); ?>

Figure 6.26 : La barre dtat montre que lURL a bien t construite

Cliquez maintenant sur le lien, et vous obtenez le lm attendu :

176 LE GUIDE COMPLET

Passer des paramtres un script PHP

Chapitre 6

Figure 6.27 : Affichage des rsultats

Transmission simple

href="fichier.php?x=2&y=toto">transmission simple</a>.

Si les noms et les valeurs transmettre ne contiennent que des caractres alphanumriques, ltape dencodage URL devient supercielle. Pour x = 2 et y = "toto", le lien suivant peut directement tre crit : <a

Ce type de transmission par URL se rvle trs pratique en programmation web car elle vite de mettre systmatiquement en uvre un formulaire pour transmettre une donne.

La mthode POST
La mthode GET entrane donc laffichage en clair dans la barre de navigation des donnes renseignes par linternaute. Vous comprenez donc la limitation dune telle mthode dans le cas de la transmission dun mot de passe.
Listing 6-13 : formulaire didentification <form action="auth.php"> <label>identifiant</label> <input type="text" name="id" /><br/> <label>mot de passe</label> <input type="password" name="pass" /><br/>

LE GUIDE COMPLET 177

Chapitre 6

Les formulaires et transmissions de donnes

<br/><input type="submit" value="identification"> </form>

Figure 6.28 : Formulaire didentication disposant dun widget password

Listing 6-14 : auth.php <?php print("<b>Identifiant</b> : ".$_GET[id]."<br/>"); print("<b>Mot de passe</b> : ".$_GET[pass]."<br/>"); ?>

En validant le bouton didentication, vous basculez sur le script auth.php et vous aurez la surprise de voir dans la barre de navigation votre mot de passe en clair !

Figure 6.29 : Il faut esprer quun collgue mal intentionn ne se trouve pas

derrire !

Heureusement, les formulaires peuvent galement tre envoys avec la mthode POST !

178 LE GUIDE COMPLET

Passer des paramtres un script PHP


Listing 6-15 : Le formulaire utilise dsormais la mthode post <form action="auth.php" method="post"> <label>identifiant</label> <input type="text" name="id" /><br/> <label>mot de passe</label> <input type="password" name="pass" /><br/> <br/><input type="submit" value="identification"> </form>

Chapitre 6

En termes fonctionnels, cela ne change presque rien pour vous : la variable $_POST est utilise plutt que la variable $_GET.
<?php print("<b>Identifiant</b> : ".$_POST[id]."<br/>"); print("<b>Mot de passe</b> : ".$_POST[pass]."<br/>"); ?>

En revanche, les paramtres transmis napparaissent plus dans la barre de navigation.

Figure 6.30 : Le mot de passe napparat plus dans la barre de navigation

Comment choisir entre POST et GET

La mthode POST peut tre prfre la mthode GET lorsque vous devez transmettre une quantit importante de donnes (plusieurs mgaoctets). Inversement, il est conseill de lviter si linternaute est susceptible de revenir en arrire en utilisant licne de retour (back). Vous risquez en effet dans ce cas dtre confront des problmatiques de cache et de timeout.

LE GUIDE COMPLET 179

Chapitre 6

Les formulaires et transmissions de donnes

Plus gnralement, la mthode POST est conseille lorsque le script de destination modie une donne et que le rafraichissement de la page et la mise en cache de la requte ne sont pas souhaits. Il est donc recommand de mettre jour un enregistrement dune base de donnes en POST et de raliser une recherche avec la mthode GET.

Vous constatez quun changement de mthode (POST, GET) au niveau de la balise <form> entrane une modication du script. La variable $_REQUEST permet dviter cela dans la mesure o elle contient la fois les variables transmises en POST, les variables transmises en GET ainsi que les cookies (que vous tudierez plus loin). Vous ferez donc le choix dans le reste de louvrage de passer par cette variable.

Le mode register_globals on
Pour les versions plus anciennes de PHP, la rcupration des variables tait encore plus simple. Des variables portant le nom des widgets taient automatiquement initialises. Vous auriez crit script.php de la manire suivante :
Listing 6-16 : ancienne mthode pour rcuprer les paramtres <?php print("<b>Titre</b> : ".$titre."<br/>"); $str_genre = join(,,$genre[]); print("<b>Genre</b> : ".$str_genre."<br/>"); print("<b>Description</b> : ".$description."<br/>"); print("<b>Couleur</b> : ".$couleur."<br/>"); print("<b>Pays</b> : ".$pays."<br/>"); $str_soustitre = join(,,$soustitre[]); print("<b>Sous titres</b> : ".$str_soustitre."<br/>"); ?>

Il est encore possible dutiliser cette faon doprer en initialisant on la directive de conguration register_globals. Nous vous le dconseillons cependant vivement an de limiter au maximum les failles de scurit que cela entrane bien souvent.

180 LE GUIDE COMPLET

Check-list

Chapitre 6

La fonction ini_get()

La fonction ini_get() vous permet de rcuprer la valeur dune directive de conguration PHP et ainsi de savoir si vous tes en register_globals on ou off :
<?php if (ini_get("register_globals")==1) { print("Vous tes en register_globals=on"); } else { print("Vous tes en register_globals=off"); } ?>

6.4. Check-list
j j j j j

j j

Les formulaires permettent de rcuprer de linformation auprs des internautes et de les transmettre un script PHP cible. Seuls les champs situs entre <form> et </form> sont transmis au moment de la validation du formulaire. Lattribut action du FORM permet de spcier lemplacement du script cible. Deux modes de transmission sont possibles pour les formulaires : GET et POST. Le mode est prcis laide de lattribut method. Un formulaire est compos dun certain nombre de champs. Ces derniers peuvent prendre diffrentes formes : champ texte, champ texte multiligne, menu droulant, cases cocher, etc. Des paramtres peuvent galement tre transmis directement dans lURL. On parle alors de Query String. Au sein du script, les paramtres peuvent tre rcuprs avec la variable $_REQUEST[].

LE GUIDE COMPLET 181

En tte HTTP et authentication


Requtes et rponses ....................................................................................................... 184 Fonction header() ............................................................................................................... 188 Page derreur ...................................................................................................................... 190 Authentification ................................................................................................................... 192 En bref .................................................................................................................................. 196

Chapitre 7

En tte HTTP et authentification

Le web repose sur le protocole HTTP. Ce dernier permet un navigateur comme Firefox de communiquer avec un serveur tel quApache. Cet change est bien videmment norm et codi. Ce chapitre vise mieux apprhender ces changes et dmontrer quune bonne connaissance de ce protocole permet de tirer partie de fonctionnalits avances du couple navigateur/serveur.

7.1. Requtes et rponses


La demande faite par un navigateur un serveur web est appele une requte (HTTP Request). Une requte typique consiste demander le contenu dun page ou dune image. Suite cette requte, le serveur retourne une rponse (HTTP Response). Requtes et rponses sont composes dune multitude dinstructions formant une en tte.

Extension LiveHTTPHeaders
Lextension de Firefox LiveHTTPHeaders permet de visualiser prcisment les changes HTTP entre un client et un serveur. Elle peut tre tlcharge gratuitement sur le site http://livehttpheaders.mozdev.org. en utilisant les liens Installation puis Install version 0.X of LiveHTTPHeaders now. Firefox vous propose alors dajouter ce site sa liste de sites auxquels il peut faire conance.

Figure 7.1 : Utilisez le bouton "Modier les options"

Figure 7.2 : Utilisez le bouton "Autoriser"

184 LE GUIDE COMPLET

Requtes et rponses

Chapitre 7

Une fois ce domaine ajout cliquez nouveau sur le lien Install version 0.XX of LiveHTTPHeaders now pour installer vritablement lextension.

Figure 7.3 : Utilisez le bouton "Installer" une fois le dcompte termin

Le navigateur doit ensuite tre ferm puis rouvert pour prendre en compte cette nouvelle extension. La premire utilisation de cet outil va permettre despionner lchange suivant : le navigateur appelle lURL http://localhost/test.php, et le serveur retourne le rsultat de linterprtation du script suivant :
<?php print("ok"); ?>

Lextension peut tre lance en passant par le menu Outils / En ttes


HTTP en direct.

Figure 7.4 : Visualisation dun change requte / rponse

LE GUIDE COMPLET 185

Chapitre 7

En tte HTTP et authentification

La requte
Trois catgories de donnes sont incluses dans len tte de la requte :
j

des informations sur la page cible et la version du protocole


GET /test.php HTTP/1.1 Host: localhost

des prcisions sur le navigateur


User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1 Accept: text/xml,application/xml,application/xhtml+xml, text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

le type de la connexion
Keep-Alive: 300 Connection: keep-alive

Ces informations peuvent tre rcupres au sein du script laide de la fonction getallheaders() qui retourne un tableau contenant lensemble des informations prsentes dans len-tte. Ces informations permettent au script dajuster son comportement en fonction :
j j j

du type du navigateur (UserAgent), des formats des chiers accepts (Accept), de la langue (AcceptLanguage).

Lexemple suivant affiche un message de reconnaissance de votre navigateur.


Listing 7-1 : Dtection du navigateur $header = getallheaders(); if (strpos($header["User-Agent"], "Firefox") > 0) { print("Vous utilisez Firefox"); } elseif (strpos($header["User-Agent"],"MSIE") > 0) { print("Vous utilisez Internet Explorer"); }

186 LE GUIDE COMPLET

Requtes et rponses
else { print("Navigateur non reconnu"); }

Chapitre 7

print("<br/><br/><i>".$header["User-Agent"]."</i>");

Figure 7.5 : Dtection de Firefox

Figure 7.6 : Dtection dInternet Explorer

La rponse
Len-tte de la rponse donne des informations sur :
j

le code rponse,
HTTP/1.x 200 OK

le serveur distant,
Date: Mon, 10 Apr 2006 04:58:32 GMT Server: Apache/2.0.55 (Win32) PHP/5.1.2 X-Powered-By: PHP/5.1.2

le contenu,
Content-Length: 2 Content-Type: text/html

la connexion,
Keep-Alive: timeout=15, max=100 Connection: Keep-Alive

LE GUIDE COMPLET 187

Chapitre 7

En tte HTTP et authentification

Le contenu proprement parler fait suite len-tte dans le message de rponse retourn par le serveur web. La fonction apache_response_headers() retourne un tableau associatif contenant tous les lments de len-tte de rponse.

7.2. Fonction header()


PHP permet de modier len tte de la rponse laide de la fonction header(). Lemplacement de cette fonction au sein dun script est extrmement important : la fonction header() doit absolument tre place avant le premier affichage de la page. Les deux scripts suivants affichent le message Bonjour avant de faire appel header(). Ils provoquent par consquent laffichage dune erreur.
Listing 7-2 : Affichage provoquant une erreur Bonjour <?php header("Text: coucou"); ?> Listing 7-3 : Autre syntaxe provoquant une erreur <?php print("Bonjour"); header("Text: coucou"); ?>

Figure 7.7 : Erreur gnre suite un mauvais placement de la fonction

header()

188 LE GUIDE COMPLET

Fonction header()

Chapitre 7

Prudence

Un simple retour la ligne ou un espace situ avant la balise <?php conduiraient galement une erreur ! La fonction header() impose une grande prcision.

En dplaant laffichage derrire la fonction header(), lerreur disparat et vous constatez que len-tte a bien t mise jour.
Listing 7-4 : Exemple valide <?php header("Text: coucou"); print("Bonjour"); ?>

Figure 7.8 : Len tte a bien t modie

Il est galement possible de modier le contenu des instructions en les crasant (voir Figure 7.9) :
Listing 7-5 : Modification de linstruction X-Powered-By <?php print("Bonjour"); header("X-Powered-By: PHP/8 !!!"); ?>

Plus utile, la fonction header() permet galement de donner des instructions telle quune demande de redirection avec linstruction Location.
Listing 7-6 : Demande de redirection vers une autre page <?php header("Location: http://www.google.com"); ?>
LE GUIDE COMPLET 189

Chapitre 7

En tte HTTP et authentification

Figure 7.9 : Modication de linstruction X-Powered-By

7.3. Page derreur


Le code retour 200 prsent dans len tte de rponse (HTTP/1.x 200 OK) signie que le navigateur na rencontr aucun problme pour traiter la requte. En ralisant une requte sur une page nexistant pas sur le serveur, le code derreur passe 404.

Figure 7.10 : Page derreur affiche par le client

Figure 7.11 : En tte derreur

190 LE GUIDE COMPLET

Page derreur

Chapitre 7

Le protocole HTTP prvoit un certain nombre de codes derreur tous commenant par 4xx.
Tableau 7.1 : Codes derreur client

Code derreur

Signication Erreur de syntaxe dans ladresse du document Pas dautorisation daccs au document Accs au document soumis au paiement Pas dautorisation daccs au serveur La page demande nexiste pas Mthode de requte du formulaire non autorise Requte non accepte par le serveur Autorisation du proxy ncessaire Temps daccs la page demande expir Lutilisateur doit soumettre nouveau avec plus dinfos Cette ressource nest plus disponible Le serveur a refus la requte car elle na pas de longueur La pr condition donne dans la requte a chou Lentit de la requte tait trop grande LURI de la requte tait trop longue Type de mdia non gr

400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415

Vous pouvez vous-mme dclencher les erreurs que vous souhaitez en retournant la valeur du code derreur avec la fonction header(). Lexemple suivant indique que la page nexiste pas uniquement aux visiteurs utilisant Firefox :
Listing 7-7 : Dtection du navigateur en PHP $header = getallheaders(); if (strpos($header["User-Agent"], "Firefox") > 0) { header("HTTP/1.0 404 Not Found"); print("La page nexiste pas"); } else print("Hello IE");

LE GUIDE COMPLET 191

Chapitre 7

En tte HTTP et authentification

Figure 7.12 : La page sans erreur avec Internet Explorer

Figure 7.13 : Lutilisation de Firefox en revanche dclenche lapparition dun message derreur

Figure 7.14 : Len tte indique bien que la page nexiste pas

7.4. Authentication
Le protocole HTTP inclut une gestion dauthentication. Cette authentication met en uvre le code retour 401. En recevant ce code retour le navigateur sait quil doit ouvrir une petite fentre an de permettre lutilisateur de renseigner son identiant et son mot de passe. En plus du code derreur, le serveur doit galement prciser le nom de lespace (realm) protger avec linstruction WWWAuthenticate. Une demande dauthentication peut donc tre code de la manire suivante :

192 LE GUIDE COMPLET

Authentification

Chapitre 7

Listing 7-8 : Demande dauthentification header(WWW-Authenticate: Basic realm="Zone protge"); header("HTTP/1.0 401 Unauthorized");

Figure 7.15 : Firefox propose de vous authentier dans la "zone protge"

Une fois le bouton OK valid, Firefox transmet une requte contenant vos informations dindentication. Cela se traduit par lajout au sein de len tte dune instruction Authorization correspondant lencodage en base 64 de votre identiant suivi de votre mot de passe :
identifiant:mot de passe

Vous pouvez vrier quil sagit bien dun encodage en base 64 en utilisant la fonction base64_decode() sur la valeur associe Authorization.
Listing 7-9 : Cette instruction affiche bien la chane "test:test" echo base64_decode("dGVzdDp 0ZXN0");

Figure 7.16 : Transmission encode de votre identiant et de votre mot de passe

LE GUIDE COMPLET 193

Chapitre 7

En tte HTTP et authentification

Syntaxe

Veillez bien utiliser un B majuscule pour Basic et des doubles guillemets pour entourer la valeur associe realm. Dans le cas contraire des problmatiques dincompatibilit avec les navigateurs pourraient survenir.

Ltape suivante consiste pouvoir vrier si lauthentication sest bien droule. Les donnes dont vous disposez pour raliser cette authentication sont contenues dans la variable super globale $_SERVER. Cette variable contient un certain nombre dinformations sur la requte, le script appel et le serveur web. Une liste de tous les lments de $_SERVER est disponible en Annexe. Dans le cas dune authentication, $_SERVER dispose de deux lments en plus, $_SERVER["PHP_AUTH_USER"] et $_SERVER["PHP_AUTH _PW"] qui contiennent respectivement les valeurs que vous avez prcises pour lidentiant et le mot de passe. Le principe consiste maintenant utiliser ces deux valeurs pour vrier si elles sont correctes. Deux cas apparaissent alors : j la vrication a chou et vous proposez nouveau la demande dauthentication, j la vrication a russi et la suite du script est propose.
Listing 7-10 : Script dauthentification if ($_SERVER["PHP_AUTH_USER"]!="test" || $_SERVER["PHP_AUTH_PW"]!="test") { header(WWW-Authenticate: Basic realm="Zone protge"); header("HTTP/1.0 401 Unauthorized"); exit(0); } print("Bienvenue dans la zone scurise");

Figure 7.17 : Message affich en cas de succs

194 LE GUIDE COMPLET

Authentification

Chapitre 7

En cas de succs les diffrentes requtes ralises avec la mme fentre de navigateur contiendront linstruction Authorization. Libre vous de vrier pour toutes les pages du site que linternaute est authenti (en utilisant $_SERVER["PHP_AUTH_USER"] et $_SERVER["PHP _AUTH_PW"]). Il sagit dailleurs dune manire classique de protger lensemble des scripts dun site.

Figure 7.18 : La requte sur le script test2.php contient bien notre indentication

Un internaute ne parvenant pas sauthentier peut tout moment cliquer sur le bouton Annuler et obtenir un message daide. Ce dernier doit suivre lenvoi du code derreur 401.
Listing 7-11 : Prcision dun message daide header(WWW-Authenticate: Basic realm="Zone protge"); header("HTTP/1.0 401 Unauthorized"); print("Veuillez contacter votre administrateur systme "); print("pour obtenir vos identifiants.");

Figure 7.19 : Message obtenu en cliquant sur Annuler

Linternaute reste identi tant que la fentre est ouverte. Une porte de sortie doit donc tre prvue pour lui permettre de se dconnecter. La technique pour y parvenir consiste renvoyer un code derreur 401.
LE GUIDE COMPLET 195

Chapitre 7

En tte HTTP et authentification

Lexemple suivant propose un lien vers un script quitter.php charg de raliser cette dconnexion.
Listing 7-12 : test.php <?php if ($_SERVER["PHP_AUTH_USER"]!="test" || $_SERVER["PHP_AUTH_PW"]!="test") { header(WWW-Authenticate: Basic realm="Zone protge"); header("HTTP/1.0 401 Unauthorized"); exit (0); } print("Bienvenue dans la zone scurise<br/><br/>"); print("<a href=quitter.php>quitter lapplication</a>"); ?> Listing 7-13 : quitter.php <?php header(WWW-Authenticate: Basic realm="Zone protge"); header("HTTP/1.0 401 Unauthorized"); ?>

Une fois identi, cliquez sur le lien pour basculer sur quitter.php et constater que la fentre dauthentication est bien propose. Modiez maintenant lurl dans la barre de navigation an dindiquer http:// localhost/test.php. Vous constatez nouveau que la dconnexion a bien fonctionn.

7.5. En bref
j j j

PHP permet de rcuprer et de modier les informations lies aux en-ttes HTTP. La fonction header() permet dintervenir sur len-tte la condition expresse de prcder les affichages du script. Les codes derreurs envoys par les rponses permettent la gestion des pages derreurs et de lauthentication.

196 LE GUIDE COMPLET

JavaScript, contrle de formulaires et AJAX


Prsentation de JavaScript ............................................................................................. 198 Des vrifications simples en PHP .................................................................................. 216 Les expressions rgulires .............................................................................................. 222 Ajax ........................................................................................................................................ 226 Check-list ............................................................................................................................. 234

Chapitre 8

JavaScript, contrle de formulaires et AJAX

Vous tes dsormais en mesure dobtenir des informations auprs des internautes et de les transmettre un script charg de leur traitement. Ltape suivante consiste vrier que les donnes du formulaire sont conformes vos attentes, que tous les champs obligatoires ont t remplis et quils contiennent bien le type de valeur que vous attendez. Suivant la technique utilise, ces contrles pourront avoir lieu la fois au niveau du navigateur (JavaScript) ou du serveur (PHP), avec ou sans rechargement de page.

8.1. Prsentation de JavaScript


Le langage JavaScript a t cr en 1995 par Brendan Eich (aujourdhui employ par Firefox) pour le compte de la socit Netscape. Face au succs croissant du Web, Microsoft sinspira bien vite du concept pour son nouveau navigateur (Internet Explorer) et cra le Jscript en sloignant bien videmment du langage initial. Le besoin vident dun standard conduisit nanmoins les principaux acteurs dnir une norme : lECMAScript. La situation actuelle est heureusement bien meilleure quil y a quelques annes. En dehors de Microsoft et de sa mauvaise volont coutumire, les principaux navigateurs du march (Firefox, Safari, Opera, Konqueror) tendent suivre scrupuleusement la norme et permettent dcrire un code extrmement portable. Face ce mouvement, la croissance rapide de Firefox, et la grogne gnrale des dveloppeurs, Microsoft tend cependant rentrer davantage dans les rangs avec Internet Explorer 7. En ce qui concerne les nouveauts, JavaScript est un langage qui continue voluer et qui a vu un accroissement rapide de sa popularit avec lavnement du concept Ajax. La version 2.0 de Firefox propose dans ses nouveauts une volution majeure du langage et son passage la version 1.7.
JavaScript 2.0

Firefox 3.0 intgrera une version 2 de JavaScript. Cet interprteur aura la particularit davoir t offert par la socit Adobe-Macromedia. Il convient en effet de rappeler que le langage action ActionScript utilis au sein des animations Flash repose 100% sur lECMAScript et quil

198 LE GUIDE COMPLET

Prsentation de JavaScript

Chapitre 8

est par consquent compatible avec JavaScript. La page www.mozilla .org/projects/tamarin propose plus dinformations sur le sujet.

Lobjet de ce chapitre nest certainement pas de rentrer dans les dtails du langage. Il sagit au contraire de prsenter quelques fonctionnalits qui pourront se rvler utiles lors de la conception dapplications web. La syntaxe du langage ressemblant normment celle du PHP, nous ne nous tendrons pas sur le sujet.

Les fonctions
Comme vous lavez compris dans le premier chapitre, JavaScript est un langage interprt qui sexcute au niveau du navigateur. Un code JavaScript se dclare entre les balises <script type="text/javascript"> et </script>. Il se situe le plus souvent dans len-tte de la page HTML (entre les balises <head> et </head>).
Syntaxe alternative

La syntaxe <script language="javascript"> peut galement tre trouve mais appartient dsormais au pass.

Un code JavaScript est gnralement organis en fonctions.


Listing 8-1 : Dfinition de deux fonctions JavaScript : message() et popup() <html> <head> <script type="text/javascript"> function message(str) { document.write(str); } function popup(str) { alert(str); } </script> </head> <body> ...

LE GUIDE COMPLET 199

Chapitre 8

JavaScript, contrle de formulaires et AJAX

Plutt que placer tout le code JavaScript au niveau de len-tte (header), vous pouvez le centraliser dans un chier extrieur.
Listing 8-2 : fichier fonctions.js contenant la dclaration des deux fonctions function message(str) { document.write(str); } function popup(str) { alert(str); }

Ce dernier est ensuite inclus dans le chier HTML de la manire suivante :


Listing 8-3 : Le code JavaScript est inclus depuis un fichier externe <html> <head> <script type="text/javascript" src="fonctions.js"></script> </head> <body> ...

Une fois les fonctions cres et associes votre page, elles peuvent tre appeles de diffrentes manires : soit directement dans le contenu de la page, soit en les liant un vnement.
Similarits et diffrences entre PHP et JavaScript

Comme vous le constatez, PHP et JavaScript utilisent la mme syntaxe pour dclarer des fonctions. Dautres lments du langage sont galement trs proches : les structures de contrle (if, while, for, etc.), les oprateurs de contrle (==, >=, etc.), le caractre non typ des variables. Parmi les diffrences, nous pouvons tout de mme citer : j labsence du $ devant les variables ; j la ncessit de dclarer les variables avant de les utiliser pour la premire fois (par exemple, var n;) ; j des noms de fonctions diffrents (par exemple, print() devient document.write()) ; j le signe plus (+) plutt que le point (.) comme oprateur de concatnation de chanes de caractres.

200 LE GUIDE COMPLET

Prsentation de JavaScript

Chapitre 8

Lappel direct
Dans le corps de la page (<body>), ouvrez un deuxime bloc de code JavaScript qui vous permet de faire appel directement aux fonctions dnies plus haut :
Listing 8-4 : excution de la fonction message() par appel dans le corps de la page <html> <head> <script type="text/javascript"> function message(str) { document.write(str); } </script> </head> <body> <script type="text/javascript"> message("message gnr par une fonction JavaScript"); </script> </body> </html>

Comme en PHP, les lments (fonctions, variables) dnis dans les diffrents blocs de code sont accessibles partir des autres blocs. Dans le cas prsent, vous auriez pu dnir les fonctions juste au-dessus de leur appel :
Listing 8-5 : Dclaration de la fonction et son appel dans le mme bloc <html> <head> <body> <script type="text/javascript"> function message(str) { document.write(str); } message("message gnr par une fonction JavaScript"); </script> </body> </html>

An de faciliter la relecture, lusage veut cependant de les laisser dans len-tte de la page.

LE GUIDE COMPLET 201

Chapitre 8

JavaScript, contrle de formulaires et AJAX

Les vnements
La nature des vnements lis une page web est assez varie. Un vnement peut tre li la page elle-mme (ouverture, fermeture) ou un widget (clic sur un lien, sur un bouton, focus sur un champ de texte, choix dune option dans un menu droulant). Lexemple ci-dessous ouvre une petite fentre ( laide de la fonction alert()) une fois la page charge, et une autre quand vous fermez le navigateur. Les deux vnements utiliss sont onLoad() et onUnload() lis la balise <body>.
Listing 8-6 : Excution de la fonction popup() louverture et la fermeture de la page avec des paramtres diffrents <html> <head> <script type="text/javascript"> function popup(str) { alert(str); } </script> </head> <body onLoad="popup(ouverture de la page)" onUnload="popup(fermeture de la page)"> vnements JavaScript </body> </html>

Figure 8.1 : Apparition de la fentre pop-up une fois la page charge

202 LE GUIDE COMPLET

Prsentation de JavaScript

Chapitre 8

Vous allez maintenant dclencher la fonction popup() en cliquant sur un bouton :


Listing 8-7 : La fonction popup() est associ au clic sur le bouton <html> <head> <script type="text/javascript"> function popup(str) { alert(str); } </script> </head> <body> <form> <input type="button" value="cliquer ici" onClick="popup(vnement associ au clic)" /> </form> </body> </html>

Figure 8.2 : La fentre apparat la suite dun clic sur le bouton

Plutt que de crer des fonctions dans len-tte, il est prfrable, quand celles-ci sont simples, de mettre le code directement au niveau de lvnement.
Listing 8-8 : le code responsable de louverture de la fentre pop-up est directement plac au niveau de lvnement <html> <body> <form> <input type="button" value="cliquer ici"
LE GUIDE COMPLET 203

Chapitre 8
</form> </body> </html>

JavaScript, contrle de formulaires et AJAX

onClick="alert(vnement associ au clic)" />

Lexemple suivant ouvre une fentre lorsque vous survolez (vnement onMouseOver()) un lien :
Listing 8-9 : Affichage dune fentre lorsque le pointeur de la souris passe au-dessus du lien <html> <body> <a href="#" onMouseOver="alert(coucou)">lien</a> </body> </html>
Tableau 8.1 : vnements JavaScript

vnement

Gestionnaire dvnement

Signication Le chargement dune image a chou Perte du focus dun lment Changement de valeur dun lment Simple clic sur un lment Double clic sur un lment Erreur lors du chargement dune image Un lment obtient le focus Une touche du clavier est presse Suit le keydown Une touche du clavier est relche Lorsque la page est intgralement charge Le bouton de la souris est press La souris est dplace Le curseur de la souris quitte llment

abort blur change click dblclick error focus keydown keypress keyup load mousedown mousemove mouseout

onAbort onBlur onChange onClick onDblClick onError onFocus onKeyDown onKeyPress onKeyUp onLoad onMouseDown onMouseMove onMouseOut

204 LE GUIDE COMPLET

Prsentation de JavaScript
Tableau 8.1 : vnements JavaScript

Chapitre 8

vnement

Gestionnaire dvnement

Signication Le curseur de la souris passe sur llment Le bouton de la souris est relch Le formulaire est rinitialis Llment est redimensionn Le texte est slectionn Lors de la soumission dun formulaire Lorsque lutilisateur quitte la page

mouseover mouseup reset resize select submit unload

onMouseOver onMouseUp onReset onResize onSelect onSubmit onUnload

Linteraction avec les widgets


JavaScript permet dinteragir avec tous les lments dun formulaire. Tout champ peut tre initialis, modi et contrl. Les techniques permettant daccder aux valeurs des widgets ont largement volu depuis 1995. Nous prsenterons ici la mthode la plus rcente et la plus rpandue aujourdhui. JavaScript dispose dune fonction qui vous permet daccder tout lment de la page : document.getElementById(). Cette fonction prend en argument lidentiant de llment auquel vous souhaitez accder. Tout lment dune page HTML peut tre identi en lui assignant un attribut id. La seule contrainte est de choisir un identiant unique au sein de la page.
Listing 8-10 : ce champ text est dsormais identifi en tant que nom <input type="text" id="nom" />

Les attributs name et id

Lattribut id ne se substitue en aucun cas lattribut name. Lors de la soumission dun formulaire, seul lattribut name est pris en compte pour la transmission des donnes.

LE GUIDE COMPLET 205

Chapitre 8

JavaScript, contrle de formulaires et AJAX

La fonction document.getElementById() permet daccder lensemble des attributs dun lment : sa valeur (value), son nom (name), son identiant unique (id), son type (type), etc. Si vous souhaitez par exemple accder la valeur (value) dun input
text dont lid est p, crivez :
document.getElementById(p).value

Laccs aux autres attributs de llment suit le mme principe :


Listing 8-11 : document.getElementById() permet daccder lensemble des attributs du widget <html> <body> <input type="text" name="prenom" id="p" value="paul" /> <br/><br/> <input type="button" value="type" onClick="alert(type : + document.getElementById(p).type)" /> <br/> <input type="button" value="name" onClick="alert(name : + document.getElementById(p).name)" /> <br/> <input type="button" value="id" onClick="alert(id : + document.getElementById(p).id)" /> <br/> <input type="button" value="value" onClick="alert(value : + document.getElementById(p).value)" /> <br/> </body> </html>

Figure 8.3 : Chaque bouton permet daccder un attribut

206 LE GUIDE COMPLET

Prsentation de JavaScript

Chapitre 8

Les mthodes associes aux lments peuvent galement tre appeles. Lexemple suivant illustre lutilisation de la mthode select() qui permet de slectionner le contenu des input text et des textarea.
Listing 8-12 : Slection du contenu de linput text <html> <body> <input type="text" name="prenom" id="p" value="paul" /> <br/><br/> <input type="button" value="selection du contenu" onClick="document.getElementById(p).select()" /> <br/> </body> </html>

Figure 8.4 : Slection du contenu

La balise <form> dispose elle-mme dun certain nombre de mthodes. Lappel direct sa mthode submit() peut viter de passer par un bouton submit pour valider le formulaire.
Listing 8-13 : Le lien situ en dehors du formulaire dclenche lenvoi du formulaire <form id="form1"> </form> <a href="#" onClick="document.getElementById(form1).submit()">

Prsentons avant daller plus loin une fonction trs utile du JavaScript : confirm(). Lappel cette fonction dclenche lapparition dune petite fentre (similaire celle de la fonction alert()) qui demande une conrmation (OK, Annuler) linternaute. Si le bouton OK est press,
LE GUIDE COMPLET 207

Chapitre 8

JavaScript, contrle de formulaires et AJAX

confirm() retourne le boolen true. Associe une structure de contrle comme if, cette fonction peut permettre dexcuter diffrentes

parties de code en fonction de la rponse de linternaute. Dveloppez laide de cette fonction un petit script qui demande une conrmation avant dinitialiser le contenu dun champ texte :
Listing 8-14 : Utilisation de la commande confirm() <html> <header> <script type="text/javascript"> function ma_fonction() { if (confirm("Initialiser le champ text ?")) { document.getElementById(p).value=abcdef; } } </script> </header> <body> <input type="text" id="p" /><br/><br/> <input type="button" value="valider" onClick="ma_fonction()" /><br/> </body> </html>

Figure 8.5 : Utilisation de la fonction conrm

La fonction prompt() permet, quant elle, de demander durant lexcution dun JavaScript une donne linternaute. Faites voluer le script prcdent en initialisant le champ text avec une donne que la fonction prompt()aura transmise :

208 LE GUIDE COMPLET

Prsentation de JavaScript

Chapitre 8

Listing 8-15 : Utilisation de la commande prompt() <html> <header> <script type="text/javascript"> function ma_fonction() { if (confirm("Vous souhaitez initialiser le champ text ?")) { var str = prompt("Avec quelle valeur ?"); document.getElementById(p).value=str; } } </script> </header> <body> <input type="text" id="p" /><br/><br/> <input type="button" value="valider" onClick="ma_fonction()" /><br/> </body> </html>

Figure 8.6 : Utilisation de la fonction prompt

Nous progressons maintenant vers le but de ce paragraphe : tester les champs dun formulaire avant de dclencher la transmission. Il se rvle trs facile de tester la prsence dune donne dans un champ text, compte tenu de ce que vous avez vu prcdemment :
Listing 8-16 : Vrification du contenu dun champ text <html> <header> <script type="text/javascript"> function verif() { if (document.getElementById(p).value==) {

LE GUIDE COMPLET 209

Chapitre 8

JavaScript, contrle de formulaires et AJAX

alert("Erreur"); } else { alert("ok"); } } </script> </header> <body> <input type="text" id="p" /><br/><br/> <input type="button" value="valider" onClick="verif()" /><br/> </body> </html>

La ligne alert(ok) aurait pu tre ici remplace par lappel de la mthode submit() du formulaire monform.
Dbogage JavaScript

Le navigateur Firefox propose un outil trs pratique pour les dveloppeurs web : la console JavaScript. Cette console, qui peut tre ouverte depuis le menu Outils, liste toutes les erreurs qui sont survenues durant lexcution de votre code et vous donne des indications sur leur origine.

Figure 8.7 : Une console JavaScript indiquant une mauvaise orthographe de la fonction alert()

Cette fonctionnalit devrait sduire les dveloppeurs web exasprs par les messages derreur incomprhensibles fournis par Internet Explorer. Bien que dj trs utile, cette fonctionnalit fait ple gure face lextension Firebug tlchargeable sur le site : www.getfirebug.com. Vritable couteau suisse, cette extension permet de tracer les erreurs avec une facilit dconcertante.

210 LE GUIDE COMPLET

Prsentation de JavaScript

Chapitre 8

Figure 8.8 : Affichage de la mme erreur dans la console de Firebug

Les lments select, input radio et input checkbox doivent tre tests diffremment. Les cases cocher, quil sagisse de radio ou de checkbox, ne drogent pas la rgle dunicit en ce qui concerne lid qui leur est associ. La vrication de ltat coch repose sur la valeur (true/false) de lattribut checked.
if (document.getElementById(c).checked==false) alert("Cette case nest pas coche");

Pour les lments select, lattribut qui nous intresse est selectedIndex qui contient le numro de loption slectionne (la premire a pour index 0). Ce principe conduit souvent avoir comme premier lment du select une option vide qui force linternaute en slectionner vritablement une. Dans le cas dun select multiple, selectedIndex peut avoir la valeur 1 si aucune des options nest slectionne. Validez maintenant le formulaire mis en place dans le chapitre prcdent. Vous en proterez pour lui ajouter un champ annee que vous limiterez quatre caractres. Votre objectif est dafficher un message
LE GUIDE COMPLET 211

Chapitre 8

JavaScript, contrle de formulaires et AJAX

derreur prcisant les champs qui nont pas t renseigns. Une fois le formulaire convenablement rempli, une demande de conrmation est faite avant la transmission du formulaire script.php.
<html> <head> <script type="text/javascript"> function verif() { var err = ""; if (document.getElementById(idTitre).value==) err = err+"- titre\n"; if (document.getElementById(idAnnee).value==) err = err+"- anne\n"; if (document.getElementById(idGenre).selectedIndex==-1) err = err+"- genre\n"; if (document.getElementById(idDescript).value==) err = err+"- description\n"; if (document.getElementById(idCoulOui).checked==false && document.getElementById(idCoulNon).checked==false) err = err+"- couleur\n"; if (document.getElementById(idPays).selectedIndex==0) err = err+"- pays\n"; if (document.getElementById(idStFr).checked==false && document.getElementById(idStGb).checked==false && document.getElementById(idStEs).checked==false) err = err+"- sous titre\n"; if (err!="") { alert("Formulaire incomplet :\n"+err); } else if (confirm("Transmettre le formulaire ?")) { document.getElementById(monform).submit(); } } </script> </head> <body> <form action="script.php" id="monform">

212 LE GUIDE COMPLET

Prsentation de JavaScript

Chapitre 8

<label>Titre du film</label> <input type="text" name="titre" id="idTitre" /><br/> <label>Anne</label> <input type="text" name="annee" id="idAnnee" maxlength="4" /> <br/> <label>Genre</label> <select name="genre[]"multiple="yes" size="3" id="idGenre"> <option value="policier">POLICIER</option> <option value="sf">SCIENCE FICTION</option> <option value="culte">CULTE</option> </select><br/> <label>Description</label> <textarea name="description" id="idDescript"></textarea><br/> <label>Film en couleur</label> <input type="radio" name="couleur" value="1" id="idCoulOui" /> oui <input type="radio" name="couleur" value="0" id="idCoulNon" /> non <br/> <label>Pays</label> <select name="pays" id="idPays"> <option value=""></option> <option value="fr">FRANCE</option> <option value="us">USA</option> <option value="gb">ANGLETERRE</option> </select><br/> <label>Sous titre</label> <input type="checkbox" name="soustitre[]" value="fr" id="idStFr" /> franais <input type="checkbox" name="soustitre[]" value="gb" id="idStGb" /> anglais <input type="checkbox" name="soustitre[]" value="es" id="idStEs" /> espagnol <br/> <br/> <input type="button" value="valider" onClick="verif()" /> </form> </body> </html>

LE GUIDE COMPLET 213

Chapitre 8

JavaScript, contrle de formulaires et AJAX

Figure 8.9 : Validation des diffrents types de widget

Les accents

Le choix de lidentiant idAnnee plutt quidAnne est volontaire. La gestion des accents est loin dtre parfaite dans la plupart des navigateurs, et cela risque dtre lorigine derreurs.

La bibliothque Prototype
Comme vous pouvez le constater, la syntaxe des fonctions JavaScript peut apparatre assez complique. Partant de ce constat, certains dveloppeurs lis la plateforme Ruby On Rails ont conu une bibliothque JavaScript visant simplier la vie des dveloppeurs et allger leur code : Prototype. Cette bibliothque peut tre tlcharge sur le site www.prototypejs.org. Pour lutiliser, placez-la par exemple dans un rpertoire js contenant vos scripts JavaScript et incluez-la de la manire suivante :
Listing 8-17 : Inclusion de la bibliothque Prototype <html> <head> <script src="/js/prototype.js" type="text/javascript"></script> </head> <body> ...

214 LE GUIDE COMPLET

Prsentation de JavaScript

Chapitre 8

Une fois incluse, cette bibliothque vous permet de remplacer document.getElementById(id_element) par $(id_element) et document.getElementById(id_element).value par $F(id_element). $() et $F() sont des extensions propres Prototype vous permettant de rendre votre code beaucoup plus lgant et lisible.
Listing 8-18 : Version Prototype <head> <script src="/js/prototype.js" type="text/javascript"></script> <script language="javascript"> function verif() { var err = ""; if ($F(idTitre)==) err = err+"- titre\n"; if ($F(idAnnee)==) err = err+"- anne\n"; if ($(idGenre).selectedIndex==-1) err = err+"- genre\n"; if ($F(idDescript)==) err = err+"- description\n"; if ($(idCoulOui).checked==false && $(idCoulNon).checked==false) err = err+"- couleur\n"; if ($(idPays).selectedIndex==0) err = err+"- pays\n"; if ($(idStFr).checked==false && $(idStGb).checked==false && $(idStEs).checked==false) err = err+"- sous titre\n"; if (err!="") { return alert("Formulaire incomplet :\n"+err); } if (confirm("Transmettre le formulaire ?")) { $(monform).submit(); } } </script> </head>

Inconvnient de Prototype

Linconvnient majeur de la bibliothque Prototype est sa taille. La premire fois quun internaute visite une page faisant appel la bibliothque Prototype, un chier (prototype.js) de 70 Ko doit tre tlcharg en plus de la page et des ventuelles images lies. Heureusement pour nous, les navigateurs web sont intelligents et ne tlchargeront pas nouveau ce chier chaque consultation de la page

LE GUIDE COMPLET 215

Chapitre 8

JavaScript, contrle de formulaires et AJAX

(ou de toute autre page utilisant la bibliothque). Le cache du navigateur sera en effet mis contribution.

8.2. Des vrications simples en PHP


Les tests JavaScript ne doivent en aucun cas tre considrs comme un gage de scurit absolu. Vous savez en effet quil est possible de composer soi-mme un lien permettant de transmettre des donnes. En utilisant cette technique, lutilisateur passe travers les tests JavaScript et force la transmission des informations qui lui conviennent. Il est galement important de savoir que la technologie JavaScript peut tre dsactive au niveau du navigateur. Au bilan, vos vrications JavaScript doivent plutt tre envisages comme des avertissements. Lutilisateur est mis au courant que ses donnes risquent dtre refuses au niveau du script et quil lui faudra alors revenir en arrire an de modier les donnes du formulaire. Nous sommes donc ici plus dans une optique de confort, dergonomie et de gain de temps. Commencez par tudier les diffrentes fonctions de contrle que vous propose PHP et utilisez le formulaire prsent juste au-dessus pour vos exemples. Tout dabord, la fonction empty()est de loin la plus importante. Cette fonction retourne true si la variable que vous lui avez adresse en argument est vide ou inexistante. Cette fonction peut tre utilise pour les champs titre, anne,
description et pays.
if (empty($_REQUEST[titre])==true) { print("ERREUR : le champ titre na pas t rempli"); exit(); }

Vous savez quun if vrie si lexpression est diffrente de false. Vous pouvez donc simplier votre test et faciliter sa lecture :
if (empty($_REQUEST[titre])) { print("ERREUR : le champ titre na pas t rempli"); exit(); }

216 LE GUIDE COMPLET

Des vrifications simples en PHP

Chapitre 8

Allgement du code

Il convient de ne pas aller trop loin dans lallgement de votre code. Une lisibilit accrue pour une relecture facile est largement plus importante quun code compact. De plus, nallez surtout pas imaginer quen rduisant la taille de votre code, vous optimiserez sa performance : cest faux !

La fonction exit() est utilise pour interrompre et quitter dnitivement le script. Vous pouvez aussi faire appel la fonction die() qui quitte galement le programme tout en affichant lcran la chane de caractres qui lui est adresse en paramtre.
if (empty($_REQUEST[titre])) { die("ERREUR : le champ titre na pas t rempli"); }

La commande return ()

Vous pourrez trouver sur le Web des scripts qui utilisent la fonction return() plutt que les fonctions exit() ou die(). Cette fonction est pourtant diffrente dans le sens o return() ne quitte que le script en cours. Vous verrez en effet par la suite quun script peut en inclure dautres. Pour tre sr de quitter dnitivement le script, il vaut donc mieux utiliser exit() ou die().

Ce test nest cependant pas trs able car un titre ne contenant quun espace serait considr comme valide. Cette remarque met en exergue limportance de la prparation et du nettoyage pralables des donnes avant leur utilisation au sein dun script. Dans la majorit des cas, il est conseill de supprimer les caractres dits blancs (espaces, tabulations) situs aux extrmits dun paramtre. La fonction trim() prvue cet effet rend cette opration triviale.
$_REQUEST[titre] = trim($_REQUEST[titre]); if (empty($_REQUEST[titre])) { die("ERREUR : le champ titre na pas t rempli"); }

Trois paramtres restent donc tester : le genre, la couleur et le sous-titre.

LE GUIDE COMPLET 217

Chapitre 8

JavaScript, contrle de formulaires et AJAX

Ces paramtres ont la particularit de ne pas tre propags par le formulaire si aucune valeur nest coche ou slectionne. Votre test ne porte donc plus sur le caractre vide ou non de la variable, mais sur son existence. La fonction isset() vous vient ici en aide en retournant true si une variable existe et false dans le cas contraire.
if (isset($_REQUEST[genre])) { die("ERREUR : aucun genre na t slectionn"); }

Les fonctions empty() et isset()

Mme si la fonction isset() peut la plupart du temps tre remplace par empty(), il est prfrable dtre le plus prcis possible dans le choix et lutilisation de vos fonctions.

Vous tes dsormais en mesure de savoir si tous les champs ont t renseigns. Vous navez cependant aucune information sur la validit des paramtres reus. Dans ltat actuel des choses, $_REQUEST[genre] pourrait contenir la chane de caractres xx et passer les tests. Vous allez donc aller plus loin dans la validation des paramtres et contrler les points suivants :
j j j j j j j

$_REQUEST[titre] contient plus de deux caractres ; $_REQUEST[annee] comprise entre 1930 et 2007 ; $_REQUEST[genre] contient au moins une des valeurs suivantes : policier, sf, culte ; $_REQUEST[description]

contient

entre

10

et

500 caractres ;
$_REQUEST[couleur] vaut 0 ou 1 ; $_REQUEST[pays] contient une des valeurs suivantes : fr, us, gb ; $_REQUEST[soustitre] contient au moins une des valeurs suivantes : fr, gb, es.

La fonction strlen() qui retourne la taille dune chane de caractres est utilise pour les tests 1 et 4.
Listing 8-19 : Validation du titre if (strlen($_REQUEST[titre])>2)

218 LE GUIDE COMPLET

Des vrifications simples en PHP


Listing 8-20 : Validation de la description if( strlen($_REQUEST[description])>10 && strlen($_REQUEST[description])<500)

Chapitre 8

Les tests 2 et 5 peuvent se rsumer des comparaisons de type numrique :


Listing 8-21 : Validation du champ anne if ($_REQUEST[annee]>=1930 && $_REQUEST[annee]<=2006) Listing 8-22 : Validation de la couleur if ($_REQUEST[couleur]==0 || $_REQUEST[couleur]==1)

Le test 6 se rsume quant lui des comparaisons sur les chanes de caractres :
Listing 8-23 : Validation du pays if ($_REQUEST[pays]==fr || $_REQUEST[pays]==us || $_REQUEST[pays]==gb)

Le principe de ce dernier test est correct, mais pose le problme dallonger et de complexier normment lif ds que vous ajoutez une option. Une technique optimale consiste dclarer un tableau contenant toutes les valeurs possibles et vrier que la valeur de $_REQUEST[pays] en fait bien partie. La fonction in_array() va vous permettre dy parvenir. Son premier argument correspond la valeur tester et le second un tableau contenant les valeurs de rfrence :
Listing 8-24 : Version plus lgante de la vrification du pays $tableau_pays = array(fr,us,gb); if (in_array($_REQUEST[pays],$tableau_pays)==false) $erreur .= "- le champ pays est mal rempli<br/>";

Les tests 3 et 7 diffrent du test 6 dans la mesure o $_REQUEST [genre] et $_REQUEST[soustitre] peuvent contenir plusieurs valeurs qui doivent toutes tre valides. La fonction in_array() va donc devoir tre applique pour chacune de ces valeurs :
Listing 8-25 : Validation du genre $tableau_genre = array(policier,sf,culte); foreach ($_REQUEST[genre] as $tmp) { if (in_array($tmp,$tableau_genre)==false) $erreur .= "- le genre $tmp nest pas correct<br/>"; }

LE GUIDE COMPLET 219

Chapitre 8

JavaScript, contrle de formulaires et AJAX

Listing 8-26 : Validation du sous-titre $tableau_soustitre = array(fr,gb,es); foreach ($_REQUEST[soustitre] as $tmp) { if (in_array($tmp,$tableau_soustitre)==false) $erreur .= "- le sous-titre $tmp nest pas correct<br/>"; }

Ces deux tests sont valides mais insuffisants car vous ne testez pas le fait que $_REQUEST[genre] et $_REQUEST[soustitre] sont bien des tableaux et quils contiennent au moins un lment. Cette vrication est importante dans la mesure o foreach() gnre une erreur lorsque la variable qui lui est adresse en paramtre nest pas un tableau. Renforcez la vrication en utilisant la fonction is_array(), qui indique si la variable qui lui est transmise en paramtre est bien un tableau, et la fonction count() qui retourne le nombre dlments contenus dans un tableau.
Listing 8-27 : Version plus complte de la validation du genre if (is_array($_REQUEST[genre])==false || count($_REQUEST[genre])<=1) { $erreur .= "- le genre nest pas correct<br/>"; } else { $tableau_genre = array(policier,sf,culte); foreach ($_REQUEST[genre] as $tmp) { if (in_array($tmp,$tableau_genre)==false) $erreur .= "- le genre $tmp nest pas correct<br/>"; } }

Lensemble de ces tests vous informe de la validit des paramtres. Adaptez-les an de dtecter dsormais leur non-validit et regroupez-les au sein dune fonction : verif(). Cette fonction retourne true si aucune erreur nest dtecte et false dans le cas contraire.
Listing 8-28 : Fonction verif() de vrification des paramtres <?php function verif() { $erreur = ""; if (strlen($_REQUEST[titre])<=2) $erreur .= "- le champ titre est mal rempli<br/>";

220 LE GUIDE COMPLET

Des vrifications simples en PHP

Chapitre 8

if( strlen($_REQUEST[description])<=10 || strlen($_REQUEST[description])>=500) $erreur .= "- le champ description est mal rempli<br/>"; if ($_REQUEST[annee]<1930 || $_REQUEST[annee]>2006) $erreur .= "- le champ anne est mal rempli<br/>"; if ($_REQUEST[couleur]!=0 && $_REQUEST[couleur]!=1) $erreur .= "- le champ couleur est mal rempli<br/>"; $tableau_pays = array(fr,us,gb); if (in_array($_REQUEST[pays],$tableau_pays)==false) $erreur .= "- le champ pays est mal rempli<br/>"; if (is_array($_REQUEST[genre])==false || count($_REQUEST[genre])<1) { $erreur .= "- le genre nest pas correct<br/>"; } else { $tableau_genre = array(policier,sf,culte); foreach ($_REQUEST[genre] as $tmp) { if (in_array($tmp,$tableau_genre)==false) $erreur .= "- le genre $tmp nest pas correct<br/>"; } } if (is_array($_REQUEST[soustitre])==false || count($_REQUEST[soustitre])<1) { $erreur .= "- le sous-titre nest pas correct<br/>"; } else { $tableau_soustitre = array(fr,gb,es); foreach ($_REQUEST[soustitre] as $tmp) { if (in_array($tmp,$tableau_soustitre)==false) $erreur .= "- le sous-titre $tmp nest pas correct<br/>"; } } if (!empty($erreur)) { print($erreur); return false; } return true; } if (verif()==false) exit(0); print("<b>Titre</b> : ".$_REQUEST[titre]."<br/>");
LE GUIDE COMPLET 221

Chapitre 8

JavaScript, contrle de formulaires et AJAX

print("<b>Anne</b> : ".$_REQUEST[annee]."<br/>"); $str_genre = join(,,$_REQUEST[genre]); print("<b>Genre</b> : ".$str_genre."<br/>"); print("<b>Description</b> : ".$_REQUEST[description]."<br/>"); print("<b>Couleur</b> : ".$_REQUEST[couleur]."<br/>"); print("<b>Pays</b> : ".$_REQUEST[pays]."<br/>"); $str_soustitre = join(,,$_REQUEST[soustitre]); print("<b>Sous titres</b> : ".$str_soustitre."<br/>"); ?>

8.3. Les expressions rgulires


Les expressions rgulires (galement appeles regular expressions ou regexp) permettent de raliser des tests beaucoup plus ns et complexes. Lide ici est dutiliser la fonction preg_match() qui retournera true si la variable que vous lui adressez en second paramtre correspond lexpression rgulire que vous lui avez transmise en premier paramtre (que vous appellerez dsormais pattern). En terme technique, vous vriez si ces deux arguments se correspondent. Lopration gnrale de recherche de correspondance est appele le pattern matching.
Et le franais dans tout a ?

Comme vous pouvez le constater, il est fait un usage intensif de barbarismes franglais dans cet ouvrage. Le but est avant tout de vous prsenter les termes le plus souvent utiliss dans la littrature informatique.

Un pattern est une simple chane de caractres entoure par le caractre / qui va vous permettre de prciser trs nement le motif que vous recherchez dans la variable tester. Si vous souhaitez par exemple vrier que la variable $str contient quelque part dans son contenu la chane "http", crivez :
Listing 8-29 : Premire utilisation de la fonction preg_match() if (preg_match("/http/", $str)) { print ("str contient http"); } else { print ("str ne contient pas http"); }

222 LE GUIDE COMPLET

Les expressions rgulires

Chapitre 8

$str contient "blabla http blabla", la fonction preg_match() retourne true. En revanche, si vous lui adressez bla http bla ou bla hTTp bla, preg_match() retournera false. La fonction preg_match() fait en effet partie des fonctions sensibles la

Si

casse (qui font la diffrence entre les majuscules et les minuscules). Loption i place derrire le deuxime / permet de raliser une comparaison de type case insensitive (qui nest pas sensible la casse).
Listing 8-30 : Test insensible la casse if (preg_match("/a/i",$str)) { print("str contient a ou A"); } else { print("str ne contient pas a ou A"); }

Pour vrier que "http" se trouve en dbut de chane, vous disposez de laccent circonexe (^) qui, dans le cadre dune regexp, correspond un dbut de ligne.
Listing 8-31 : Premire utilisation de la fonction preg_match() if (preg_match("/^http/",$str)) { print("str commence http"); } else { print("str ne commence pas http"); }

Dans le mme esprit, le caractre $ correspond une n de ligne. Le pattern ^http$ permet par consquent de vrier que $str contient exactement la chane "http". Dans un tel cas, le test if ($str=="http") reste cependant largement plus rapide et pertinent quif (preg_match("/^http$/",$str)).
Expressions rgulires et norme

Les expressions rgulires sont aujourdhui largement normalises. Leur syntaxe est quasi la mme quen C, Perl, etc.

Le point (.) a aussi un rle spcial au sein dun pattern, il correspond un (et un seul) caractre, quel quil soit.
j

preg_match("/ht.tp/","htatp") retourne true ;

LE GUIDE COMPLET 223

Chapitre 8
j

JavaScript, contrle de formulaires et AJAX

preg_match("/ht.tp/","htap") retourne false.

Le pattern ^..$ est donc un moyen de tester que $str contient deux caractres. Le test if (strlen($str)==2) est cependant plus optimis pour ce type de vrication. Pour vrier que $str contient bien le point, vous devez le protger avec la barre oblique inverse (\). Le pattern www\. permet de vrier que $str contient " www." et non " www#". La barre oblique inverse doit galement tre utilise pour protger les caractres suivants : / ^ [ ] $ ( ) | * { } + ? { \ . Ces caractres vont en effet permettre daller plus loin dans la construction des patterns. Les crochets par exemple permettent de regrouper un ensemble de caractres qui devront apparatre au moins une fois dans $str.
j j

preg_match("[aeiouy]",$str) vrie que $str contient au

moins une voyelle ;


preg_match("[aeiouy]r",$str) vrie que $str contient au moins une fois une voyelle suivie de la lettre r ;

Certains regroupements de caractres peuvent tre simplis laide des expressions spciales :
j j j

\w : pour des lettres, des chiffres ou le caractre _ ; \d : pour des chiffres ; \s : pour des caractres despacement : \n, ,\t,.

Le pattern ^\d\d\s\d\d\s\d\d\s\d\d\s\d\d$ peut tre utilis pour vrier que $str correspond un numro de tlphone (ex: 01 53 98 73 40). Vous pouvez une nouvelle fois simplier ce pattern en utilisant les expressions de frquence suivantes :
j j j

"(to)?" : la chane contient une fois au maximum la chane "to" ; "(to)+" : la chane contient une fois au minimum la chane "to" ; "(to)*" : la chane contient zro ou plusieurs fois la chane "to" ;

224 LE GUIDE COMPLET

Les expressions rgulires


j j

Chapitre 8

"(to){2}" : la chane contient deux chanes "to" qui se

suivent ;
"(to){2,5}" : la chane contient entre deux et cinq chanes "to" qui se suivent.

Votre pattern tlphonique devient donc ^(\d\d\s){4}(\d\d)$. Voyez quelques exemples :


j j

"^\w+$" pour vrier que $str ne contient que des lettres ; "^[\w\s,\.]+$" pour vrier que $str nest compose que de

lettres, de chiffres, de caractres blancs ou de points et de virgules. Les crochets permettent galement de dnir des intervalles :
j j j j j

[az] pour des lettres minuscules ; [AZ] pour des lettres majuscules ; [09] pour des chiffres de 0 9 ; [05] pour des chiffres de 0 5 ; [dg] pour des lettres minuscules de d g.

Le caractre | au sein dun pattern prend la signication dun OU :


j j

"(fr|gb|es)" pour vrier que la chane contient fr ou gb ou es ; "^(fr|gb|es)$" pour vrier quelle est gale fr, gb ou es.

Compilez maintenant vos connaissances an de trouver le pattern qui vous permettra de tester quune chane est une adresse de courriel valide. Pour simplier et ne pas vous perdre dans des dtails, considrez quune adresse de courriel est construite de la manire suivante : le nom de lutilisateur (caractres alphanumriques ainsi que les caractres .), larobase (@), le nom de domaine (caractres alphanumriques ainsi que les caractres .), un point et lextension du domaine (de deux trois caractres).
j j j j

tape 1 : tape 2 : tape 3 : tape 4 :

^[\w\.]+ ; @ ; [\w\.]+ ; \. ;

LE GUIDE COMPLET 225

Chapitre 8
j

JavaScript, contrle de formulaires et AJAX

tape 5 : [az]{2,3}$^.
Listing 8-32 : Validation dune adresse de courriel
if (preg_match("/^[\w\.-]+@[\w\.-]+\.[a-z]{2,3}$/i", $str)) { print("Cette adresse e-mail est valide."); }

Et pourquoi pas ereg() ?

PHP propose effectivement une autre fonction permettant de manipuler les expressions rgulires : ereg() (ou eregi()pour ignorer la casse). Quoique fonctionnant de faon satisfaisante, ereg() souffre de linconvnient majeur davoir une esprance de vie dsormais assez courte. Les dveloppeurs de PHP ont en effet dcid pour PHP6 de ne plus supporter ereg() et de reporter tous leurs efforts sur la famille des fonctions preg. Les fonctions preg tant galement plus rapides et compatibles avec les donnes binaires, nhsitez surtout pas oublier ereg !

8.4. Ajax
Abrviation dAsynchronous JavaScript and XML, Ajax englobe un certain nombre de technologies qui, pour schmatiser, permettent de saffranchir du schma classique : une action implique un rechargement de page. Lobjet JavaScript XMLHttpRequest qui est au cur dAjax permet en effet de transmettre des donnes au serveur et de rcuprer le rsultat. En traitant ce rsultat et en sappuyant sur les technologies DHTML/CSS, des interfaces graphiques avances peuvent tre mises en uvre pour le plus grand confort de linternaute. Loutil cartographique de Google (http://maps.google.com) est un des plus beaux exemples denvironnement Ajax.

AJAX et Prototype
Lobjet XMLHttpRequest, disponible maintenant dans tous les navigateurs, nest hlas pas standardis au niveau de son utilisation. Une nouvelle fois, la bibliothque Prototype nous vient en aide en masquant toutes les difficults lies aux diffrentes mthodes dinitialisation.

226 LE GUIDE COMPLET

Ajax

Chapitre 8

Notre premier exemple consiste transmettre une opration au script calculatrice.php qui calculera le rsultat et le renverra notre script, tout ceci sans quitter la page ! Prototype rend cette opration extrmement aise avec la mthode
request() qui tend les fonctionnalits dun lment de type

formulaire. Cette mthode prend en paramtre un objet dont le rle est de dnir les comportements de lapplication en cas de succs ou dchec. Un objet JavaScript se construit de la faon suivante :
Listing 8-33 : Cration et utilisation de lobjet rectangle <script> var rectangle = { longueur:3, largeur:2, surface:function () { return this.longueur * this.largeur; } }; alert(surface=+rectangle.surface()); </script>

La mthode request() va automatiquement rcuprer le script appeler en allant lire la valeur de lattribut action du formulaire. Les paramtres transmis correspondent aux champs du formulaire.
Listing 8-34 : Formulaire permettant de dfinir lopration : calculatrice.html <html> <header> <script src="/js/prototype.js" type="text/javascript"></script> <script type="text/javascript"> function calcule() { if ($F(a).blank() || $F(b).blank()) { alert(Veuillez rviser les valeurs.); return; } $(calculatrice).request({ onComplete: function(transport){ alert(transport.responseText) } }); }

LE GUIDE COMPLET 227

Chapitre 8

JavaScript, contrle de formulaires et AJAX

</script> </header> <body> <form id="calculatrice" method="get" action="calculatrice.php"> <input type="text" name="a" id="a" /> <select name="operation"> <option value="addition"> + </option> <option value="soustraction"> - </option> <option value="multiplication"> * </option> <option value="division"> / </option> </select> <input type="text" name="b" id="b" /> <input type="button" value="calculer" onClick="calcule()" /><br/> </form> </body> </html>

Pour retourner une valeur, le script PHP se contente dcrire le rsultat sur la sortie standard.
Listing 8-35 : Script calculant le rsultat de lopration : calculatrice.php <?php $a = $_REQUEST[a]; $b = $_REQUEST[b]; switch ($_REQUEST[operation]) { case addition: $resultat = $a + $b; break; case soustraction: $resultat = $a - $b; break; case multiplication: $resultat = $a * $b; break; case division: $resultat = $a / $b; break; } print ("Resultat : ".$resultat); ?>

228 LE GUIDE COMPLET

Ajax

Chapitre 8

Figure 8.10 : Le rsultat apparat sans rechargement de la page

change de donnes au format JSON


Vous savez dsormais changer une donne entre un script et le serveur. Lidal serait cependant de pouvoir transmettre plusieurs informations dans le cadre dune seule et mme transaction. Il conviendrait pour cela que le script PHP puisse transmettre un tableau de valeurs la fonction JavaScript. Par dfaut cependant, un tableau PHP et un tableau JavaScript nont absolument rien voir. Heureusement pour nous, le format JSON rend possible lchange de donnes complexes (tableaux, objets) entre JavaScript et PHP (et inversement). La JavaScript Object Notation a le triple avantage dtre lgre, lisible et interprtable par un trs grand nombre de langages de haut niveau (Ruby, Java, C#, Python, etc.). Un change JSON typique se droule ainsi :
j j j

une donne PHP est convertie au format JSON ; cette chane de caractres reprsentant la donne PHP est transmise au JavaScript ; le script dcrypte la chane et la convertit en sa reprsentation JavaScript.

Une opration similaire pourrait tout fait avoir lieu dans le sens inverse : de JavaScript vers PHP.

LE GUIDE COMPLET 229

Chapitre 8

JavaScript, contrle de formulaires et AJAX

Les fonctions de manipulation de donnes au format JSON sont incluses la fois dans PHP 5.2 et dans la bibliothque Prototype (1.5).
Tableau 8.2 : Gestion du format JSON

PHP (5.2) Encodage dune variable au format JSON Dcodage dune variable au format JSON

JavaScript (Prototype)

json_encode ($variable) json_decode ($json_string)

Object.toJSON(var)

json_string .evalJSON()

Lexemple suivant permet de valider un formulaire en restant sur la mme page tout en passant par le serveur pour raliser les vrications. En cliquant sur le bouton du formulaire, la fonction JavaScript verifAJAX() envoie une requte AJAX au script verif.php qui contrle les champs et retourne un objet au format JSON dont chaque attribut correspond un champ invalide. La fonction JavaScript verifAJAX() reoit la chane de caractres correspondant lobjet, le convertit en objet JavaScript et affiche un message derreur si lobjet contient des attributs, ou un message de flicitations dans le cas contraire.
Listing 8-36 : Formulaire <html> <head> <script src="/js/prototype.js" type="text/javascript"></script> <script type="text/javascript"> function verifAJAX() { $(monform).request({ onComplete: function(transport){ var errors = transport.responseText.evalJSON(); var message = ""; for (var id in errors) { message += "\n - "+errors[id]; } if (message=="") { alert("Flicitations !"); } else { alert("Veuillez vrifier les champs suivants : "+ message);

230 LE GUIDE COMPLET

Ajax
} } }); } </script> </head> <body> <form action="verif.php" id="monform">

Chapitre 8

<label>Titre du film</label> <input type="text" name="titre" id="idTitre" /><br/> <label>Anne</label> <input type="text" name="annee" id="idAnnee" maxlength="4" /> <br/> <label>Genre</label> <select name="genre[]"multiple="yes" size="3" id="idGenre"> <option value="policier">POLICIER</option> <option value="sf">SCIENCE FICTION</option> <option value="culte">CULTE</option> </select><br/> <label>Description</label> <textarea name="description" id="idDescript"></textarea><br/> <label>Film en couleur</label> <input type="radio" name="couleur" value="1" id="idCoulOui" /> oui <input type="radio" name="couleur" value="0" id="idCoulNon" /> non <br/> <label>Pays</label> <select name="pays" id="idPays"> <option value=""></option> <option value="fr">FRANCE</option> <option value="us">USA</option> <option value="gb">ANGLETERRE</option> </select><br/> <label>Sous titre</label> <input type="checkbox" name="soustitre[]" value="fr" id="idStFr" /> franais <input type="checkbox" name="soustitre[]" value="gb" id="idStGb" /> anglais <input type="checkbox" name="soustitre[]" value="es" id="idStEs" /> espagnol <br/> <br/>

LE GUIDE COMPLET 231

Chapitre 8

JavaScript, contrle de formulaires et AJAX

<input type="button" value="valider" onClick="verifAJAX()" /> </form> </body> </html>

Inclusion de la bibliothque Prototype

Noubliez pas dinclure la bibliothque Prototype avec la balise script situe dans le header de la page.

Listing 8-37 : Script de validation <?php function verif() { $ret_arr = array(); if (strlen($_REQUEST[titre])<=2) { $ret_arr[] = titre; } if( strlen($_REQUEST[description])<=10 || strlen($_REQUEST[description])>=500) { $ret_arr[] = description; } if ($_REQUEST[annee]<1930 || $_REQUEST[annee]>2006) { $ret_arr[] = annee; } if (!array_key_exists(couleur, $_REQUEST)) { $ret_arr[] = couleur; } $tableau_pays = array(fr,us,gb); if (in_array($_REQUEST[pays],$tableau_pays)==false) { $ret_arr[] = pays; } if (is_array($_REQUEST[genre])==false || count($_REQUEST[genre])<1) { $ret_arr[] = genre; } else { $tableau_genre = array(policier,sf,culte); foreach ($_REQUEST[genre] as $tmp) {

232 LE GUIDE COMPLET

Ajax
if (in_array($tmp,$tableau_genre)==false) { $ret_arr[] = genre; break; } } }

Chapitre 8

if (is_array($_REQUEST[soustitre])==false || count($_REQUEST[soustitre])<1) { $ret_arr[] = soustitre; } else { $tableau_soustitre = array(fr,gb,es); foreach ($_REQUEST[soustitre] as $tmp) { if (in_array($tmp,$tableau_soustitre)==false) { $ret_arr[] = soustitre; break; } } } return (object)$ret_arr; } print (json_encode(verif())); ?>

Figure 8.11 : Les vrications proviennent du serveur

LE GUIDE COMPLET 233

Chapitre 8

JavaScript, contrle de formulaires et AJAX

Ce mode de fonctionnement dispose des avantages suivants :


j j j

vous ne dupliquez pas les tests la fois en JavaScript et en PHP ; la validation au niveau serveur est la fois plus sre et plus aise ; linternaute ne quittant pas la page, le contenu du formulaire nest pas perdu.

Dans une utilisation normale, le script PHP raliserait une action supplmentaire dans le cas o aucune erreur ne serait dtecte. Les donnes transmises pourraient tre envoyes par mail ou insres dans une base de donnes.

8.5. Check-list
j j j j j

j j

Les JavaScripts sont excuts au niveau du navigateur. Lexcution dun JavaScript fait suite un vnement sur la page web. Les JavaScripts permettent de vrier si le formulaire a bien t rempli. Les donnes reues par un script PHP doivent toujours tre contrles avant dtre exploites. Les contrles JavaScript ne suffisent pas pour une validation srieuse. Des contrles PHP doivent systmatiquement venir les complter. Les expressions rgulires permettent de vrier trs prcisment quune variable correspond un modle donn (pattern). AJAX permet au navigateur web de communiquer avec le serveur sans avoir recharger une nouvelle page.

234 LE GUIDE COMPLET

Lenvoi dun formulaire par courriel


Configuration requise ........................................................................................................ Mail Texte ............................................................................................................................. Mail HTML ........................................................................................................................... Check-list .............................................................................................................................

236 237 242 248

Chapitre 9

Lenvoi dun formulaire par courriel

Lenvoi par courriel dinformations en provenance dun formulaire est certainement lutilisation la plus rpandue de PHP. Vous verrez dans ce chapitre que PHP vous facilite largement la tche pour les envois les plus simples. Vous constaterez en revanche que les courriels mis en forme (HTML) ncessitent davantage de connaissances, notamment en ce qui concerne le standard MIME.

9.1. Conguration requise


Alors que lenvoi de courriel ne ncessite aucune conguration particulire si vos scripts sont excuts chez un hbergeur, il en va tout autrement sils sont placs sur votre machine. Arrtons-nous un instant sur les adaptations apporter votre environnement de travail pour le rendre compatible avec lenvoi de courriels.
Hbergements gratuits

Certains hbergeurs gratuits interdisent lusage de la commande mail() an dviter les abus de type spam. Nhsitez donc pas, avant de choisir un hbergeur, vous renseigner sur ltendue des limitations au niveau des fonctionnalits du langage.

Si votre version de WampServer nest pas suffisamment rcente, vous pourrez dcouvrir, en parcourant le chier php.ini, la section suivante :
Listing 9-1 : section consacre lenvoi de courriels dans le fichier php.ini [mail function] ; For Win32 only. SMTP = localhost ; For Win32 only. ;sendmail_from = me@example.com

La ligne SMTP = localhost indique que PHP est paramtr pour utiliser votre propre machine (localhost) pour lenvoi des courriels. Il sagit l de la directive de conguration par dfaut qui est loin de convenir. Le serveur que vous devez utiliser est celui qui est propos par votre fournisseur daccs. Il sagit du serveur SMTP par lequel vous passez galement dans votre gestionnaire de courriels (par exemple, Outlook Express, Thunderbird, etc.). Chez Free, le serveur SMTP a pour adresse

236 LE GUIDE COMPLET

Mail Texte

Chapitre 9

smtp.free.fr. Cette norme est peu prs respecte par lensemble des FAI (fournisseurs daccs Internet). Nous pouvons citer titre dexemple : smtp.wanadoo.fr, smtp.noos.fr, smtp.club-internet.fr, etc. Intressons-nous
me@example.com.

maintenant la ligne ;sendmail_from = Le point-virgule initial signie quelle est commente et quelle nest donc pas prise en compte. Cette directive permet de prciser lorigine des courriels envoys depuis votre machine. Cette directive est importante dans la mesure o les serveurs de courriels relais refuseront de faire suivre votre message si son origine nest pas prcise. Veillez donc supprimer le point-virgule et renseigner votre adresse e-mail. Une fois ces directives de conguration modies, le serveur Apache doit tre redmarr.
Accs restreints

Les FAI nautorisent que leurs clients utiliser leur serveur SMTP. Un client Wanadoo ne pourra en aucun cas passer par smtp.free.fr. Cette situation peut se rvler pnible si vous travaillez sur un portable et que le fournisseur daccs change dun lieu un autre. Une solution consiste passer par un serveur SMTP gratuit qui vous autorisera transmettre des courriels quelle que soit votre connexion Internet. Google propose dsormais ce service lensemble de ses clients Gmail (www.gmail.com).

9.2. Mail Texte


Comme vous lavez vu en introduction, lenvoi de courriels en PHP est simple. Il suffit dutiliser la fonction mail(). Les arguments de cette fonction sont :
j j j j

ladresse de destination ; le titre du message ; le contenu du message ; dventuelles options.

La fonction mail() est gnralement appele de la manire suivante :


mail($destinataire,$titre,$message);

LE GUIDE COMPLET 237

Chapitre 9
j j j

Lenvoi dun formulaire par courriel

$email est le-mail de la personne qui va recevoir le courriel, par exemple $destinataire = "bill@domaine.fr";. $titre est le titre de le-mail, par exemple $titre = "rponse au formulaire";. $message est le corps du message qui va contenir toutes les

informations. La fonction mail() retourne un boolen qui indique si lenvoi sest bien droul. Ce statut ne concerne que lenvoi, il nindique en aucun cas le fait que le courriel est bien arriv dans la bote du destinataire. Commencez par construire ce message :
Listing 9-2 : Construction du contenu du courriel $message = ""; $message .= "Titre : ".$_REQUEST[titre]."\n"; $str_genre = join(,,$_REQUEST[genre]); $message .= "Genre : ".$str_genre."\n"); $message .= "Description : ".$_REQUEST[description]."\n"); $message .= "Couleur : ".$_REQUEST[couleur]."\n"); $message .= "Pays : ".$_REQUEST[pays]."\n"); $str_soustitre = join(,,$_REQUEST[soustitre]); $message .= "Sous titres : ".$str_soustitre."\n";

La premire ligne initialise la variable (=), les suivantes ajoutent des informations la n de la variable (.=). Vous remarquez lusage systmatique du caractre \n la n de chaque ligne. Il sagit du caractre reprsentant un saut de ligne. Jusqu maintenant, vous utilisiez la balise <BR/> pour effectuer des sauts de ligne car les informations gnres par vos scripts saffichaient dans un navigateur web. Or, en HTML, un saut de ligne est reprsent par la balise <BR/>. Dans le cas prsent, cest un lecteur de courriels (de type Thunderbird ou Outlook) qui va afficher linformation. Cette fois, les donnes sont considres comme du texte brut. Le caractre de saut de ligne est alors reprsent par un \n (ou \r\n sous Windows). Il existe dautres caractres spciaux qui peuvent tre utiliss dans du texte brut, par exemple le \t qui correspond une tabulation.

238 LE GUIDE COMPLET

Mail Texte

Chapitre 9

Votre script prend nalement la forme suivante :


<?php function verif() { $erreur = ""; if (strlen($_REQUEST[titre])<=2) $erreur .= "- le champ titre est mal rempli<br/>"; if( strlen($_REQUEST[description])<=10 || strlen($_REQUEST[description])>=500) $erreur .= "- le champ description est mal rempli<br/>"; if ($_REQUEST[annee]<1930 || $_REQUEST[annee]>2006) $erreur .= "- le champ anne est mal rempli<br/>"; if ($_REQUEST[couleur]!=0 && $_REQUEST[couleur]!=1) $erreur .= "- le champ couleur est mal rempli<br/>"; $tableau_pays = array(fr,us,gb); if (in_array($_REQUEST[pays],$tableau_pays)==false) $erreur .= "- le champ pays est mal rempli<br/>"; if (is_array($_REQUEST[genre])==false || count($_REQUEST[genre])<1) { $erreur .= "- le genre nest pas correct<br/>"; } else { $tableau_genre = array(policier,sf,culte); foreach ($_REQUEST[genre] as $tmp) { if (in_array($tmp,$tableau_genre)==false) $erreur .= "- le genre $tmp nest pas correct<br/>"; } } if (is_array($_REQUEST[soustitre])==false || count($_REQUEST[soustitre])<1) { $erreur .= "- le sous-titre nest pas correct<br/>"; } else { $tableau_soustitre = array(fr,gb,es); foreach ($_REQUEST[soustitre] as $tmp) { if (in_array($tmp,$tableau_soustitre)==false) $erreur .= "- le sous-titre $tmp nest pas correct<br/>"; } } if (!empty($erreur)) {

LE GUIDE COMPLET 239

Chapitre 9

Lenvoi dun formulaire par courriel

print($erreur); return false; } return true; } if (verif()==false) exit(0); print("<b>Titre</b> : ".$_REQUEST[titre]."<br/>"); print("<b>Anne</b> : ".$_REQUEST[annee]."<br/>"); $str_genre = join(,,$_REQUEST[genre]); print("<b>Genre</b> : ".$str_genre."<br/>"); print("<b>Description</b> : ".$_REQUEST[description]."<br/>"); print("<b>Couleur</b> : ".$_REQUEST[couleur]."<br/>"); print("<b>Pays</b> : ".$_REQUEST[pays]."<br/>"); $str_soustitre = join(,,$_REQUEST[soustitre]); print("<b>Sous titres</b> : ".$str_soustitre."<br/>"); $destinataire = "fx@kernix.com"; $titre = "rponse au formulaire"; $message = ""; $message .= "Titre : ".$_REQUEST[titre]."\n"; $message .= "Anne : ".$_REQUEST[annee]."\n"; $str_genre = join(,,$_REQUEST[genre]); $message .= "Genre : ".$str_genre."\n"; $message .= "Description : ".$_REQUEST[description]."\n"; $message .= "Couleur : ".$_REQUEST[couleur]."\n"; $message .= "Pays : ".$_REQUEST[pays]."\n"; $str_soustitre = join(,,$_REQUEST[soustitre]); $message .= "Sous titres : ".$str_soustitre."\n"; if (mail($destinataire,$titre,$message)==true) { print("<hr/>Les informations ont bien t transmises."); } else { die("<hr/>Lenvoi du courriel a chou."); } ?>

240 LE GUIDE COMPLET

Mail Texte

Chapitre 9

Figure 9.1 : Message envoy par le script et visualis avec Thunderbird

Prsentation des courriels en mode texte

Certains gestionnaires de courriels reconnaissent en mode texte des balises qui permettent denrichir visuellement le contenu. Un mot peut ainsi tre pass en gras sil est entour dastrisques (*), en soulign avec d _ et en italique avec /.

Figure 9.2 : Mise en forme minimale dans un courriel en mode texte

LE GUIDE COMPLET 241

Chapitre 9

Lenvoi dun formulaire par courriel

9.3. Mail HTML


Le script que vous venez dcrire ne permet denvoyer un courriel quau format texte. Mettre une page HTML dans le corps du message ne fonctionnerait pas. Lmission dun courriel au format HTML ncessite la mise en uvre du quatrime paramtre de la fonction mail(). Ce paramtre est une chane de caractres contenant des informations qui seront ajoutes len-tte (header) du message. Un courriel est compos de deux parties principales : len-tte et le corps du message. Len-tte contient un certain nombre dinformations sur le courriel : son origine, le destinataire, le format, le sujet, lheure denvoi, le logiciel denvoi. Lorganisation des donnes dans cet en-tte est trs simple :
champs1: valeur1 champs2: valeur2 etc.

Voyez cet exemple den-tte de courriel :


From: michel@toto.fr To: Paul@titi.fr Subject: retour de vacances X-Mailer: Microsoft Outlook Express

Figure 9.3 : Partie de len-tte dun courriel (vu avec Outlook Express)

La commande mail() compose donc un en-tte par dfaut en intgrant les donnes passes en paramtres : le destinataire (To:), le sujet
242 LE GUIDE COMPLET

Mail HTML

Chapitre 9

(Subject:). Le quatrime paramtre permet dajouter certaines informations cet en-tte. Il est courant quune personne recevant un courriel manant dun script PHP ne sache pas qui lui a envoy. En ajoutant "From: michel@toto.fr" comme quatrime paramtre, le destinataire est en mesure de connatre lorigine du courriel. Les lignes contenues dans le quatrime paramtre doivent tre spares par des sauts de ligne : \n. Ajoutez galement une adresse de rponse (ReplyTo) diffrente de ladresse de lmetteur (From) :
mail("paul@host.com","retour de vacances","excellent", "From: michel@toto.fr\nReply-To: eric@toto.fr");

Cest aussi grce len-tte que vous allez tre en mesure de dire au gestionnaire de courriels que le message quil a reu doit tre considr comme une page HTML. Les deux lignes suivantes dans len-tte indiquent que le courriel nest pas du simple texte.
MIME-Version: 1.0 Content-Type: multipart/alternative; boundary=B97C1230

Le corps du courriel doit lui aussi tre construit de manire spcique. Le contenu HTML doit tre prcd de :
This is a multi-part message in MIME format. --B97C1230 Content-Type: text/html; charset="iso-8859-1"

et suivi de :
--B97C1230-end of the multi-part

La valeur "B97C1230", que lon retrouve en trois endroits, est une valeur la fois alatoire et unique. Il est possible de calculer une valeur unique en PHP de la faon suivante :
$val_unique = md5(uniqid(rand()));

Affichez une liste de 20 valeurs uniques gnres avec cette technique :


for ($i=1;$i<=20;$i++) { $unique = md5(uniqid(rand())); print("$i - $unique<br>"); }

LE GUIDE COMPLET 243

Chapitre 9

Lenvoi dun formulaire par courriel

Figure 9.4 : Liste de 20 valeurs uniques

Envoyez votre premier courriel en HTML :


<?php $boundary = md5(uniqid(rand())); $header = ""; $header .= "From: php <test@mondomaine.com>\n"; $header .= "Reply-To: reply@mondomaine.com\n"; $header .= "MIME-Version: 1.0\n"; $header .= "Content-Type: multipart/alternative; boundary=$boundary\n"; $sujet = "test denvoi HTML"; $html = "\nThis is a multi-part message in MIME format."; $html .= "\n--$boundary\nContent-Type: text/html; charset=\"iso-8859-1\"\n\n"; $html .= "<html><body>\n"; $html .= "<br><br><center><h2><font color=red>premier courriel HTML</font></h2>\n"; $html .= "</body></html>\n"; $html .= "\n--$boundary--\n end of the multi-part";

244 LE GUIDE COMPLET

Mail HTML
mail("test@kernix.com",$sujet,$html,$header); print("courriel envoy ..."); ?>

Chapitre 9

Le rsultat correspond tout fait vos attentes :

Figure 9.5 : Un premier courriel HTML

Pour voir comment la fonction a organis les donnes, vous pouvez afficher les sources du courriel :

Figure 9.6 : Source du courriel HTML

Vous retrouvez bien tous les lments transmis.

LE GUIDE COMPLET 245

Chapitre 9

Lenvoi dun formulaire par courriel

Images et courriels

Il est possible de joindre les images composant le courriel dans le contenu mme de ce dernier. Cette mthode complexe nest cependant pas obligatoire. Il est prfrable de placer les images sur un serveur dhbergement accessible sur le Net et dy faire appel en utilisant le chemin absolu, par exemple : <img src="http://server.com/img/titre.gif" />.

Reprenez votre exemple denvoi de prol en ajoutant la dimension HTML :


Listing 9-3 : Envoi des informations dans un courriel HTML $destinataire = "test@kernix.com"; $titre = "rponse au formulaire"; $boundary = md5(uniqid(rand())); $header = ""; $header .= "From: script php <test@mondomaine.com>\n"; $header .= "Reply-To: reply@mondomaine.com \n"; $header .= "MIME-Version: 1.0\n"; $header .= "Content-Type: multipart/alternative; boundary=$boundary\n"; $message = ""; $message .= "\nThis is a multi-part message in MIME format."; $message .= "\n--$boundary\nContent-Type: text/html; charset=\"iso-8859-1\"\n\n"; $message .= "<html><body>\n"; $message .= "<b>Titre</b> : <font color=red>".$_REQUEST [titre]."</font><br/>\n"; $message .= "<b>Anne</b> : ".$_REQUEST[annee]."<br/>\n"; $str_genre = join(,,$_REQUEST[genre]); $message .= "<b>Genre</b> : ".$str_genre."<br/>\n"; $message .= "<b>Description</b> : ".$_REQUEST [description]."<br/>\n"; $message .= "<b>Couleur</b> : ".$_REQUEST[couleur] ."<br/>\n"; $message .= "<b>Pays</b> : ".$_REQUEST[pays]."<br/>\n"; $str_soustitre = join(,,$_REQUEST[soustitre]); $message .= "<b>Sous-titres</b> : <i>".$str_soustitre ."</i><br/>\n"; $message .= "</body></html>\n"; $message .= "\n--$boundary--\n end of the multi-part";

246 LE GUIDE COMPLET

Mail HTML

Chapitre 9

if (mail($destinataire,$titre,$message,$header)==true) { print("<hr/>Les informations ont bien t transmises."); } else { die("<hr/>Lenvoi du courriel a chou."); }

Figure 9.7 : Courriel en HTML

Tous les champs sont maintenant bien renseigns (voir le champ From).
Le cinquime paramtre

Les versions les plus rcentes de PHP (suprieures 4.0.5) ajoutent un cinquime paramtre optionnel la fonction mail(). Ce paramtre permet de transmettre des instructions au logiciel qui va se charger denvoyer le courriel sur le Net. Parmi les commandes intressantes, on trouve essentiellement "f$adr", o $adr correspond le-mail de la personne qui recevra un message derreur si le courriel ne peut arriver destination. La fonction mail() sutilise alors comme suit : mail($destinataire,$titre,$message,$header,"f$adr");. Ce paramtre permet aussi dviter certaines erreurs avec les serveurs SMTP qui refusent les courriels dont lorigine nest pas prcise. Ce paramtre nest pas disponible si PHP est congur en safe_mode.

LE GUIDE COMPLET 247

Chapitre 9

Lenvoi dun formulaire par courriel

9.4. Check-list
j j j

Lenvoi de courriels en PHP est une opration trs simple. Les courriels contenant de la couleur ou des images ncessitent la modication de len-tte du courriel. Len-tte du courriel permet galement de prciser son origine (From), ladresse e-mail de retour et une multitude dautres informations. Le cinquime paramtre de la fonction mail() est trs utile pour rcuprer les messages derreur.

248 LE GUIDE COMPLET

Lenregistrement dans une base de donnes


Les bases de donnes ..................................................................................................... 250 PHP et MySQL ................................................................................................................... 259 Envoi de fichier ................................................................................................................... 277 Le couteau suisse du dveloppeur web : phpMyAdmin ......................................... 283 Check-list ............................................................................................................................. 289

Chapitre 10

Lenregistrement dans une base de donnes

Lobjectif de ce chapitre est de raliser un script capable denregistrer dans une base de donnes des informations transmises par un formulaire reprsentant une che lve . Nous nous attacherons donc dnir de manire simple et prcise la notion de bases de donnes, leur rle et leur fonctionnement. Nous tudierons ensuite la faon de les interroger depuis un script PHP. Nous nous intresserons enn phpMyAdmin, outil extrmement populaire sur le Web qui permet de grer une base de donnes MySQL.

10.1. Les bases de donnes


Les bases de donnes sont aujourdhui devenues indispensables et incontournables dans lunivers du Web professionnel. Les plus gros sites mondiaux font tous appel de tels systmes.

Quest ce quun SGBD ?


Pendant longtemps, les dveloppeurs qui craient des scripts pour le Web (des CGI) utilisaient de simples chiers texte pour stocker leurs donnes. Les donnes taient enregistres ligne par ligne, et chaque dveloppeur dnissait sa propre norme. Avec la dmocratisation de lusage des bases de donnes, il est plus que conseill dabandonner aujourdhui cette approche. Les avantages offerts par les bases de donnes sont en effet trs nombreux :
j j j j

rapidit tous les niveaux (accs rapide aux donnes sur le disque) ; performances ne diminuant presque pas quand la quantit de donnes augmente ; extractions aises et pouvant se faire sur des critres complexes ; de nombreux outils permettant la sauvegarde, la rplication de donnes.

Un systme de gestion de bases de donnes (gnralement appel SGBD) est en fait un logiciel dont le seul but est de stocker et de

250 LE GUIDE COMPLET

Les bases de donnes

Chapitre 10

restituer de linformation le plus rapidement possible. Il sagit dun logiciel fonctionnant, le plus souvent, en mode client-serveur, la manire dun serveur web ou FTP. Le client envoie des requtes au serveur et celui-ci retourne une rponse. Les requtes sont de types :
ENREGISTRE LADRESSE 12 LE NOM Darras et LE PRENOM Jacques RENVOIE TOUTES LES PERSONNES AYANT COMME PRENOM Michel

ou :
EFFACE TOUS LES ELEVES AYANT MOINS DE 10 DE MOYENNE

Les SGBD sont trs nombreux. On trouve parmi les plus connus :
j j j j j j

SQL Server (Microsoft) ; PostGRE SQL ; Oracle ; DB2 ; MySQL ; SQLite.


Les SGBD en mode chier

Paradox, dBase, Foxpro, Access, dont vous avez certainement entendu parler, sont des SGBD ne fonctionnant pas en mode client-serveur, mais en mode chier. Il faut, dans ce cas, disposer la fois du logiciel et de la base sur son disque dur pour pouvoir les utiliser. Avec lavnement des rseaux dentreprise et des applications en ligne, ce mode de fonctionnement risque fort de laisser la place aux SGBD client-serveur.

Dans le cadre de ce livre, vous allez travailler avec MySQL, le SGBD le plus rpandu sur le Web, qui possde un certain nombre davantages :
j j j j

Il Il Il Il

est prsent chez de nombreux hbergeurs. est extrmement rapide (peut-tre le plus rapide !). fonctionne sous Windows, Linux, Mac OS X. est simple installer et utiliser.

LE GUIDE COMPLET 251

Chapitre 10
j j j j j j j j

Lenregistrement dans une base de donnes

Il est gratuit et open source. Il propose une gestion avance des privilges et des droits. Il existe une compatibilit avec de nombreux langages comme PHP, C, C++, Perl, Python, Java. La scalabilit, la scurit et la stabilit sont irrprochables. Il propose des outils tels que phpMyAdmin. La gestion de lencodage des caractres permet de travailler aussi bien avec du texte chinois que franais. La compatibilit avec le standard SQL est exemplaire. La version 5 propose des fonctionnalits avances, notamment les procdures stockes, les triggers, les vues, les commit/rollback, les cls trangres. Il permet de changer la vole la structure des tables et les types des colonnes.

Pour tre rigoureux, citons tout de mme quelques inconvnients :


j j

Il nexiste pas de client graphique du niveau de ceux de Microsoft SQL Server ou Oracle. Le systme de rplication peut encore tre amlior.

Figure 10.1 : Le logo de MySQL

Comme vous lavez vu, les SGBD ont envahi le Web. On les trouve notamment dans :
j j j

la gestion de contenus (news, forums, blogs) ; le commerce lectronique, pour la gestion de caddies, de commandes, de prols clients ; la gestion des LOG et du trac ;

252 LE GUIDE COMPLET

Les bases de donnes


j j

Chapitre 10

les moteurs de recherche ; les plateformes denchres.

Ajouter une couche base de donnes un site web permet gnralement de lenrichir, de le dynamiser et de le professionnaliser. Plus complet, et mis jour plus rgulirement, votre site incitera dautant plus facilement les visiteurs revenir. Avec des modules de newsletters, de votes, de forums, ces mmes visiteurs pourront, en plus, simpliquer dans la vie du site et sy attacher.

Organisation dun SGBD


Chez la plupart des hbergeurs qui proposent le support des bases de donnes, vous obtiendrez, lors de louverture de votre compte, quatre informations indispensables :
j j j

le serveur de base de donnes, par exemple bdd.kernix, ou 190.191.192.193 ; le nom de la base de donnes, par exemple test ; votre identiant et votre mot de passe, gnralement les mmes que pour le courriel et le FTP, par exemple monidentifiant, monpassword.

Ce sont ces informations qui vont vous permettre de vous identier et de communiquer avec le SGBD. Avant de raliser vos premires requtes, il est ncessaire de comprendre comment les donnes sorganisent au sein dun SGBD. Un SGBD est un systme hirarchique et multi-utilisateur. Chaque utilisateur possde certains droits sur certaines bases. Vous ne disposerez gnralement de droits que sur une seule base. Une base peut tre assimile une grosse armoire de rangement dont vous avez la cl (identiant et mot de passe). Cette armoire va vous permettre dy placer des classeurs. Les classeurs correspondent aux tables. Chaque base de donnes contient donc plusieurs tables vous permettant dorganiser vos donnes. La base test pourra par exemple contenir :
j j j

une table eleve ; une table professeur ; une table fournisseur.


LE GUIDE COMPLET 253

Chapitre 10

Lenregistrement dans une base de donnes

Chaque table contient des caractristiques qui lui sont propres : on parle alors de colonnes. Les tables ne contiennent pas obligatoirement des donnes de mme type.
j j

Table : eleve. Colonnes : nom, prenom, adresse, ville, code postal, pays, sexe, date de naissance, taille, email, telephone, langue vivante.

Lorsque les tables sont cres, il devient possible dy enregistrer de nouveaux lves, professeurs ou fournisseurs. Les donnes sorganisent alors dans la table ligne par ligne : on parle denregistrements. La table eleve contient ainsi une liste dlves. Chaque lve disposant de ses caractristiques :
j j

Dupont Paul 12, rue Cronstadt Paris 75015 Durand Michel 23, bd Voltaire Boulogne 92100

Pour diffrencier de manire unique ces diffrents enregistrements, il est courant dajouter une colonne initiale aux tables : on parle de cl propos de cette colonne spciale. Le premier champ de la table eleve devient donc ideleve (identiant de llve).
j j

1 Dupont Paul 12, rue Cronstadt Paris 75015 2 Durand Michel 23, bd Voltaire Boulogne 92100

Plutt que de demander la ligne o le nom est Dupont et risquer de tomber sur un autre Dupont, il est maintenant possible de demander la ligne ayant la cl 1.

Les requtes
Prsentation du SQL
Comme vous lavez vu plus haut, vous utilisez des requtes pour communiquer avec une base. Ces requtes sont fondes sur un langage propre aux SGBD : le SQL (Structured Query Language). Ce langage est n vers la n des annes 1970 et a vite t normalis. Par l mme, en tudiant le SQL dans le cadre du SGBD MySQL, vous pourrez passer

254 LE GUIDE COMPLET

Les bases de donnes

Chapitre 10

sans aucune difficult un autre SGBD (par exemple PostGRE SQL, lautre grand SGBD du Web et de lopen source). Une requte typique en SQL est de la forme :
SELECT nom FROM eleve WHERE ideleve = 5

Elle pourrait tre traduite en franais de la manire suivante : renvoie le nom de llve ayant la cl numro 5 . Une prsentation approfondie des fonctionnalits les plus avances du SQL ncessiterait un volume supplmentaire. Vous vous contenterez donc dtudier les parties du langage ncessaires la ralisation de la plupart des petites applications web. Vous verrez notamment linsertion, la slection, et la suppression de donnes.

Types de colonnes
Le langage SQL est un langage typ. Une colonne peut tre de type chane de caractres, nombre entier, virgule, date, etc. Bien choisir les types de vos donnes vous permettra dobtenir de meilleures performances au niveau de vos requtes. Cest dailleurs le premier conseil qui est donn une personne souhaitant optimiser son application.
Tableau 10.1 : Les principaux types de donnes de MySQL

Type de donnes MySQL

Dnition Chane de caractres de taille variable Texte contenant au maximum 255 caractres Texte contenant au maximum 65 535 caractres Texte contenant au maximum 16 777 215 caractres Texte contenant au maximum 4 294 967 295 caractres Date et heure Date Nombre entier compris entre -128 et 127

VARCHAR TINYTEXT TEXT MEDIUMTEXT LONGTEXT DATETIME DATE TINYINT

LE GUIDE COMPLET 255

Chapitre 10

Lenregistrement dans une base de donnes

Tableau 10.1 : Les principaux types de donnes de MySQL

Type de donnes MySQL

Dnition Nombre entier compris entre -32 768 et 32 767 Nombre entier compris entre -2 147 483 648 et 2 147 483 647 Nombre entier compris entre -9 223 372 036 854 775 808 et 9 223 372 036 854 775 807 Nombre virgule

SMALLINT INT BIGINT

FLOAT

TEXT et BLOB

Les types TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB existent galement. Ils ne diffrent de leurs cousins TEXT que par le fait quils sont sensibles la casse. Les mots CouCou et coucou sont donc identiques quand ils sont stocks en TEXT, et diffrents en cas de BLOB.

la diffrence de PHP, les numriques ou les chanes de caractres sont eux-mmes diviss en plusieurs types. Cette subdivision a bien videmment pour objectif de gagner en place et en rapidit. Quand vous voulez stocker un ge, il vaut mieux prfrer un TINYINT un INT. Votre table sera plus petite et, quand vous voudrez extraire des donnes, le rsultat sera obtenu plus rapidement. La cration dune table au sein de votre base de donnes ncessite aussi une requte. La commande utilise est cette fois CREATE TABLE. La requte SQL permettant de crer votre table eleve est la suivante :
CREATE TABLE eleve ( ideleve int(10) unsigned NOT NULL auto_increment, nom varchar(64) NOT NULL default , prenom varchar(64) NOT NULL default , adresse varchar(128) NOT NULL default , ville varchar(64) NOT NULL default , cp varchar(8) NOT NULL default , pays varchar(32) NOT NULL default france, sexe varchar(8) binary NOT NULL default , naissance date NOT NULL default 0000-00-00, taille tinyint(10) unsigned NOT NULL default 0, email varchar(64) NOT NULL default ,

256 LE GUIDE COMPLET

Les bases de donnes


telephone varchar(16) NOT NULL default , lv varchar(16) NOT NULL default , PRIMARY KEY (ideleve), KEY nom (nom) ) TYPE=MyISAM;

Chapitre 10

La table contient 13 colonnes. tudions comment est construite cette requte

Cration de la table
CREATE TABLE eleve (.

Il sagit de la commande SQL de la requte. Cette dernire fonctionne, en rsum, de la manire suivante :
CREATE TABLE nom_de_la_table (Champ1 Type1, Champ2 Type2)

Dnition du champ ideleve


ideleve int(10) unsigned NOT NULL auto_increment,

Il sagit donc dun entier (int(10)) positif (unsigned), non nul (NOT NULL), qui sauto-incrmente ds que lon ajoute une nouvelle entre. La syntaxe est du type :
nom_du_champ type _du_champ liste_d_options

Le champ taille est aussi un entier positif non nul. En revanche, il ne sincrmente pas, et possde une valeur par dfaut : 0 (default 0). Vous remarquez que nous avons choisi un TINYINT pour la taille. Or, la taille peut facilement tre suprieure 127 cm. Associ loption unsigned, un TINYINT peut en fait contenir une valeur allant jusqu 255. Il en est de mme pour les autres types numriques (le maximum peut tre doubl).
Dnomination des tables et des champs

Il est souvent dconseill dutiliser des caractres spciaux dans les programmes pour dnir des fonctions ou des variables. De la mme manire, en base de donnes, il est plus sr dviter de mettre des espaces ou des accents dans le nom des tables ou des colonnes. Cest pour cette raison que nous prfrons ideleve idlve.

LE GUIDE COMPLET 257

Chapitre 10

Lenregistrement dans une base de donnes

Dnition du champ nom


nom varchar(64) NOT NULL default ,

Il sagit cette fois dune chane de caractres de taille maximale 64, nayant pas de valeur par dfaut ( la diffrence du champ pays qui a pour valeur par dfaut france). Plusieurs champs ont le mme type sans avoir la mme taille. Lide est doptimiser vos tables et de ne pas les alourdir plus quelles nen ont besoin. Quand on sait que le code postal ne sera jamais plus long que 8 caractres, il est prfrable de lui donner une taille de 8. Il faut donc bien calculer, et ne pas voir trop juste. En effet, une donne comportant 10 caractres, stocke dans un champ de taille 8, sera tronque. Le champ sexe dispose dun attribut en plus : binary. Cela signie que le champ en question est sensible la casse (minuscules, majuscules). Par dfaut, ce nest pas le cas avec de simples varchar (par exemple, le champ ville). Ainsi, quand on cherche les lves habitant Paris, MySQL nest pas sensible au fait que lorthographe soit "paris", "PARIS" ou "Paris". Ce comportement est souvent celui quon attend, mais est plus lourd gnrer. Prciser binary permet donc galement dacclrer les requtes.

Dnition du champ naissance de type date


naissance date NOT NULL default 0000-00-00,

Le type date a t prfr au type datetime car vous navez pas besoin de lheure exacte de la naissance.

Dnitions des cls et des index


PRIMARY KEY (ideleve), KEY nom (nom)

Ces deux lignes permettent de dnir les cls et les index sur certaines colonnes : ideleve devient une cl primaire, et un index est cr sur la colonne nom. Une cl primaire signie que pour la table eleve, il ne peut y avoir quun seul lve ayant lideleve 5. Lindex signie, quant lui, quune table adjacente la table eleve va tre cre an dacclrer les requtes bases sur cette colonne indexe. Dans ce cas, il est pertinent dindexer la colonne nom, car il y a de fortes chances que lon veuille accder la che dun lve en prcisant son nom. linverse, indexer la colonne ville nest pas trs judicieux, car il est trs peu probable que lon souhaite rcuprer des enregistrements partir de

258 LE GUIDE COMPLET

PHP et MySQL

Chapitre 10

cette colonne. Il faut noter que la cration dun index accompagne systmatiquement la cration dune cl primaire. La colonne ideleve est donc indexe.
Les index

Les index doivent tre utiliss bon escient. Mettre un index sur une mauvaise colonne pourrait conduire des rponses plus lentes. Il est gnralement conseill de mettre des index sur des colonnes souvent utilises, et varies au niveau du contenu. Un index intelligent peut en revanche permettre dtre 100 fois plus rapide sur certaines requtes.

Formats de tables
"TYPE=MyISAM"

MySQL propose diffrents formats de tables. MyISAM est aujourdhui le meilleur parmi les formats stables et rpandus. Il a lavantage de disposer de plus de fonctionnalits et dtre plus rapide que son anctre ISAM. Prciser le format de la table nest cependant pas vraiment ncessaire car MySQL cre gnralement une table avec le meilleur format dont elle dispose.

10.2. PHP et MySQL


Premires requtes
Parmi les nombreuses extensions proposes par PHP, MySQL est une des plus utilises. Les fonctions proposes par cette extension vont permettre de se connecter au serveur de SGBD et la base. Comme vous lavez vu plus haut dans ce chapitre, les informations vous permettant de vous y connecter (nom du serveur, nom de la base, identiant, mot de passe) doivent vous tre fournies par votre hbergeur. Si vous travaillez sur votre propre machine, les informations suivantes (qui correspondent celles par dfaut) devraient convenir
j j j j

Serveur SGBD : localhost. Nom de la base : test. Identiant : root. Mot de passe : vide.
LE GUIDE COMPLET 259

Chapitre 10

Lenregistrement dans une base de donnes

Avant denvoyer des requtes, il convient tout dabord de se connecter au serveur :


$liendb = mysql_connect("localhost", "root", "");

Choisissez ensuite la base de donnes avec laquelle vous allez travailler (gnralement, vous navez pas le choix, vous ne disposez que dune base de donnes) :
mysql_select_db("test");

Il faut ensuite formater une requte en SQL :


$sql = "CREATE TABLE eleve ( ideleve int(10) unsigned NOT NULL auto_increment, nom varchar(64) NOT NULL default , prenom varchar(64) NOT NULL default , adresse varchar(128) NOT NULL default , ville varchar(64) NOT NULL default , cp varchar(8) NOT NULL default , pays varchar(32) NOT NULL default france, sexe varchar(8) binary NOT NULL default , naissance date NOT NULL default 0000-00-00, taille int(10) unsigned NOT NULL default 0, email varchar(64) NOT NULL default , telephone varchar(16) NOT NULL default , lv varchar(16) NOT NULL default , PRIMARY KEY (ideleve), KEY nom (nom) )";

Envoyez-la ensuite la base :


mysql_query($sql);

Lorsque vous navez plus besoin de la base de donnes dans le script, il est conseill de fermer la connexion au serveur :
mysql_close($liendb);

Vous comprenez donc que le client dans la relation client/serveur est votre script PHP. Cest lui qui envoie et reoit les donnes. Les clients SQL peuvent cependant prendre dautres formes
j

Une application graphique comme ACCESS (via un lien ODBC) : la cration des tables, les requtes, les liaisons, etc., sont alors ralises visuellement (voir Figure 8.2). Un terminal texte : les requtes sont ainsi tapes directement en SQL dans un interprteur de commandes (un shell) et les rponses apparaissent au format texte (voir Figure 8.3).

260 LE GUIDE COMPLET

PHP et MySQL

Chapitre 10

Figure 10.2 : Client SQL graphique

Figure 10.3 : Client SQL texte

crivez maintenant le script creer_table_eleve.php, qui va vous permettre de crer votre table eleve :

LE GUIDE COMPLET 261

Chapitre 10

Lenregistrement dans une base de donnes

Listing 10-1 : Script permettant de crer une table <?php $liendb = mysql_connect("localhost", "root", ""); mysql_select_db("test"); $sql = "CREATE TABLE eleve ( ideleve int(10) unsigned NOT NULL auto_increment, nom varchar(64) NOT NULL default , prenom varchar(64) NOT NULL default , adresse varchar(128) NOT NULL default , ville varchar(64) NOT NULL default , cp varchar(8) NOT NULL default , pays varchar(32) NOT NULL default france, sexe varchar(8) binary NOT NULL default , naissance date NOT NULL default 0000-00-00, taille int(10) unsigned NOT NULL default 0, email varchar(64) NOT NULL default , telephone varchar(16) NOT NULL default , lv varchar(16) NOT NULL default , PRIMARY KEY (ideleve), KEY nom (nom) )"; mysql_query($sql); mysql_close($liendb); echo "table < eleve > cre"; ?>

Pour rsumer, lexcution de la requte a ncessit cinq grandes tapes


j j j j j

tape 1 : tape 2 : tape 3 : tape 4 : tape 5 : fois

cration dune connexion au serveur. slection de votre base. prparation de la requte. envoi de la requte la base. fermeture de votre connexion. vous avez excut votre script en appelant

Une

que

http://localhost/creer_table_eleve.php, la table eleve est alors cre dans votre base test.
Fonction mysql_connect() ou mysql_pconnect()

Il existe deux fonctions permettant de se connecter une base : mysql_connect() et mysql_pconnect(). La fonction mysql_pconnect() utilise une connexion persistante dans le sens o
262 LE GUIDE COMPLET

PHP et MySQL

Chapitre 10

elle essaie de trouver une connexion qui a dj t ouverte avec la base. En pratique, cette fonction nest prfrer mysql_connect() que lorsque votre site est le seul fonctionner sur le serveur. Si votre site est hberg sur un serveur mutualis (comme cest le cas la plupart du temps), cette fonction est plutt viter.

Il convient maintenant dalimenter cette table avec des donnes. Considrez llve suivant
j j j j j j j j j j j j

Nom : Dupont. Prnom : Paul. Adresse : 12, rue Brancion. Ville : Paris. Code postal : 75015. Pays : France. Sexe : masculin. Date de naissance : 11/04/1989. Taille : 120 cm. Courriel : pdupont@wanadoo.fr. Tlphone : 0123456. Langue vivante : anglais.

Pour enregistrer cet lve dans la base, vous avez besoin de la commande SQL INSERT INTO, dont la syntaxe est la suivante :
INSERT INTO nom_table (liste de colonnes) VALUES (liste des valeurs des colonnes)

La requte SQL permettant denregistrer Paul Dupont dans la table eleve est la suivante :
INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv) VALUES (Dupont, Paul, 12 rue Brancion, Paris, 75015, france, masculin, 1989-04-11, 120, pdupont@wanadoo.fr, 0123456, anglais)

Les guillemets ne doivent pas tre oublis autour des donnes.

LE GUIDE COMPLET 263

Chapitre 10

Lenregistrement dans une base de donnes

La notion dchappement de caractres existe aussi en SQL, et se gre de la mme manire quen PHP. Si ladresse de Paul Dupont avait t 12, rue de lInde , vous auriez d crire :
INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv) VALUES (Dupont, Paul, 12 rue de l\Inde, Paris, 75015, france, masculin, 1989-04-11, 120, pdupont@wanadoo.fr, 0123456, anglais)

Les dates en SQL

Les dates doivent tre enregistres langlo-saxonne : anne-moisjour. Pour une date avec lheure : AAAAMMJJ HHMMSS.

crivez le script enregistre_pauldupont.php :


Listing 10-2 : Script enregistre_pauldupont.php <?php $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv) VALUES (Dupont, Paul, 12 rue Brancion, Paris, 75015, france, masculin, 1989-04-11, 120, pdupont@wanadoo.fr, 0123456, anglais)"; mysql_query ($sql); mysql_close($liendb); echo "eleve < Paul Dupont > enregistr"; ?>

En excutant le script, vous ajoutez votre premier enregistrement la table. Lideleve de cet enregistrement est 1 car il sagit dune colonne qui sauto-incrmente chaque insertion. Notez que la requte SQL en elle-mme nest quune chane de caractres toute simple. Vous auriez aussi pu crire :
$command = "INSERT INTO"; $table = "eleve"; $colonnes = "nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv"; $valeurs = "Dupont, Paul, 12 rue Brancion, Paris, 75015, france, masculin, 1989-04-11, 120, pdupont@wanadoo.fr, 0123456, anglais";

264 LE GUIDE COMPLET

PHP et MySQL

Chapitre 10

$sql = "$command $table ($colonnes) VALUES ($valeurs)";

Vous navez fait jusqualors quenvoyer des requtes la base et vous navez pas eu besoin de rcuprer des donnes. Vous allez donc maintenant crire un script qui va vous renvoyer le nom et le prnom de llve qui a la cl 1. Aprs CREATE TABLE et INSERT INTO, la commande SQL dont vous allez avoir besoin est SELECT :
SELECT liste des colonnes slectionnes FROM nom de la table WHERE clause

Dans cet exemple, vous voulez rcuprer les donnes prsentes dans les colonnes nom et prenom de lenregistrement ayant pour ideleve la valeur 1. Cela se traduit ainsi :
SELECT nom, prenom FROM eleve WHERE ideleve = 1

crivez le script voir_pauldupont.php :


<?php $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT nom, prenom FROM eleve WHERE ideleve = 1"; $resultat = mysql_query ($sql); $eleve = mysql_fetch_array ($resultat); $nom = $eleve[nom]; $prenom = $eleve[prenom]; echo "eleve [1], nom = $nom, prenom = $prenom"; mysql_close($liendb); ?>

Figure 10.4 : Rsultat sans surprise de votre premier SELECT

LE GUIDE COMPLET 265

Chapitre 10

Lenregistrement dans une base de donnes

Dans ce script, et la diffrence des prcdents, vous rcuprez le rsultat de la requte dans une variable $resultat. Cette variable pointe sur lensemble des donnes renvoyes par le serveur de BDD : on la qualie didentiant de rsultat. Pour accder ces donnes, vous utilisez la fonction
mysql_fetch_array(), qui cre le tableau $eleve[] et qui permet

daccder aux diffrentes colonnes contenues dans la rponse :


$eleve[nom] retourne ainsi le nom de llve. Il ne servirait rien dcrire $eleve[ville], car vous navez pas demand au serveur la colonne ville.

Dans cet exemple, vous ne rcuprez quun enregistrement. Dans la majorit des cas, cependant, les requtes faites aux SGBD renvoient plusieurs enregistrements. Cest dailleurs prcisment la puissance des bases de donnes que de pouvoir extraire des donnes suivant des critres trs prcis. Avant de pouvoir extraire plusieurs enregistrements, il faut remplir votre table :
Listing 10-3 : Trois nouveaux lves enregistrs <?php $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv) VALUES (Pitel, Guillaume, 5 rue des Sorcires, Paris, 75013, france, masculin, 1989-05-21, 130, pitel@limsi.fr, 0456789, allemand)"; mysql_query ($sql); $sql = "INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv) VALUES (Metayer, Fabrice, 123 bd de Bretagne, Paris, 75015, france, masculin, 1989-11-3, 95, fm@hotmail.com, 0789456, anglais)"; mysql_query ($sql); $sql = "INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv) VALUES (Marillier, Olivia, 32 avenue du Golf, Paris, 75015, france, feminin, 1988-10-19, 145, olivia@marillier.fr, 0741852, espagnol)";

266 LE GUIDE COMPLET

PHP et MySQL
mysql_query ($sql); mysql_close($liendb); echo "3 lves enregistrs"; ?>

Chapitre 10

Plusieurs requtes

Dans ce script, vous envoyez plusieurs requtes la base. La connexion (mysql_connect()) et la dconnexion (mysql_close()) nont cependant lieu quune fois, au dbut et la n du script.

Vriez que le nombre denregistrements dans la table est bien de quatre :


<?php $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT ideleve FROM eleve"; $resultat = mysql_query ($sql); $nb_eleves = mysql_num_rows($resultat); echo "< $nb_eleves > lves dans la table eleve"; mysql_close($liendb); ?>

La fonction permettant dobtenir le nombre denregistrements est mysql_num_rows(). Elle prend en argument le pointeur sur les donnes renvoyes par MySQL : $resultat (rappelons que row signie ligne ). Dans ce script, vous najoutez pas WHERE la n du SELECT car vous voulez rcuprer tous les lves. Vous avez vu, en revanche, avec le script voir_pauldupont.php, quil est possible dextraire des donnes de la base selon certaines contraintes. Ces contraintes se placent derrire WHERE et sont ralises sur le nom des colonnes. Si vous souhaitez, par exemple, avoir la liste des lves de taille suprieure ou gale 150 cm, vous utilisez la requte suivante :
SELECT * FROM eleve WHERE taille >= 150

Lastrisque (*) indique que vous souhaitez rcuprer toutes les informations (colonnes) des lves dont la taille est infrieure 150 cm. Si vous aviez voulu ne rcuprer que leur taille, vous auriez d crire :
LE GUIDE COMPLET 267

Chapitre 10

Lenregistrement dans une base de donnes

SELECT taille FROM eleve WHERE taille <= 150

Il est possible de combiner plusieurs contraintes avec AND :


SELECT nom FROM eleve WHERE ville = paris AND sexe = masculin

Cette requte retourne le nom des garons parisiens. Pour slectionner les lves tudiant lespagnol ou langlais, la liaison entre les contraintes devient OR :
SELECT * FROM eleve WHERE lv = anglais OR prenom = espagnol

Les extractions par rapport aux dates se calquent sur le mme modle. Listez, par exemple, les lves ns aprs 1989 et nhabitant pas dans le XVe arrondissement :
SELECT prenom FROM eleve WHERE naissance > 1989-01-01 AND cp != 75015

crivez maintenant le script complet qui permet dafficher les noms et les prnoms des garons parisiens :

Figure 10.5 : Liste des garons parisiens

<?php echo "<u>liste des garons parisiens :</u> <br><br>"; $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve WHERE ville = paris AND sexe = masculin"; $resultat = mysql_query ($sql); while ($eleve = mysql_fetch_array ($resultat)) {

268 LE GUIDE COMPLET

PHP et MySQL

Chapitre 10

$id = $eleve[ideleve]; $nom = $eleve[nom]; $prenom = $eleve[prenom]; echo "eleve [$id], nom = $nom, prenom = $prenom<br>"; } mysql_close($liendb); ?>

Lintrt de ce script se situe au niveau de la boucle while ($eleve = mysql_fetch_array ($resultat)). Vous vous apercevez qu chaque itration vous passez llve suivant. Vous pouvez envisager
$resultat comme une variable qui contient la fois le rsultat

retourn par le SGBD et un pointeur dirig sur la ligne en cours. La fonction mysql_fetch_array() fait, en ralit, avancer le pointeur chaque fois quelle est appele. Si elle est appele et si le pointeur est dj la n du rsultat, mysql_fetch_array() retourne false et la boucle sarrte. Vous auriez aussi pu passer par une boucle for en vous appuyant sur la fonction mysql_num_rows() :
<?php echo "<u>liste des garons parisiens :</u> <br><br>"; $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve WHERE ville = paris AND sexe = masculin"; $resultat = mysql_query ($sql); $n = mysql_num_rows($resultat); for ($i = 1; $i <= $n; $i++) { $eleve = mysql_fetch_array ($resultat); $id = $eleve[ideleve]; $nom = $eleve[nom]; $prenom = $eleve[prenom]; echo "eleve [$id], nom = $nom, prenom = $prenom<br>"; } mysql_close($liendb); ?>

Le rsultat est le mme, mais vous utilisez une fonction supplmentaire.

LE GUIDE COMPLET 269

Chapitre 10

Lenregistrement dans une base de donnes

Une autre fonction peut tre utilise pour accder aux diffrentes lignes et colonnes : mysql_result(). Cette fonction prend en paramtre la variable $resultat, le numro de la ligne et le nom de la colonne :
<?php echo "<u>liste des garons parisiens :</u> <br><br>"; $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve WHERE ville = paris AND sexe = masculin"; $resultat = mysql_query ($sql); $n = mysql_num_rows($resultat); for ($i = 0; $i < $n; $i++) { $id = mysql_result($resultat,$i,ideleve); $nom = mysql_result($resultat,$i,nom); $prenom = mysql_result($resultat,$i,prenom); echo "eleve [$id], nom = $nom, prenom = $prenom<br>s"; } mysql_close($liendb); ?>

Il est aussi possible de passer le numro de la colonne plutt que son nom. La premire colonne a comme indice 0. Vous allez pouvoir lister tous les champs sans avoir crire leur nom :
<?php echo "<u>liste des garons parisiens :</u> <br><br>"; $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve WHERE ville = paris AND sexe = masculin"; $resultat = mysql_query ($sql); $n = mysql_num_rows($resultat); for ($i = 0; $i < $n; $i++) { for ($j = 0; $j < 13; $j++) echo mysql_result($resultat,$i,$j) . " "; echo "<br>"; } mysql_close($liendb); ?>

270 LE GUIDE COMPLET

PHP et MySQL

Chapitre 10

Figure 10.6 : Liste des garons parisiens avec tous les champs

Le script contient deux boucles for imbriques. La premire permet de passer dune ligne la suivante, la seconde fait passer dune colonne lautre. Allons plus loin dans ce sens : essayez de raliser un script qui, quelle que soit la requte, liste toutes les lignes et les colonnes du rsultat. Vous allez avoir besoin pour cela de la fonction mysql_fields(). Cette commande retourne le nombre de colonnes dans le rsultat, ce qui permet dignorer la valeur 13 que vous avez crite en dur dans le code :
<?php $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT nom, prenom, lv FROM eleve WHERE ville = paris"; $resultat = mysql_query ($sql); $nb_lignes = mysql_num_rows($resultat); $nb_colonnes = mysql_num_fields($resultat); echo "rsultat de la requte : <i>$sql</i> <hr>"; echo "<table border=1 width=100%>"; for ($i = 0; $i < $nb_lignes; $i++) { echo "<tr>"; for ($j = 0; $j < $nb_colonnes; $j++) echo "<td>" . mysql_result($resultat,$i,$j) . "</td>"; echo "</tr>"; } echo "</table>"; mysql_close($liendb); ?>

LE GUIDE COMPLET 271

Chapitre 10

Lenregistrement dans une base de donnes

Figure 10.7 : Affichage gnrique du rsultat dune requte

Si vous changez la requte, le tableau est automatiquement mis jour :

Figure 10.8 : Le tableau est mis jour

Enregistrement dune che


Ralisez maintenant le script eleve_enregistre.php qui va permettre denregistrer un lve dans la base. Commencez par crer le formulaire eleve.html :

272 LE GUIDE COMPLET

PHP et MySQL
Listing 10-4 : Fichier ajout_eleve.html <html> <head><title>Ajouter un lve</title></head> <body> <h1>Ajouter un lve :</h1> <form action="eleve_enregistre.php" method="post"> <label>nom</label> <input type="text" name="nom" /><br/> <label>prnom</label> <input type="text" name="prenom" /><br/> <label>adresse</label> <textarea name="adresse"></textarea><br/> <label>ville</label> <input type="text" name="ville" /><br/> <label>code postal</label> <input type="text" name="codepostal" /><br/> <label>pays</label> <input type="text" name="pays" /><br/>

Chapitre 10

<label>sexe</label> <input type="radio" name="sexe" value="masculin" /> M <input type="radio" name="sexe" value="feminin" /> F<br/> <label>date naissance</label> <input type="text" name="naissance" /><br/> <label>taille (cm)</label> <input type="text" name="taille" /><br/> <label>email</label> <input type="text" name="email" /><br/> <label>tlphone</label> <input type="text" name="telephone" /><br/> <label>langue vivante</label> <select name="lv"> <option value="anglais">anglais</option> <option value="espagnol">espagnol</option> <option value="allemand">allemand</option>

LE GUIDE COMPLET 273

Chapitre 10
</select>

Lenregistrement dans une base de donnes

<br/> <br/> <input type="submit" value="enregistrer" /> </form> </body> </html>

Figure 10.9 : Formulaire dajout dlve

Vos scripts, pour le moment, rcuprent des donnes dun formulaire ou envoient des requtes MySQL. Lide est maintenant de combiner les deux en composant la requte SQL partir des donnes transmises. Les variables $_REQUEST[nom] ont remplac les valeurs xes que vous aviez lhabitude de mettre (Dupont).
Listing 10-5 : Script eleve_enregistre.php <?php if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[ville]) || empty($_REQUEST[codepostal]) || empty($_REQUEST[pays]) ||

274 LE GUIDE COMPLET

PHP et MySQL

Chapitre 10

empty($_REQUEST[naissance]) || empty($_REQUEST[telephone]) || empty($_REQUEST[lv])) die("ERREUR : tous les champs doivent tre remplis."); if ($_REQUEST[sexe]!="masculin" && $_REQUEST[sexe]!="feminin") die("ERREUR : choisissez votre sexe."); if (preg_match("/^[\w\.-]+@[\w\.-]+\.[a-z]{2,3}$/i", $_REQUEST[email]) == false) die("ERREUR : adresse e-mail non valide."); if ($_REQUEST[taille]<=100 || $_REQUEST[taille]>=220) die("ERREUR : la taille nest pas valide."); $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv) VALUES (".$_REQUEST[nom].", ".$_REQUEST[prenom].", " .$_REQUEST[adresse].", ".$_REQUEST[ville].", " .$_REQUEST[codepostal].", ".$_REQUEST[pays].", " .$_REQUEST[sexe].", ".$_REQUEST[naissance].", " .$_REQUEST[taille].", ".$_REQUEST[email].", " .$_REQUEST[telephone].", " .$_REQUEST[lv].")"; if (mysql_query($sql)!=false) print("eleve < ".$_REQUEST[nom]." > enregistr."); else print("Echec lors de la cration de la fiche."); mysql_close($liendb); ?>

Vous remarquez quun test est fait pour savoir si lexcution de la requte sest bien droule. La fonction mysql_query() retourne en effet false en cas dchec. Il est souvent intressant de savoir quel est le numro de la ligne qui vient dtre enregistr. Si la table contient une colonne fonctionnant en AUTO_INCREMENT, la fonction mysql_insert_id()permet davoir accs la valeur gnre par le dernier INSERT. Modiez votre script de manire ce quil affiche aussi le numro de lideleve dans la rponse :

LE GUIDE COMPLET 275

Chapitre 10

Lenregistrement dans une base de donnes

if (mysql_query($sql)!=false) { $ideleve = mysql_insert_id(); print("eleve [$ideleve] < ".$_REQUEST[nom]." > enregistr."); } else print("Echec lors de la cration de la fiche.");

En analysant bien ce script (et en connaissant le problme de lchappement de caractre), vous pourriez vous demander si ce que vous crivez est valide. En effet, si linternaute a tap "34 rue de lIsle" comme adresse dans le formulaire, la requte reste-t-elle correcte malgr la prsence des guillemets ? Est-il ncessaire dchapper, avec une barre oblique inverse, toutes les variables provenant du formulaire ?
Listing 10-6 : Exemple de requte entirement chappe $sql = "INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv) VALUES (" . addslashes($_REQUEST[nom]) .", " . addslashes($_REQUEST[prenom]) .", " . addslashes($_REQUEST[adresse]) .", " . addslashes($_REQUEST[ville]) .", " . addslashes($_REQUEST[codepostal]) .", " . addslashes($_REQUEST[pays]) .", " . addslashes($_REQUEST[sexe]) .", " . addslashes($_REQUEST[naissance]) .", " . addslashes($_REQUEST[taille]) .", " . addslashes($_REQUEST[email]) .", " . addslashes($_REQUEST[telephone]) .", " . addslashes($_REQUEST[lv]) .")";

La rponse est assez complexe, car PHP gre cette problmatique dune manire trs spciale. Par dfaut, en PHP, toutes les variables dun script provenant dun formulaire ou dun cookie sont dj chappes : on parle de magic quotes propos de cet chappement automatique. Ainsi, lorsque linternaute envoie "34 rue de lIsle", le script reoit une variable $_REQUEST[adresse] contenant "34 rue de l\Isle". Il est donc indispensable de savoir si votre systme fonctionne sur ce modle car si vous chappez une telle variable, son contenu est alors doublement chapp et contient "34 rue de l\\\Isle". La fonction PHP qui vous permet de statuer sur la question est get_magic_quotes_gpc() :

276 LE GUIDE COMPLET

Envoi de fichier

Chapitre 10

if (get_magic_quotes_gpc()) echo "le systme utilise les magic quotes"; else echo "le systme nutilise pas le systme des magic quotes";

Si ce script affiche "le systme utilise les magic quotes", votre requte dorigine est valide ; sinon, cest la deuxime solution (avec les addslashes()) qui doit tre utilise. Lidal est donc, avant de commencer dvelopper un applicatif, de vrier comment fonctionne lhbergeur avec qui vous allez travailler. Votre code sera en effet diffrent selon quil autorise ou quil nautorise pas les magic quotes. La premire alternative reste cependant la plus rpandue.
Variables initialises dans le script

Il faut bien faire attention que les magic quotes ninterviennent que sur les variables provenant dun formulaire ou dun cookie, et non sur les variables dnies (ou rednies) au sein mme du script. Si vous composez une requte de la faon suivante, vous risquez fort de vous retrouver avec un message derreur :
$adresse = "34 rue de lIsle"; $sql = "INSERT INTO test (adresse) VALUES ($adresse)";

Comme la variable est dnie au sein du script, la requte doit tre crite de cette manire :
$sql = "INSERT INTO test (adresse) VALUES (" . addslashes($adresse) . ")";

10.3. Envoi de chier


Vous allez maintenant enrichir votre che et ajouter une photo au prol des lves.

Modication de la structure dune table


Une colonne photo doit donc tre insre dans la table. Cest la commande SQL ALTER qui va permettre de modier la structure de la table :
ALTER TABLE eleve ADD photo VARCHAR(64) NULL

LE GUIDE COMPLET 277

Chapitre 10

Lenregistrement dans une base de donnes

Cette requte ajoute une colonne nomme photo, de type chane de caractres, de taille 64, et pouvant tre vide (NULL). La commande ALTER permet ainsi de changer la structure dune table en ajoutant, effaant, modiant des colonnes. Ajoutez une colonne essai la table eleve an de procder quelques tests :
ALTER TABLE eleve ADD essai INT(10) unsigned NOT NULL

La colonne essai est donc un entier positif non nul. Faites en sorte maintenant quelle devienne un nombre ottant :
ALTER TABLE eleve CHANGE essai essai FLOAT

Modiez maintenant son nom, et appelez-la essaie2 :


ALTER TABLE eleve CHANGE essai essai2 FLOAT

Finalement, supprimez cette colonne de la table eleve :


ALTER TABLE eleve DROP essai2

Envoi de chier
Lenvoi dun chier impose lutilisation de la mthode POST et dun encodage spcial des donnes transmises. Le changement dencodage est rendu possible grce lattribut enctype qui prend alors la valeur "multipart/formdata". Il vous est possible de choisir la photo sur votre disque dur en utilisant un widget spcique pour le champ photo : lINPUT de type FILE. Votre formulaire devient donc :
Listing 10-7 : form.html <html> <head><title>Ajouter un lve</title></head> <body> <h1>Ajouter un lve :</h1> <form action="eleve_enregistre.php" method="post" enctype="multipart/form-data"> <label>nom</label> <input type="text" name="nom" /><br/>

278 LE GUIDE COMPLET

Envoi de fichier
<label>prnom</label> <input type="text" name="prenom" /><br/> <label>adresse</label> <textarea name="adresse"></textarea><br/> <label>ville</label> <input type="text" name="ville" /><br/> <label>code postal</label> <input type="text" name="codepostal" /><br/> <label>pays</label> <input type="text" name="pays" /><br/>

Chapitre 10

<label>sexe</label> <input type="radio" name="sexe" value="masculin" /> M <input type="radio" name="sexe" value="feminin" /> F<br/> <label>date naissance</label> <input type="text" name="naissance" /><br/> <label>taille (cm)</label> <input type="text" name="taille" /><br/> <label>email</label> <input type="text" name="email" /><br/> <label>tlphone</label> <input type="text" name="telephone" /><br/> <label>langue vivante</label> <select name="lv"> <option value="anglais">anglais</option> <option value="espagnol">espagnol</option> <option value="allemand">allemand</option> </select><br/> <label>photo</label> <input type="file" name="photo" /><br/> <br/> <br/> <input type="submit" value="enregistrer" /> </form> </body> </html>

LE GUIDE COMPLET 279

Chapitre 10

Lenregistrement dans une base de donnes

Figure 10.10 : Il est possible avec le widget le de slectionner une photo sur son disque dur

Il convient maintenant de modier votre script denregistrement an quil place la photo dans votre compte, quil affiche la photo et quil enregistre le prol de llve (nom de la photo incluse). PHP rend lenvoi de chier trs facile. Deux fonctions sont utilises : is_uploaded_file() et move_uploaded_file(). La fonction is_uploaded_file() permet de vrier que lenvoi du chier sest droul sans encombre. Elle prend en paramtre un nom temporaire de chier et retourne un boolen en cas de succs (true) ou dchec (false). Le nom temporaire se rcupre via la super-globale $_FILES. Cette variable est un tableau dont les cls correspondent aux noms des widgets de type file. Dans le cas prsent, $_FILES[photo] est cr et propose deux lments :
j j

qui contient le nom temporaire du chier sur le serveur ; $_FILES[photo][name] qui contient le nom du chier que vous avez slectionn sur votre machine.
$_FILES[photo][tmp_name]

280 LE GUIDE COMPLET

Envoi de fichier

Chapitre 10

La fonction sutilise donc de la manire suivante:


if (is_uploaded_file($_FILES[photo][tmp_name])==true) // on passe la suite

Nom temporaire

Les plus curieux auront peut-tre eu la curiosit dafficher $_FILES[photo][tmp_name] et se seront alors aperus que le nom temporaire na vraiment aucun rapport avec le chier slectionn. Ce nom peut tre de la forme /tmp/phpDVzJ1N.

Le dplacement du chier temporaire est ralis par la fonction move_uploaded_file(). Son premier paramtre correspond au nom du chier temporaire ($_FILES[photo][tmp_name]) et le second lemplacement nal du chier. Cet emplacement contient la fois le rpertoire qui contiendra le chier et son nom. Gnralement, le nom du chier est celui dorigine : $_FILES[photo][name]. Le rpertoire en revanche peut se situer nimporte o. Si vous voulez dplacer le chier dans un rpertoire images se trouvant au mme niveau que votre script, utilisez le chemin :
"images/".$_FILES[photo][name]

Si le rpertoire images se situe un niveau au-dessus de votre script, le chemin devient :


"../images/".$_FILES[photo][name]

Taille du chier

La taille du chier transmis se rcupre de la manire suivante : $_FILES[photo][size].

Contentez-vous pour linstant de placer le chier au mme niveau que le script eleve_enregistre.php :
Listing 10-8 : Transmission dune photo <?php if (is_uploaded_file($_FILES[photo][tmp_name])) { move_uploaded_file($_FILES[photo][tmp_name], $_FILES[photo][name]); print("<center><img src=".$_FILES[photo][name]. " /></center></hr>"); }
LE GUIDE COMPLET 281

Chapitre 10

Lenregistrement dans une base de donnes

else { die("Problme denvoi du fichier."); } if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[ville]) || empty($_REQUEST[codepostal]) || empty($_REQUEST[pays]) || empty($_REQUEST[naissance]) || empty($_REQUEST[telephone]) || empty($_REQUEST[lv])) die("ERREUR : tous les champs doivent tre remplis."); if ($_REQUEST[sexe]!="masculin" && $_REQUEST[sexe]!="feminin") die("ERREUR : choisissez votre sexe."); if (preg_match("/^[\w\.-]+@[\w\.-]+\.[a-z]{2,3}$/i", $_REQUEST[email]) == false) die("ERREUR : adresse e-mail non valide."); if ($_REQUEST[taille]<=100 || $_REQUEST[taille]>=220) die("ERREUR : la taille nest pas valide."); $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv, photo) VALUES (".$_REQUEST[nom].", " .$_REQUEST[prenom].", ".$_REQUEST[adresse].", " .$_REQUEST[ville].", ".$_REQUEST[codepostal].", " .$_REQUEST[pays].", ".$_REQUEST[sexe].", " .$_REQUEST[naissance].", ".$_REQUEST[taille].", " .$_REQUEST[email].", ".$_REQUEST[telephone].", " .$_REQUEST[lv].", ".$_FILES[photo][name].")"; $ideleve = mysql_insert_id(); if (mysql_query($sql)!=false) { $ideleve = mysql_insert_id(); print("eleve [$ideleve] < ".$_REQUEST[nom]." > enregistr."); } else print("Echec lors de la cration de la fiche."); mysql_close($liendb); ?>

282 LE GUIDE COMPLET

Le couteau suisse du dveloppeur web : phpMyAdmin

Chapitre 10

Figure 10.11 : Transmission de la photo

crasement de chiers

Un chier portant le mme nom quun chier dj prsent sur le serveur remplacera ce dernier en tant upload.

Plusieurs chiers peuvent tre envoys au sein dun mme formulaire. Il faut alors crer plusieurs champs de type file, chacun disposant de son propre attribut name. Au niveau du script, vous vous retrouvez alors avec autant de variables que de champs. Si vous avez les champs photo1 et photo2, les variables suivantes sont cres : $_FILES[photo1] et $_FILES[photo2].
Taille maximale des chiers transmis

La taille des chiers uploads est gnralement limite an dviter les abus. Vous pouvez obtenir cette valeur limite en utilisant la fonction phpinfo() qui affichera la valeur dupload_max_filesize.

10.4. Le couteau suisse du dveloppeur web : phpMyAdmin


Loutil phpMyAdmin est dvelopp en PHP et permet de grer intgralement votre base. Les fonctionnalits quil propose sont assez nombreuses :
LE GUIDE COMPLET 283

Chapitre 10
j j j j j

Lenregistrement dans une base de donnes

cration, modication, suppression de tables (avec toutes les options) ; ajout, modication, suppression des donnes ; possibilit dentrer des requtes SQL ; importation, exportation de donnes ; reporting sur ltat des tables. supplmentaires sont proposes

Certaines fonctionnalits ladministrateur de la base :


j j j j j

gestion des droits des utilisateurs ; reload de la base ; cration de bases ; accs aux donnes systme ainsi quaux statistiques ; dplacement dune table dune base dans une autre.

Cet outil est devenu un atout pour les dveloppeurs web car il permet de gagner normment de temps. Plutt que de crer des scripts pour chaque action que vous voulez raliser sur la table (cration, ajout de donnes, modication de colonnes), phpMyAdmin vous permet de tout faire simplement, et en ligne. Il donne, de plus, accs des fonctionnalits parfois inconnues ou difficiles mettre en place. Faisons un petit tour de ces fonctionnalits

1 La page daccueil permet de crer une nouvelle base.

Figure 10.12 : Page daccueil de phpMyAdmin

284 LE GUIDE COMPLET

Le couteau suisse du dveloppeur web : phpMyAdmin

Chapitre 10

2 Par dfaut, votre base est vide. En cliquant sur son nom, gauche, vous avez la possibilit de crer une nouvelle table.

Figure 10.13 : Cration dune nouvelle table

3 Vous arrivez ensuite sur une page qui vous permet de prciser les noms et les types de chacune des colonnes. Cest aussi cet endroit que vous allez spcier les cls et les index.

Figure 10.14 : Paramtrage de la table

4 Votre table est alors cre. Dans la partie gauche, le nom de la table apparat en dessous de la base. En cliquant sur le nom de cette table, vous arrivez sur une page qui vous permet de modier les champs.

LE GUIDE COMPLET 285

Chapitre 10

Lenregistrement dans une base de donnes

Figure 10.15 :

Mise jour des champs de la table

5 Longlet Insrer vous permet dajouter des donnes dans la table.

Figure 10.16 :

Insertion dans la table

6 Une fois la premire donne ajoute, vous pouvez voir le contenu de la table en cliquant sur la petite icne qui prcde le nom de la table dans la zone de gauche.

Figure 10.17 : Affichage du contenu de la table

286 LE GUIDE COMPLET

Le couteau suisse du dveloppeur web : phpMyAdmin

Chapitre 10

7 Longlet SQL permet de saisir des requtes SQL

Figure 10.18 : Saisie dune requte

Figure 10.19 : Rsultat de la requte

8 Longlet Exporter permet dexporter des donnes dans diffrents formats

LE GUIDE COMPLET 287

Chapitre 10

Lenregistrement dans une base de donnes

Figure 10.20 : Exportation des donnes

9 Quand des tables existent dans la base, vous obtenez des informations en cliquant sur le nom de cette base. Vous pouvez notamment voir la taille prise par les donnes contenues dans chaque table.

Figure 10.21 : Votre table contient quatre lignes, reprsentant 3,4 ko

Les hbergeurs offrent gnralement ce service ds quils proposent la paire PHP/MySQL. Si ce nest pas le cas, essayez de leur demander. Linstallation est rellement aise, et cest gratuit.

288 LE GUIDE COMPLET

Check-list

Chapitre 10

10.5. Check-list
j j j j j j

j j j

j j

MySQL est aujourdhui considr comme lun des meilleurs SGBD du march. Une base de donnes vise avant tout stocker et rcuprer des informations le plus vite possible. Les SGBD modernes fonctionnent sur un modle client-serveur. SQL est le langage utilis pour communiquer avec un serveur de bases de donnes. Un SGBD peut contenir plusieurs bases qui contiendront ellesmmes plusieurs tables. Chaque table est dnie par un certain nombre de colonnes qui ont chacune un type (numrique, date, chane de caractres, etc.). Chaque ligne dans une table est appele un enregistrement . Trois tapes sont ncessaires pour se connecter un SGBD en PHP : la connexion au serveur, la slection de la base, la transmission de la requte SQL. Laccs une base ncessite donc quatre lments : ladresse du serveur, les identiants (login, password) et le nom de la base. Les requtes de type SELECT permettent de rcuprer de linformation. Les requtes de type INSERT permettent dinsrer des informations dans la base. La transmission dun chier en PHP via un formulaire ncessite que la balise FORM dispose des attributs method="post" et enctype="multipart/formdata". La variable $_FILES contient les informations relatives au chier transmis. Le logiciel phpMyAdmin permet de grer intgralement en ligne un serveur MySQL.

LE GUIDE COMPLET 289

La gestion dune base de donnes


Lauthentification ................................................................................................................ 292 La mise jour dune table ............................................................................................... 296 La suppression : DELETE ................................................................................................ 308 La factorisation du code .................................................................................................. 314 Recherche et tri au sein dune base .............................................................................. 331 Check-list ............................................................................................................................. 337

Chapitre 11

La gestion dune base de donnes

Vous allez dcouvrir dans ce chapitre comment administrer votre base depuis une interface web. Vous utiliserez pour cela intensivement lensemble des commandes SQL dcrites dans le chapitre prcdent.

11.1. Lauthentication
Le Web, pour proposer toujours plus de dynamisme et dinteractivit, se complexie. Lutilisation de scripts et de bases de donnes est aujourdhui devenue une quasi-obligation lors de la conception dun site denvergure. Une autre tendance semble se dessiner : la prsence dun site cach accompagnant le site principal, et permettant de ladministrer. Lusage est aujourdhui de parler de front-office pour le site visible par un internaute lambda, et de back-office pour qualier le site dadministration, uniquement accessible par le propritaire du site. Vous allez donc vous doter, dans ce chapitre, dun back-office, qui vous permettra de :
j j j j j

lister les lves ; modier leur prol ; supprimer des lves ; chercher un lve ; trier les lves.

Laccs ce back-office doit bien videmment tre protg. Le systme dauthentication du protocole HTTP pourra tout 0 fait convenir. Les administrateurs devront renseigner lidentiant essai et le mot de passe essai pour se connecter. La page daccueil contient la liste des lves et permet daccder un prol donn :
Listing 11-1 : admin.php <?php if (!($_SERVER[PHP_AUTH_USER]=="essai" && $_SERVER[PHP_AUTH_PW]=="essai")) { header("status: 401 Unauthorized"); header("HTTP/1.0 401 Unauthorized"); header(WWW-authenticate: Basic . realm="acces securise au back-office");

292 LE GUIDE COMPLET

Lauthentification
print("verification : ERREUR"); exit(0); } echo echo echo echo echo "<html>"; "<head>"; "<title>Admin "</head>"; "<body>";

Chapitre 11

Ecole</title>";

$liendb = mysql_connect("localhost", mysql_select_db ("test"); $sql = "SELECT * FROM $resultat = mysql_query echo echo "<h1>admin "<p eleve"; ($sql);

"root",

"");

ecole</h1>"; accueil</p>";

align=left> ::

echo "<table width=90% align=center border=1>"; echo "<tr><td>id</td><td>nom</td><td>prenom</td> <td>naissance</td><td> </td></tr>"; while ($eleve = mysql_fetch_array ($resultat)) { $id = $eleve[ideleve]; $nom = $eleve[nom]; $prenom = $eleve[prenom]; $date = $eleve[naissance]; echo "<tr>"; echo "<td>$id</td>"; echo "<td>$nom</td>"; echo "<td>$prenom</td>"; echo "<td>$date</td>"; echo "<td>"; echo "<form action=eleve_edite.php>"; echo "<input type=hidden name=id value=$id />"; echo "<input type=submit value=voir />"; echo "</form>"; echo "</td>"; echo "</tr>"; } echo "</table>";

mysql_close($liendb); echo echo ?> "</body>"; "</html>";

LE GUIDE COMPLET 293

Chapitre 11

La gestion dune base de donnes

Figure 11.1 : Page daccueil

crivez dans la foule une version allge du script eleve_edite.php, qui est utilis par admin.php an dafficher le prol dun lve :
Listing 11-2 : eleve_edite.php <?php echo echo echo echo echo "<html>"; "<head>"; "<title>Admin "</head>"; "<body>";

Ecole</title>";

$liendb = mysql_connect("localhost", mysql_select_db ("test");

"root",

"");

echo "<h1>admin - ecole</h1>"; echo "<p align=left> :: fiche deleve [".$_REQUEST[id]."]</p>"; $sql = "SELECT * FROM eleve WHERE ideleve ".$_REQUEST[id].""; $resultat = mysql_query ($sql); $eleve = mysql_fetch_array ($resultat); echo "-> " . $eleve[nom] . "<br/>"; =

mysql_close($liendb); echo echo ?> "</body>"; "</html>";

294 LE GUIDE COMPLET

Lauthentification

Chapitre 11

Figure 11.2 : Visualisation dun lve

Vous remarquez que, pour visualiser le prol dun lve, vous avez gnr un formulaire par ligne dans le tableau. Si vous cliquez sur un bouton voir, vous vous apercevez que lURL qui apparat dans la barre dadresse est de la forme http://localhost/eleve_edite.php?id=2. Ce formulaire intermdiaire peut apparatre quelque peu superu. Il sagit dun exemple typique o lutilisation de la Query String est conseille. Modiez la boucle en ce sens :

Figure 11.3 : Utilisation dun lien pour transmettre de linformation

LE GUIDE COMPLET 295

Chapitre 11

La gestion dune base de donnes

while ($eleve = mysql_fetch_array ($resultat)) { $id = $eleve[ideleve]; $nom = $eleve[nom]; $prenom = $eleve[prenom]; $date = $eleve[naissance]; echo "<tr>"; echo "<td>$id</td>"; echo "<td>$nom</td>"; echo "<td>$prenom</td>"; echo "<td>$date</td>"; echo "<td>"; echo "<a href=eleve_edite.php?id=$id>voir</a>"; echo "</td>"; echo "</tr>"; }

11.2. La mise jour dune table


Votre chier eleve_edite.php est pour linstant trs sommaire. Cette partie va vous permettre de le complter par :
j j

laffichage de toutes les donnes de llve dans un formulaire ; lenregistrement des donnes modies.

Commencez par faire en sorte quil affiche les donnes :


Listing 11-3 : Script avec affichage des donnes <?php echo echo echo echo echo "<html>"; "<head>"; "<title>Admin Ecole</title>"; "</head>"; "<body>";

$liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); echo "<h1>admin - ecole</h1>"; echo "<p align=left> :: fiche deleve [".$_REQUEST[id]."]</p>"; $sql = "SELECT * FROM eleve WHERE ideleve = ".$_REQUEST[id].""; $resultat = mysql_query ($sql); $eleve = mysql_fetch_array ($resultat); ?>

296 LE GUIDE COMPLET

La mise jour dune table

Chapitre 11

<form action="eleve_enregistre.php" method="post"> <input type="hidden" name="enregistre" value="oui" /> <input type="hidden" name="id" value="<?php echo $_REQUEST[id]; ?>" /> <table> <tr> <td>nom</td> <td><input type="text" name="nom" value="<?php echo $eleve[nom]; ?>" /></td> </tr> <tr> <td>prnom</td> <td><input type="text" name="prenom" value="<?php echo $eleve[prenom]; ?>" /></td> </tr> <tr> <td>adresse</td> <td><textarea name="adresse"><?php echo $eleve[adresse]; ?> </textarea></td> </tr> <tr> <td>ville</td> <td><input type="text" name="ville" value="<?php echo $eleve[ville]; ?>" /></td> </tr> <tr> <td>code postal</td> <td><input type="text" name="codepostal" value="<?php echo $eleve[cp]; ?>" /></td> </tr> <tr> <td>pays</td> <td><input type="text" name="pays" value="<?php echo $eleve[pays]; ?>" /></td> </tr> <tr> <td>sexe</td> <td> M <input type="radio" name="sexe" value="masculin" <?php if ($eleve[sexe] == "masculin") echo "CHECKED"; ?>> F <input type="radio" name="sexe" value="feminin" <?php if ($eleve[sexe] == "feminin") echo "CHECKED"; ?>> </td> </tr> <tr> <td>date naissance</td> <td><input type="text" name="naissance" value="<?php echo $eleve[naissance]; ?>" /></td> </tr>
LE GUIDE COMPLET 297

Chapitre 11

La gestion dune base de donnes

<tr> <td>taille (cm)</td> <td><input type="text" name="taille" value="<?php echo $eleve[taille]; ?>" /></td> </tr> <tr> <td>email</td> <td><input type="text" name="email" value="<?php echo $eleve[email]; ?>" /></td> </tr> <tr> <td>tlphone</td> <td><input type="text" name="telephone" value="<?php echo $eleve[telephone]; ?>" /></td> </tr> <tr> <td>langue vivante</td> <td> <select name="lv"> <option value="anglais"> anglais </option> <option value="espagnol" <?php if ($eleve[lv] == "espagnol") echo "SELECTED"; ?>> espagnol </option> <option value="allemand" <?php if ($eleve[v] == "allemand") echo "SELECTED"; ?>> allemand </option> </select> </td> </tr> </table> <br/> <input type="submit" value="enregistrer" /> </form> </body> </html> <?php mysql_close($liendb); ?>

298 LE GUIDE COMPLET

La mise jour dune table

Chapitre 11

Figure 11.4 : Formulaire prrempli avec les donnes de llve

Ce script montre comment prremplir un formulaire. Suivant les types de widgets, la mthode nest pas la mme.
j

input text : la valeur est place dans linput avec la proprit value.
value="<?php echo $eleve[nom]; ?>"

j j

textarea : la valeur est place entre les balises <textarea> et </textarea>. input radio : le terme CHECKED doit tre plac dans linput

valide. Il est donc ncessaire de procder un test pour savoir lequel est valide.
<?php if ($eleve[sexe] == "masculin") echo "CHECKED"; ?>
j

select : le terme SELECTED doit tre plac dans loption valide.

Il est donc ncessaire de faire un test pour savoir quelle est la bonne langue vivante.
<?php if ($eleve[v] == "allemand") echo "SELECTED"; ?>

LE GUIDE COMPLET 299

Chapitre 11

La gestion dune base de donnes

Linstruction input hidden


Vous remarquez aussi, en dessous de la balise <form>, la prsence des deux lignes suivantes :
<input <input type="hidden" name="enregistre" type="hidden" name="id" value="<?php echo $id; ?>"> value="oui">

Il sagit dun input particulier qui permet de transmettre une valeur, sans pour autant avoir de rpercussion au niveau visuel. Le champ est cach (hidden). Vous avez ajout le premier champ car vous souhaitez raliser laction de mise jour dans le mme chier : eleve_edite.php. Ce champ va permettre de raliser un test en dbut de script sur la prsence ou non de la variable $_REQUEST[enregistre]. Si elle est prsente, vous effectuerez laction de mise jour, puis vous afficherez le formulaire mis jour ; sinon, vous vous contenterez dafficher le formulaire. Le deuxime champ permet, quant lui, de propager lidentiant de llve. Si cette ligne ntait pas prsente, le script serait incapable de trouver la ligne de la table mettre jour, car la valeur $_REQUEST[id] ne serait pas transmise.

La commande UPDATE
La nouvelle commande SQL que vous allez utiliser pour mettre jour la table est UPDATE, dont la syntaxe est la suivante :
UPDATE nom_table SET nom1 = valeur1, nom2 = valeur2... WHERE condition

Dans ce cas, vous avez 12 champs mettre jour, et la condition est simple : mettre jour la ligne ayant pour ideleve la valeur $_REQUEST[id]. Pour mettre jour le nom et le prnom, la requte prend la forme suivante :
UPDATE eleve SET nom=".$_REQUEST[nom]." WHERE ideleve=".$_REQUEST[id]."

La clause

Si vous naviez pas ajout la clause WHERE ideleve = $id, cest lensemble de la table qui aurait t mis jour. Toutes les lignes seraient devenues identiques. De la mme manire, vous auriez mis jour
300 LE GUIDE COMPLET

La mise jour dune table

Chapitre 11

plusieurs lignes (tous les garons) si vous aviez choisi une clause du type WHERE sexe = masculin.

crivez le code permettant la mise jour :


$sql = "UPDATE eleve SET nom = ".$_REQUEST[nom].",". "prenom = ".$_REQUEST[prenom].",". "adresse = ".$_REQUEST[adresse].",". "ville = ".$_REQUEST[ville].",". "cp = ".$_REQUEST[codepostal].",". "pays = ".$_REQUEST[pays].",". "sexe = ".$_REQUEST[sexe].",". "naissance = ".$_REQUEST[naissance].",". "taille = ".$_REQUEST[taille].",". "email = ".$_REQUEST[email].",". "telephone = ".$_REQUEST[telephone].",". "lv = ".$_REQUEST[lv]."". " WHERE ideleve = ".$_REQUEST[id]."";

La mise jour se fait directement avec les valeurs transmises. Ce nest pas trs judicieux dans la mesure o vous aviez mis en place toute une politique de vrication de champs pour la cration. Rajoutez donc tous ces tests :
if ($_REQUEST[enregistre] == "oui") { if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[ville]) || empty($_REQUEST[codepostal]) || empty($_REQUEST[pays]) || empty($_REQUEST[naissance]) || empty($_REQUEST[telephone]) || empty($_REQUEST[lv])) die("ERREUR : tous les champs doivent tre remplis."); if ($_REQUEST[sexe]!="masculin" && $_REQUEST[sexe]!="feminin") die("ERREUR : choisissez votre sexe."); $reg_email = "/^[\w\.-]+@[\w\.-]+\.[a-z]{2,3}$/i"; if (preg_match($reg_email,$_REQUEST[email]) == 0) die("ERREUR : adresse email non valide."); if ($_REQUEST[taille]<=100 || $_REQUEST[taille]>=220) die("ERREUR : la taille nest pas valide.");

LE GUIDE COMPLET 301

Chapitre 11

La gestion dune base de donnes

$sql = "UPDATE eleve SET nom = ".$_REQUEST[nom].",". "prenom = ".$_REQUEST[prenom].",". "adresse = ".$_REQUEST[adresse].",". "ville = ".$_REQUEST[ville].",". "cp = ".$_REQUEST[codepostal].",". "pays = ".$_REQUEST[pays].",". "sexe = ".$_REQUEST[sexe].",". "naissance = ".$_REQUEST[naissance].",". "taille = ".$_REQUEST[taille].",". "email = ".$_REQUEST[email].",". "telephone = ".$_REQUEST[telephone].",". "lv = ".$_REQUEST[lv]."". " WHERE ideleve = ".$_REQUEST[id].""; mysql_query ($sql); }

En rassemblant toutes les parties, votre script eleve_edite.php prend la forme suivante :
<?php echo echo echo echo echo "<html>"; "<head>"; "<title>Admin Ecole</title>"; "</head>"; "<body>";

$liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); if ($_REQUEST[enregistre] == "oui") { if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[ville]) || empty($_REQUEST[codepostal]) || empty($_REQUEST[pays]) || empty($_REQUEST[naissance]) || empty($_REQUEST[telephone]) || empty($_REQUEST[lv])) die("ERREUR : tous les champs doivent tre remplis."); if ($_REQUEST[sexe]!="masculin" && $_REQUEST[sexe]!="feminin") die("ERREUR : choisissez votre sexe."); $reg_email = "/^[\w\.-]+@[\w\.-]+\.[a-z]{2,3}$/i"; if (preg_match($reg_email,$_REQUEST[email]) == 0) die("ERREUR : adresse email non valide.");

302 LE GUIDE COMPLET

La mise jour dune table

Chapitre 11

if ($_REQUEST[taille]<=100 || $_REQUEST[taille]>=220) die("ERREUR : la taille nest pas valide."); $sql = "UPDATE eleve SET nom = ".$_REQUEST[nom].",". "prenom = ".$_REQUEST[prenom].",". "adresse = ".$_REQUEST[adresse].",". "ville = ".$_REQUEST[ville].",". "cp = ".$_REQUEST[codepostal].",". "pays = ".$_REQUEST[pays].",". "sexe = ".$_REQUEST[sexe].",". "naissance = ".$_REQUEST[naissance].",". "taille = ".$_REQUEST[taille].",". "email = ".$_REQUEST[email].",". "telephone = ".$_REQUEST[telephone].",". "lv = ".$_REQUEST[lv]."". " WHERE ideleve = ".$_REQUEST[id].""; mysql_query ($sql); } echo "<h1>admin - ecole</h1>"; echo "<p align=left> :: fiche dlve [".$_REQUEST[id]."]</p>"; $sql = "SELECT * FROM eleve WHERE ideleve = ".$_REQUEST[id].""; $resultat = mysql_query ($sql); $eleve = mysql_fetch_array ($resultat); ?> <form action="eleve_edite.php" method="post"> <input type="hidden" name="enregistre" value="oui" /> <input type="hidden" name="id" value="<?php echo $_REQUEST[id]; ?>" /> <table> <tr> <td>nom</td> <td><input type="text" name="nom" value="<?php echo $eleve[nom]; ?>" /></td> </tr> <tr> <td>prnom</td> <td><input type="text" name="prenom" value="<?php echo $eleve[prenom]; ?>" /></td> </tr> <tr> <td>adresse</td> <td><textarea name="adresse"><?php echo $eleve[adresse]; ?> </textarea></td>
LE GUIDE COMPLET 303

Chapitre 11

La gestion dune base de donnes

</tr> <tr> <td>ville</td> <td><input type="text" name="ville" value="<?php echo $eleve[ville]; ?>" /></td> </tr> <tr> <td>code postal</td> <td><input type="text" name="codepostal" value="<?php echo $eleve[cp]; ?>" /></td> </tr> <tr> <td>pays</td> <td><input type="text" name="pays" value="<?php echo $eleve[pays]; ?>" /></td> </tr> <tr> <td>sexe</td> <td> M <input type="radio" name="sexe" value="masculin" <?php if ($eleve[sexe] == "masculin") echo "CHECKED"; ?>> F <input type="radio" name="sexe" value="feminin" <?php if ($eleve[sexe] == "feminin") echo "CHECKED"; ?>> </td> </tr> <tr> <td>date naissance</td> <td><input type="text" name="naissance" value="<?php echo $eleve[naissance]; ?>" /></td> </tr> <tr> <td>taille (cm)</td> <td><input type="text" name="taille" value="<?php echo $eleve[taille]; ?>" /></td> </tr> <tr> <td>email</td> <td><input type="text" name="email" value="<?php echo $eleve[email]; ?>" /></td> </tr> <tr> <td>tlphone</td> <td><input type="text" name="telephone" value="<?php echo $eleve[telephone]; ?>" /></td> </tr> <tr> <td>langue vivante</td> <td> <select name="lv"> <option value="anglais"> anglais </option>
304 LE GUIDE COMPLET

La mise jour dune table


<option value="espagnol" "espagnol") echo "SELECTED"; ?>> espagnol <option value="allemand" "allemand") echo "SELECTED"; ?>> allemand </select> </td> </tr> </table> <br/> <input type="submit" value="enregistrer" /> </form> </body> </html> <?php mysql_close($liendb); ?>

Chapitre 11

<?php if ($eleve[lv] == </option> <?php if ($eleve[v] == </option>

Le chier eleve_edite.php contient donc la fois le formulaire et le script. Cette solution peut tre intressante pour diminuer le nombre de chiers de votre applicatif. Le ct ngatif est laugmentation de la taille du script qui devient ainsi moins lisible. Appliquez cette technique la cration de prol, en fusionnant les chiers ajout_eleve.html et eleve_enregistre.php en un chier eleve_ajoute.php :
<?php if { ($_REQUEST[enregistre]=="oui" && $_REQUEST[id]>=1) $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[ville]) || empty($_REQUEST[codepostal]) || empty($_REQUEST[pays]) || empty($_REQUEST[naissance]) || empty($_REQUEST[telephone]) || empty($_REQUEST[lv])) die("ERREUR : tous les champs doivent tre remplis.");

LE GUIDE COMPLET 305

Chapitre 11

La gestion dune base de donnes

if ($_REQUEST[sexe]!="masculin" && $_REQUEST[sexe]!="feminin") die("ERREUR : choisissez votre sexe."); $reg_email = "/^[\w\.-]+@[\w\.-]+\.[a-z]{2,3}$/i"; if (preg_match($reg_email,$_REQUEST[email]) == 0) die("ERREUR : adresse email non valide."); if ($_REQUEST[taille]<=100 || $_REQUEST[taille]>=220) die("ERREUR : la taille nest pas valide."); $sql = "INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv) VALUES (". "".$_REQUEST[nom].",". "".$_REQUEST[prenom].",". "".$_REQUEST[adresse].",". "".$_REQUEST[ville].",". "".$_REQUEST[codepostal].",". "".$_REQUEST[pays].",". "".$_REQUEST[sexe].",". "".$_REQUEST[naissance].",". "".$_REQUEST[taille].",". "".$_REQUEST[email].",". "".$_REQUEST[telephone].",". "".$_REQUEST[lv].")"; mysql_query ($sql); mysql_close($liendb); header("location: http://localhost/admin.php"); } echo echo echo echo echo "<html>"; "<head>"; "<title>Admin Ecole</title>"; "</head>"; "<body>";

echo "<h1>admin - ecole</h1>"; echo "<p align=left> :: ajouter un lve [".$_REQUEST[id]."]</p>"; ?> <form action="eleve_ajoute.php" method="post"> <input type="hidden" name="enregistre" value="oui" /> <table> <tr> <td>nom</td>
306 LE GUIDE COMPLET

La mise jour dune table

Chapitre 11

<td><input type="text" name="nom" /></td> </tr> <tr> <td>prnom</td> <td><input type="text" name="prenom" /></td> </tr> <tr> <td>adresse</td> <td><textarea name="adresse"></textarea></td> </tr> <tr> <td>ville</td> <td><input type="text" name="ville" /></td> </tr> <tr> <td>code postal</td> <td><input type="text" name="codepostal" /></td> </tr> <tr> <td>pays</td> <td><input type="text" name="pays" /></td> </tr> <tr> <td>sexe</td> <td> M <input type="radio" name="sexe" value="masculin" /> F <input type="radio" name="sexe" value="feminin" /> </td> </tr> <tr> <td>date naissance</td> <td><input type="text" name="naissance" /></td> </tr> <tr> <td>taille (cm)</td> <td><input type="text" name="taille" /></td> </tr> <tr> <td>email</td> <td><input type="text" name="email" /></td> </tr> <tr> <td>tlphone</td> <td><input type="text" name="telephone" /></td> </tr> <tr> <td>langue vivante</td> <td> <select name="lv"> <option value="anglais"> anglais </option> <option value="espagnol"> espagnol </option>
LE GUIDE COMPLET 307

Chapitre 11

La gestion dune base de donnes

<option value="allemand"> allemand </option> </select> </td> </tr> </table> <br/> <input type="submit" value="enregistrer" /> </form> </body> </html>

Aprs lajout la base, vous basculez sur la liste des lves. Pour cela, vous transmettez au navigateur la directive HTTP location grce la fonction PHP header(). Linstruction est la suivante :
header("location: http://localhost/admin.php");

11.3. La suppression : DELETE


Le chier eleve_edite.php permet dj de mettre jour les informations du prol "lve". Vous allez maintenant faire en sorte de pouvoir supprimer un prol dlve depuis ce chier. La commande SQL utilise pour une suppression denregistrement est
DELETE. La syntaxe est la suivante :
DELETE FROM nom_table WHERE clause

Si vous souhaitez effacer la ligne dont lideleve est 4, crivez :


DELETE FROM eleve WHERE ideleve = 4

Pour pouvoir inclure le code de mise jour, vous aviez ajout un input hidden qui indiquait au script de raliser laction de mise jour. Deux actions sont dsormais possibles : la mise jour et leffacement. La technique nest donc plus valide. Pour contourner le problme, remplacez le bouton enregistre par un menu droulant et un bouton. Le menu droulant permettra de choisir laction raliser sur la che ; il portera le nom "action". Ainsi, plutt

308 LE GUIDE COMPLET

La suppression : DELETE

Chapitre 11

que tester la variable $_REQUEST[enregistre], vous allez tester la variable $_REQUEST[action] et agir en fonction de sa valeur.

Figure 11.5 : Mise jour dune che lve

Le menu droulant prend la forme suivante :


<select name="action"> <option value="maj"> Enregistrer <option value="suppr"> Supprimer </select> <input type="submit" la la fiche fiche </option> </option>

value="effectuer">

Et le test devient :
if { ($_REQUEST[action]=="maj") if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[ville]) || empty($_REQUEST[codepostal]) || empty($_REQUEST[pays]) ||

LE GUIDE COMPLET 309

Chapitre 11

La gestion dune base de donnes

empty($_REQUEST[naissance]) || empty($_REQUEST[telephone]) || empty($_REQUEST[lv])) die("ERREUR : tous les champs doivent tre remplis."); if ($_REQUEST[sexe]!="masculin" && $_REQUEST[sexe]!="feminin") die("ERREUR : choisissez votre sexe."); $reg_email = "/^[\w\.-]+@[\w\.-]+\.[a-z]{2,3}$/i"; if (preg_match($reg_email,$_REQUEST[email]) == 0) die("ERREUR : adresse email non valide."); if ($_REQUEST[taille]<=100 || $_REQUEST[taille]>=220) die("ERREUR : la taille nest pas valide."); $sql = "UPDATE eleve SET nom = ".$_REQUEST[nom].",". "prenom = ".$_REQUEST[prenom].",". "adresse = ".$_REQUEST[adresse].",". "ville = ".$_REQUEST[ville].",". "cp = ".$_REQUEST[codepostal].",". "pays = ".$_REQUEST[pays].",". "sexe = ".$_REQUEST[sexe].",". "naissance = ".$_REQUEST[naissance].",". "taille = ".$_REQUEST[taille].",". "email = ".$_REQUEST[email].",". "telephone = ".$_REQUEST[telephone].",". "lv = ".$_REQUEST[lv]."". " WHERE ideleve = ".$_REQUEST[id].""; mysql_query ($sql); } elseif ($_REQUEST[action]=="suppr" && $_REQUEST[id]>=1) { $sql = "DELETE FROM eleve WHERE ideleve=".$_REQUEST[id].""; mysql_query ($sql); }

Si vous supprimez le prol, vous ne devez surtout pas continuer excuter le script, sous peine de gnrer une erreur. Il est en effet impossible dafficher un prol dlve qui nest plus prsent dans la table. Vous allez donc rutiliser linstruction suivante :
header("location: http://localhost/admin.php");

310 LE GUIDE COMPLET

La suppression : DELETE

Chapitre 11

Avant dutiliser cette ligne, il est cependant ncessaire de modier lgrement le script. En effet, vous avez vu dans un chapitre prcdent que la fonction header() ne pouvait tre appele que si aucun affichage navait encore eu lieu. Or, votre script prsente les cinq lignes suivantes :
echo echo echo echo echo "<html>"; "<head>"; "<title>Admin "</head>"; "<body>"; Ecole</title>";

Vous tes donc contraint de les dplacer plus bas dans le script, au moins en dessous de la fonction header(). Le script nal devient donc :
<?php $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); if { ($_REQUEST[action]=="maj") if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[ville]) || empty($_REQUEST[codepostal]) || empty($_REQUEST[pays]) || empty($_REQUEST[naissance]) || empty($_REQUEST[telephone]) || empty($_REQUEST[lv])) die("ERREUR : tous les champs doivent tre remplis."); if ($_REQUEST[sexe]!="masculin" && $_REQUEST[sexe]!="feminin") die("ERREUR : choisissez votre sexe."); $reg_email = "/^[\w\.-]+@[\w\.-]+\.[a-z]{2,3}$/i"; if (preg_match($reg_email,$_REQUEST[email]) == 0) die("ERREUR : adresse email non valide."); if ($_REQUEST[taille]<=100 || $_REQUEST[taille]>=220) die("ERREUR : la taille nest pas valide."); $sql = "UPDATE eleve SET nom = ".$_REQUEST[nom].",". "prenom = ".$_REQUEST[prenom].",". "adresse = ".$_REQUEST[adresse].",". "ville = ".$_REQUEST[ville].",".

LE GUIDE COMPLET 311

Chapitre 11

La gestion dune base de donnes


"cp = ".$_REQUEST[codepostal].",". "pays = ".$_REQUEST[pays].",". "sexe = ".$_REQUEST[sexe].",". "naissance = ".$_REQUEST[naissance].",". "taille = ".$_REQUEST[taille].",". "email = ".$_REQUEST[email].",". "telephone = ".$_REQUEST[telephone].",". "lv = ".$_REQUEST[lv]."". " WHERE ideleve = ".$_REQUEST[id]."";

mysql_query ($sql); } elseif ($_REQUEST[action]=="suppr" && $_REQUEST[id]>=1) { $sql = "DELETE FROM eleve WHERE ideleve=".$_REQUEST[id].""; mysql_query ($sql); header("Location: http://localhost/admin.php"); } echo echo echo echo echo "<html>"; "<head>"; "<title>Admin Ecole</title>"; "</head>"; "<body>";

echo "<h1>admin - ecole</h1>"; echo "<p align=left> :: fiche dlve [".$_REQUEST[id]."]</p>"; $sql = "SELECT * FROM eleve WHERE ideleve = ".$_REQUEST[id].""; $resultat = mysql_query ($sql); $eleve = mysql_fetch_array ($resultat); ?> <form action="eleve_edite.php" method="post"> <input type="hidden" name="enregistre" value="oui" /> <input type="hidden" name="id" value="<?php echo $_REQUEST[id]; ?>" /> <table> <tr> <td>nom</td> <td><input type="text" name="nom" value="<?php echo $eleve[nom]; ?>" /></td> </tr> <tr> <td>prnom</td>
312 LE GUIDE COMPLET

La suppression : DELETE

Chapitre 11

<td><input type="text" name="prenom" value="<?php echo $eleve[prenom]; ?>" /></td> </tr> <tr> <td>adresse</td> <td><textarea name="adresse"><?php echo $eleve[adresse]; ?></textarea></td> </tr> <tr> <td>ville</td> <td><input type="text" name="ville" value="<?php echo $eleve[ville]; ?>" /></td> </tr> <tr> <td>code postal</td> <td><input type="text" name="codepostal" value="<?php echo $eleve[cp]; ?>" /></td> </tr> <tr> <td>pays</td> <td><input type="text" name="pays" value="<?php echo $eleve[pays]; ?>" /></td> </tr> <tr> <td>sexe</td> <td> M <input type="radio" name="sexe" value="masculin" <?php if ($eleve[sexe] == "masculin") echo "CHECKED"; ?>> F <input type="radio" name="sexe" value="feminin" <?php if ($eleve[sexe] == "feminin") echo "CHECKED"; ?>> </td> </tr> <tr> <td>date naissance</td> <td><input type="text" name="naissance" value="<?php echo $eleve[naissance]; ?>" /></td> </tr> <tr> <td>taille (cm)</td> <td><input type="text" name="taille" value="<?php echo $eleve[taille]; ?>" /></td> </tr> <tr> <td>email</td> <td><input type="text" name="email" value="<?php echo $eleve[email]; ?>" /></td> </tr> <tr> <td>tlphone</td> <td><input type="text" name="telephone" value="<?php echo $eleve[telephone]; ?>" /></td>
LE GUIDE COMPLET 313

Chapitre 11

La gestion dune base de donnes

</tr> <tr> <td>langue vivante</td> <td> <select name="lv"> <option value="anglais"> <option value="espagnol" "espagnol") echo "SELECTED"; ?>> espagnol <option value="allemand" "allemand") echo "SELECTED"; ?>> allemand </select> </td> </tr> </table> <br/>

anglais </option> <?php if ($eleve[lv] == </option> <?php if ($eleve[v] == </option>

<select name="action"> <option value="maj"> Enregistrer <option value="suppr"> Supprimer </select> <input </form> </body> </html> <?php mysql_close($liendb); ?> type="submit"

la la

fiche fiche

</option> </option>

value="effectuer">

Fonction mysql_close()

Il est prfrable de toujours fermer la connexion la base. Vous quittez le script prmaturment si laction correspond une suppression. Vous en protez pour fermer la connexion juste avant de raliser la redirection (header()).

11.4. La factorisation du code


Si vous laissez les scripts eleve_edite.php et eleve_ajoute.php comme ils sont, vous pouvez avoir des craintes quant la validit de vos donnes. Il est en effet ncessaire de sidentier pour avoir accs la page daccueil contenant la liste des lves, mais aucune vrication nest
314 LE GUIDE COMPLET

La factorisation du code

Chapitre 11

faite sur lajout ou la modication (suppression). Toute personne tapant directement eleve_edite.php?id=6 peut modier sans problme le contenu de la page. Il est donc ncessaire de forcer lidentication en haut de chaque script :
if (!($_SERVER[PHP_AUTH_USER]=="essai" && $_SERVER[PHP_AUTH_PW]=="essai")) { header("status: 401 Unauthorized"); header("HTTP/1.0 401 Unauthorized"); header("WWW-authenticate: Basic realm=\"acces securise\""); print("verification : ERREUR"); exit(0); }

Cette solution est cependant loin dtre optimale. crire ce code plusieurs endroits entrane une perte de temps et un risque accru de laisser des erreurs. De plus, si vous voulez modier le code daccs en essai2/essai2, vous serez oblig daller modier tous les chiers, ce qui compliquerait la mise jour.

La fonction include
Pour viter cet cueil, PHP vous propose la fonction include(). Elle permet, depuis un script A, dappeler un chier B. Vous pouvez donc crer un chier identification.inc.php, et lappeler au dbut de chaque script devant tre protg :
<?php if (!($_SERVER[PHP_AUTH_USER]=="essai" && $_SERVER[PHP_AUTH_PW]=="essai")) { header("status: 401 Unauthorized"); header("HTTP/1.0 401 Unauthorized"); header("WWW-authenticate: Basic realm=\"acces securise\""); print("verification : ERREUR"); exit(0); } ?>

Cette technique permet de modier la gestion de lidentication en un instant, quil y ait 5 ou 5000 scripts dans votre applicatif.

LE GUIDE COMPLET 315

Chapitre 11

La gestion dune base de donnes

Dans la mme veine, vous pouvez aussi remarquer lutilisation dans plusieurs scripts dune connexion une base de donnes. En ayant lesprit la fonction include() et en tant suffisamment paresseux, il vous viendra tout de suite lide de crer le chier variables.inc.php :
Listing 11-4 : variables.inc.php <?php $bddserver = "localhost"; $bddlogin = "root"; $bddpassword = ""; $bdd = "test"; $table_eleve = "eleve"; $url = "http://localhost"; ?>

Ce chier est aussi inclus en haut de tous les scripts et vous permet de dplacer votre applicatif dun hbergeur vers un autre sans le moindre souci. Tous les paramtres susceptibles de changer sont isols dans un chier unique. Stocker de telles variables dans un chier extrieur est donc une bonne habitude prendre. Ne nous arrtons pas l dans cette qute factorisatrice et regardons du ct du visuel Chaque page dispose du mme en-tte et du mme pied de page. Comme il y a fort parier qu un moment ou un autre vous vouliez amliorer visuellement lensemble et placer sur chaque page une rfrence un copyright, il pourrait donc tre tout fait judicieux de crer les chiers haut.inc.php et bas.inc.php :
Listing 11-5 : haut.inc.php <html> <head> <title>Admin Ecole</title> </head> <body> <h1>Admin - Ecole</h1> Listing 11-6 : bas.inc.php </body> </html>

Chaque script du back-office sera donc construit de la faon suivante :


j

appel var.inc.php ;

316 LE GUIDE COMPLET

La factorisation du code
j j j j

Chapitre 11

appel identification.inc.php ; appel haut.inc.php ; le contenu proprement dit du script ; bas.inc.php.

Modiez en ce sens les chiers admin.php, eleve_ajoute.php, et


eleve_edite.php :
Listing 11-7 : admin.php <?php include("variables.inc.php"); include("identification.inc.php"); include("haut.inc.php"); $liendb = mysql_connect ($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM eleve"; $resultat = mysql_query ($sql); echo "<p align=left> :: accueil</p>"; echo "<table width=90% align=center border=1>"; echo "<tr><td>id</td><td>nom</td><td>prenom</td> <td>naissance</td><td> </td></tr>"; while ($eleve = mysql_fetch_array ($resultat)) { $id = $eleve[ideleve]; $nom = $eleve[nom]; $prenom = $eleve[prenom]; $date = $eleve[naissance]; echo "<tr>"; echo "<td>$id</td>"; echo "<td>$nom</td>"; echo "<td>$prenom</td>"; echo "<td>$date</td>"; echo "<td>"; echo "<a href=eleve_edite.php?id=$id>voir</a>"; echo "</td>"; echo "</tr>"; } echo "</table>"; mysql_close($liendb);

LE GUIDE COMPLET 317

Chapitre 11

La gestion dune base de donnes

include("bas.inc.php"); ?> Listing 11-8 : eleve_ajoute.inc.php <?php include("variables.inc.php"); include("identification.inc.php"); if { ($_REQUEST[enregistre] == "oui") $liendb = mysql_connect ($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[ville]) || empty($_REQUEST[codepostal]) || empty($_REQUEST[pays]) || empty($_REQUEST[naissance]) || empty($_REQUEST[telephone]) || empty($_REQUEST[lv])) die("ERREUR : tous les champs doivent tre remplis."); if ($_REQUEST[sexe]!="masculin" && $_REQUEST[sexe]!="feminin") die("ERREUR : choisissez votre sexe."); $reg_email = "/^[\w\.-]+@[\w\.-]+\.[a-z]{2,3}$/i"; if (preg_match($reg_email,$_REQUEST[email]) == 0) die("ERREUR : adresse email non valide."); if ($_REQUEST[taille]<=100 || $_REQUEST[taille]>=220) die("ERREUR : la taille nest pas valide."); $sql = "INSERT INTO eleve (nom, prenom, adresse, ville, cp, pays, sexe, naissance, taille, email, telephone, lv) VALUES (". "".$_REQUEST[nom].",". "".$_REQUEST[prenom].",". "".$_REQUEST[adresse].",". "".$_REQUEST[ville].",". "".$_REQUEST[codepostal].",". "".$_REQUEST[pays].",". "".$_REQUEST[sexe].",". "".$_REQUEST[naissance].",". "".$_REQUEST[taille].",".

318 LE GUIDE COMPLET

La factorisation du code
"".$_REQUEST[email].",". "".$_REQUEST[telephone].",". "".$_REQUEST[lv].")"; mysql_query ($sql); mysql_close($liendb); header("location: http://localhost/admin.php"); } include("haut.inc.php"); echo "<p align=left> :: ajouter un lve [".$_REQUEST[id]."]</p>"; ?>

Chapitre 11

<form action="eleve_ajoute.php" method="post"> <input type="hidden" name="enregistre" value="oui" /> <table> <tr> <td>nom</td> <td><input type="text" name="nom" /></td> </tr> <tr> <td>prnom</td> <td><input type="text" name="prenom" /></td> </tr> <tr> <td>adresse</td> <td><textarea name="adresse"></textarea></td> </tr> <tr> <td>ville</td> <td><input type="text" name="ville" /></td> </tr> <tr> <td>code postal</td> <td><input type="text" name="codepostal" /></td> </tr> <tr> <td>pays</td> <td><input type="text" name="pays" /></td> </tr> <tr> <td>sexe</td> <td> M <input type="radio" name="sexe" value="masculin" /> F <input type="radio" name="sexe" value="feminin" /> </td>
LE GUIDE COMPLET 319

Chapitre 11

La gestion dune base de donnes

</tr> <tr> <td>date naissance</td> <td><input type="text" name="naissance" /></td> </tr> <tr> <td>taille (cm)</td> <td><input type="text" name="taille" /></td> </tr> <tr> <td>email</td> <td><input type="text" name="email" /></td> </tr> <tr> <td>tlphone</td> <td><input type="text" name="telephone" /></td> </tr> <tr> <td>langue vivante</td> <td> <select name="lv"> <option value="anglais"> anglais </option> <option value="espagnol"> espagnol </option> <option value="allemand"> allemand </option> </select> </td> </tr> </table> <br/> <input type="submit" value="enregistrer" /> </form> <?php include ("bas.inc.php"); ?> Listing 11-9 : eleve_edite.php <?php include ("variables.inc.php"); include ("identification.inc.php"); $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); if { ($_REQUEST[action]=="maj") if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) ||

320 LE GUIDE COMPLET

La factorisation du code
empty($_REQUEST[adresse]) || empty($_REQUEST[ville]) || empty($_REQUEST[codepostal]) || empty($_REQUEST[pays]) || empty($_REQUEST[naissance]) || empty($_REQUEST[telephone]) || empty($_REQUEST[lv])) die("ERREUR : tous les champs doivent tre remplis."); if ($_REQUEST[sexe]!="masculin" && $_REQUEST[sexe]!="feminin") die("ERREUR : choisissez votre sexe.");

Chapitre 11

$reg_email = "/^[\w\.-]+@[\w\.-]+\.[a-z]{2,3}$/i"; if (preg_match($reg_email,$_REQUEST[email]) == 0) die("ERREUR : adresse email non valide."); if ($_REQUEST[taille]<=100 || $_REQUEST[taille]>=220) die("ERREUR : la taille nest pas valide."); $sql = "UPDATE eleve SET nom = ".$_REQUEST[nom].",". "prenom = ".$_REQUEST[prenom].",". "adresse = ".$_REQUEST[adresse].",". "ville = ".$_REQUEST[ville].",". "cp = ".$_REQUEST[codepostal].",". "pays = ".$_REQUEST[pays].",". "sexe = ".$_REQUEST[sexe].",". "naissance = ".$_REQUEST[naissance].",". "taille = ".$_REQUEST[taille].",". "email = ".$_REQUEST[email].",". "telephone = ".$_REQUEST[telephone].",". "lv = ".$_REQUEST[lv]."". " WHERE ideleve = ".$_REQUEST[id].""; mysql_query ($sql); } elseif ($_REQUEST[action]=="suppr" && $_REQUEST[id]>=1) { $sql = "DELETE FROM eleve WHERE ideleve=".$_REQUEST[id].""; mysql_query ($sql); header("Location: http://localhost/admin.php"); } include("haut.inc.php"); echo "<p align=left> :: fiche dlve [".$_REQUEST[id]."]</p>";

LE GUIDE COMPLET 321

Chapitre 11

La gestion dune base de donnes

$sql = "SELECT * FROM eleve WHERE ideleve = ".$_REQUEST[id].""; $resultat = mysql_query ($sql); $eleve = mysql_fetch_array ($resultat); ?> <form action="eleve_edite.php" method="post"> <input type="hidden" name="enregistre" value="oui" /> <input type="hidden" name="id" value="<?php echo $_REQUEST[id]; ?>" /> <table> <tr> <td>nom</td> <td><input type="text" name="nom" value="<?php echo $eleve[nom]; ?>" /></td> </tr> <tr> <td>prnom</td> <td><input type="text" name="prenom" value="<?php echo $eleve[prenom]; ?>" /></td> </tr> <tr> <td>adresse</td> <td><textarea name="adresse"><?php echo $eleve[adresse]; ?></textarea></td> </tr> <tr> <td>ville</td> <td><input type="text" name="ville" value="<?php echo $eleve[ville]; ?>" /></td> </tr> <tr> <td>code postal</td> <td><input type="text" name="codepostal" value="<?php echo $eleve[cp]; ?>" /></td> </tr> <tr> <td>pays</td> <td><input type="text" name="pays" value="<?php echo $eleve[pays]; ?>" /></td> </tr> <tr> <td>sexe</td> <td> M <input type="radio" name="sexe" value="masculin" <?php if ($eleve[sexe] == "masculin") echo "CHECKED"; ?>> F <input type="radio" name="sexe" value="feminin" <?php if ($eleve[sexe] == "feminin") echo "CHECKED"; ?>> </td>
322 LE GUIDE COMPLET

La factorisation du code

Chapitre 11

</tr> <tr> <td>date naissance</td> <td><input type="text" name="naissance" value="<?php echo $eleve[naissance]; ?>" /></td> </tr> <tr> <td>taille (cm)</td> <td><input type="text" name="taille" value="<?php echo $eleve[taille]; ?>" /></td> </tr> <tr> <td>email</td> <td><input type="text" name="email" value="<?php echo $eleve[email]; ?>" /></td> </tr> <tr> <td>tlphone</td> <td><input type="text" name="telephone" value="<?php echo $eleve[telephone]; ?>" /></td> </tr> <tr> <td>langue vivante</td> <td> <select name="lv"> <option value="anglais"> anglais </option> <option value="espagnol" <?php if ($eleve[lv] == "espagnol") echo "SELECTED"; ?>> espagnol </option> <option value="allemand" <?php if ($eleve[v] == "allemand") echo "SELECTED"; ?>> allemand </option> </select> </td> </tr> </table> <br/> <select name="action"> <option value="maj"> Enregistrer <option value="suppr"> Supprimer </select> <input </form> </body> </html>
LE GUIDE COMPLET 323

la la

fiche fiche

</option> </option>

type="submit"

value="effectuer">

Chapitre 11
<?php

La gestion dune base de donnes

mysql_close ($liendb); include ("bas.inc.php"); ?>

Modiez, tout de suite, les chiers haut.inc.php et bas.inc.php pour vous rendre compte de lintrt de cette action :
<html> <head> <title>Admin Ecole</title> </head> <body> <h1>Admin - Ecole</h1> <center> <hr/> <br/><br/> <hr/> <a href="admin.php">accueil</a> <a href="eleve_ajoute.php">ajouter un <hr> libre </center> </body> </html> lve</a>

Instantanment, tous vos scripts disposent de la nouvelle mise en page. (voir Figure 9.6) En conclusion, il est trs important de toujours avoir lesprit la factorisation de votre code :
j j j

Cela le rend plus lisible, plus facile maintenir, mettre jour, faire voluer. Cela vous fait gagner du temps. Cela rduit la taille du code et ainsi la prsence de bugs.

Cette technique est aussi de plus en plus utilise en front-office, et porte le nom de template. Ces templates permettent de modier trs rapidement lintgralit du site.

324 LE GUIDE COMPLET

La factorisation du code

Chapitre 11

Figure 11.6 : Nouvelle mise en page

Lamlioration visuelle : les CSS


Avant denrichir votre applicatif dautres fonctionnalits, nous allons nous arrter quelques instants sur son aspect visuel. Bien que cela semble souvent secondaire, bien prsenter une page, en jouant sur les couleurs, les polices, etc., peut faciliter considrablement la lisibilit et la comprhension de votre page. Le HTML donne la possibilit de jouer sur les polices, les couleurs, les fonds La premire solution qui vient donc lesprit est de modier directement le code an dinclure des indications visuelles. Pour avoir un tableau avec un fond bleu, vous pouvez crire :
<table bgcolor="blue">

Cependant, cest encore une fois une mauvaise approche car elle na pas lavantage de factoriser le travail. En effet, si vous souhaitez modier la couleur du titre des rubriques, il faut revenir sur tous les scripts et les modier un un.

LE GUIDE COMPLET 325

Chapitre 11

La gestion dune base de donnes

Pour faciliter la gestion de laspect visuel de votre applicatif, vous allez tirer partie des CSS (Cascading Style Sheets). Ce sont des commandes qui permettent, l encore, de modier laspect visuel des pages, et qui ont un double avantage :
j

Vous pouvez apporter des modications plus nes (taille, espacement de lettres, etc.) et plus nombreuses (boutons, menus, etc.). Vous pouvez grer, en un seul endroit, les attributs visuels de toutes les pages.

Les instructions CSS peuvent tre places :


j

directement dans les balises ;


<p style="background: #CCCCCC; color: black;">

dans len-tte de la page.


<html> <head> <style type="text/css"> <!-P {background: #CCCCCC; color: black;} --> </style> </head> </html>

Grce votre factorisation PHP et lexistence de votre chier haut.inc.php, vous allez tre en mesure de modier lintgralit des scripts en nintervenant que sur un chier :
<html> <head> <title>Admin Ecole</title> <style type="text/css"> <!-BODY {background: #D0D8D5;} --> </style> </head> <body> <h1>Admin - Ecole</h1> <center> <hr>

Avec cette modication, toutes vos pages ont dsormais un fond vert trs clair.

326 LE GUIDE COMPLET

La factorisation du code

Chapitre 11

Figure 11.7 : Modication du fond de la page

Sur le mme modle, il est possible de modier lintgralit des lments HTML de vos pages :
<html> <head> <title>Admin Ecole</title> <style type="text/css"> <!-BODY {background:#D0D8D5; color:#01291A; font-family:Verdana; font-size:10px;} H1 {background:#0B3E2B; color:white; font-family:Arial; font-size:20px; font-weight:bold;} P {background:#B6CCC4; color:#0B3E2B; font-family:Arial; font-size:14px; font-weight:bold;} TD

LE GUIDE COMPLET 327

Chapitre 11

La gestion dune base de donnes

{background:white; color:#0B3E2B; font-family:Arial; font-size:14px; font-weight:normal;} INPUT {background:#EBF0EE; color:#01291A; font-family:Verdana; font-size:10px;} TEXTAREA {background:#EBF0EE; color:#01291A; font-family:Verdana; font-size:10px;} SELECT {background:#EBF0EE; color:#01291A; font-family:Verdana; font-size:10px;} HR {color:#0B3E2B;} A {color:#AF6114; font-family:verdana; font-size:10px;} --> </style> </head> <body> <h1>Admin - Ecole</h1> <center> <hr/>

Figure 11.8 : Encore une nouvelle prsentation

328 LE GUIDE COMPLET

La factorisation du code

Chapitre 11

Laspect devient maintenant plus agrable, mais reste encore lgrement monotone. Toutes les cases de vos tableaux ont un fond blanc. Il serait donc prfrable, dans le chier admin.php, de dmarquer la premire ligne, qui contient les intituls des colonnes. Pour cela, il est ncessaire dintervenir dans le chier et dajouter une proprit tous les <td> en question. La proprit est class=nom_de_la_class. Si vous choisissez de lappeler intitule, vous modiez admin.php de cette manire :
echo echo echo echo echo echo echo echo "<table width=90% align=center border=1>"; "<tr>"; "<td class=intitule>id</td>"; "<td class=intitule>nom</td>"; "<td class=intitule>prenom</td>"; "<td class=intitule>naissance</td>"; "<td class=intitule> </td>"; "</tr>";

La prsence de cette classe va vous permettre daffiner votre CSS et de faire en sorte que les cellules de tableaux ayant la classe intitule aient un aspect visuel diffrent. Prcisez-le avec la notation TD.intitule :
<html> <head> <title>Admin Ecole</title> <style type="text/css"> <!-BODY {background:#D0D8D5; color:#01291A; font-family:Verdana; font-size:10px;} H1 {background:#0B3E2B; color:white; font-family:Arial; font-size:20px; font-weight:bold;} P {background:#B6CCC4; color:#0B3E2B; font-family:Arial; font-size:14px; font-weight:bold;} TD {background:white; color:#0B3E2B; font-family:Arial; font-size:14px; font-weight:normal;} TD.intitule {background:#777; color:white; font-family:Arial; font-size:14px; font-weight:bold;} INPUT

LE GUIDE COMPLET 329

Chapitre 11

La gestion dune base de donnes

{background:#EBF0EE; color:#01291A; font-family:Verdana; font-size:10px;} TEXTAREA {background:#EBF0EE; color:#01291A; font-family:Verdana; font-size:10px;} SELECT {background:#EBF0EE; color:#01291A; font-family:Verdana; font-size:10px;} HR {color:#0B3E2B;} A {color:#AF6114; font-family:verdana; font-size:10px;} --> </style> </head> <body> <h1>Admin - Ecole</h1> <center> <hr/>

Vous auriez aussi pu crire :


.intitule {background:#0B3E2B; color:white; font-family:Arial; font-size:14px; font-weight:bold;}

Dans ce cas, toutes les balises ayant la classe intitule auraient partag le mme style, par exemple <p class=intitule>. Une des dernires proprits intressantes des CSS est de permettre de modier le style dun lment de la page en fonction dun vnement. Ainsi, il est possible de changer laspect visuel des liens lorsque vous passez le pointeur de la souris au-dessus :
A:hover {background:#AF6114; color:white; font-family:Verdana; font-size:10px;}

Avant de nir cette partie, il convient de revenir sur quelques inconvnients des CSS :
j j

Certains navigateurs anciens ne grent pas du tout les CSS. Selon les navigateurs, certains styles sont absents ou mal traits.

330 LE GUIDE COMPLET

Recherche et tri au sein dune base

Chapitre 11

Figure 11.9 : Nouvelle prsentation avec changement de laspect visuel des

liens

11.5. Recherche et tri au sein dune base


La fonction de recherche et de tri dlments de la base est souvent utile au sein dun back-office. Vous allez donc modier la page daccueil en lui ajoutant, tout dabord, un petit formulaire permettant de taper le nom ou le prnom dun lve, puis un menu qui offrira la possibilit de lister les lves suivant un critre donn.

Dnir la fonction de recherche


La premire ide qui peut venir lesprit est de crer un nouveau script nomm par exemple eleve_recherche.php, qui listerait les lves correspondant un mot-cl. Cependant, en y regardant de plus prs, vous pouvez vous apercevoir quil sagit en fait du chier admin.php, auquel il suffit dajouter une clause la n de la requte SELECT. Lide est donc de gnrer une clause ds quun mot-cl est pass en paramtre. Rien de bien sorcier en perspective ! Le moteur de recherche doit par contre tre suffisamment permissif et vous renvoyer Paul Dupont mme si vous ne tapez que Dup. Lutilisation de loprateur dgalit (=) dans la clause nest donc pas valide. Ce quil faut employer, dans ce cas, cest la fonction MySQL INSTR(). Cette
LE GUIDE COMPLET 331

Chapitre 11

La gestion dune base de donnes

fonction prend deux arguments : la donne dans laquelle on cherche un motif et le motif en question. Le premier argument est gnralement le nom dune colonne. La requte est donc construite ainsi :
SELECT * FROM $table_eleve WHERE INSTR(nom,$motclef) OR INSTR(prenom,$motclef)

Fonction MySQL

Il existe une multitude de fonctions qui peuvent tre incluses directement dans des requtes SQL. Vous en trouverez un certain nombre dans les annexes.

Listing 11-10 : Moteur de recherche intgr <?php include("variables.inc.php"); include("identification.inc.php"); include("haut.inc.php"); $liendb = mysql_connect ($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); ?> <p align=left>:: accueil</p> <form action="admin.php" method="post"> <input type="text" name="motclef" value="<?php echo $_REQUEST[motclef];?>" /> <input type="submit" value="rechercher" /> </form> <table width=90% border=1> <tr> <td class=intitule>id</td> <td class=intitule>nom</td> <td class=intitule>prenom</td> <td class=intitule>naissance</td> <td class=intitule> </td> </tr> <?php

332 LE GUIDE COMPLET

Recherche et tri au sein dune base


$clause = ; if (isset($_REQUEST[motclef])) { $clause .= " WHERE INSTR(nom,".$_REQUEST[motclef].")"; $clause .= " OR INSTR(prenom,".$_REQUEST[motclef].")"; } $sql = "SELECT * FROM eleve ".$clause; $resultat = mysql_query ($sql);

Chapitre 11

while ($eleve = mysql_fetch_array ($resultat)) { $id = $eleve[ideleve]; $nom = $eleve[nom]; $prenom = $eleve[prenom]; $date = $eleve[naissance]; echo "<tr>"; echo "<td>$id</td>"; echo "<td>$nom</td>"; echo "<td>$prenom</td>"; echo "<td>$date</td>"; echo "<td>"; echo "<a href=eleve_edite.php?id=$id>voir</a>"; echo "</td>"; echo "</tr>"; } echo "</table>"; mysql_close($liendb); include("bas.inc.php"); ?>

Figure 11.10 : Rsultat de la recherche sur le mot au

LE GUIDE COMPLET 333

Chapitre 11

La gestion dune base de donnes

Dans le cas o un mot-cl a t tap, vous entrez dans la condition if, et la variable $clause est initialise, par exemple :
" WHERE INSTR(nom,au) OR INSTR(prenom,au)")

La variable $sql est ensuite initialise. Si la variable $clause na pas t cre, la requte reste "SELECT * FROM $table_eleve", sinon la clause est ajoute :
"SELECT * FROM $table_eleve WHERE INSTR(nom,au) OR INSTR(prenom,au)"

Si vous tapez prsent le mot-cl dup, vous nobtenez aucun rsultat car INSTR est sensible la casse. Pour lister tous les lves, sans vous proccuper de la diffrence minuscules/majuscules, prfrez loprateur de comparaison LIKE :
Listing 11-11 : Test non sensible la casse if (isset($motclef)) { $clause = "WHERE nom LIKE ".$_REQUEST[motclef]." OR prenom LIKE ".$_REQUEST[motclef].""; }

Il est important de ne jamais hsiter composer vos requtes partir dlments disparates. Cela permet daboutir des fonctionnalits trs intressantes sans trop defforts.

Dnir la fonction de tri


Lautre fonctionnalit trs utile en SGBD est la possibilit dobtenir les donnes tries. Pour illustrer cette fonctionnalit, vous allez ajouter au script admin.php la possibilit de trier les lves par noms, prnoms ou dates de naissance. Pour prciser un ordre, il suffit dajouter la commande ORDER BY la n de la requte. Ainsi, si vous souhaitez classer les lves par noms, crivez :
SELECT * FROM eleve ORDER BY nom

Il est possible de raliser un classement multiple en dnissant un ORDER BY sur plusieurs colonnes. Si vous souhaitez classer les lves par noms et, pour un mme nom, par dates de naissance, crivez :
ORDER BY nom, naissance

334 LE GUIDE COMPLET

Recherche et tri au sein dune base

Chapitre 11

ORDER BY et WHERE

Les commandes ORDER BY et WHERE ne sont pas exclusives. Les deux peuvent cohabiter. Il est cependant ncessaire de mettre le WHERE avant lORDER BY.

Tout comme pour la recherche, vous voyez quil suffit denrichir la requte si une variable $ordre est transmise :
<?php include("variables.inc.php"); include("identification.inc.php"); include("haut.inc.php"); $liendb = mysql_connect($bddserver, $bddpassword); mysql_select_db ($bdd); ?> <p align="left"> :: accueil</p> echo $bddlogin,

<form action="admin.php" method="post"> <input type="text" name="motclef" value="<?php $motclef; ?>"> <input type="submit" value="rechercher"> </form> <table width="90%" align="center" border="1"> <tr> <td class="intitule">id</td> <td class="intitule">nom</td> <td class="intitule">prenom</td> <td class="intitule">naissance</td> <td class="intitule"> </td> </tr> <?php if { (isset($motclef)) $clause = " WHERE nom LIKE prenom LIKE %$motclef%"; } if { } (isset($ordre)) $orderby = " ORDER BY $ordre"; %$motclef%

OR

LE GUIDE COMPLET 335

Chapitre 11

La gestion dune base de donnes


$table_eleve" ($sql); . $clause .

$sql = "SELECT * FROM $orderby; $resultat = mysql_query

while ($eleve = mysql_fetch_array ($resultat)) { $id = $eleve[ideleve]; $nom = $eleve[nom]; $prenom = $eleve[prenom]; $date = $eleve[naissance]; echo "<tr>"; echo "<td>$id</td>"; echo "<td>$nom</td>"; echo "<td>$prenom</td>"; echo "<td>$date</td>"; echo "<td>"; echo "<a href=eleve_edite.php?id=$id>voir</a>"; echo "</td>"; echo "</tr>"; } echo ?> <form action="admin.php" method="post"> <select name="ordre"> <option value="nom">classement par nom</option> <option value="prenom">classement par prnom</option> <option value="naissance">classement par date</option> </select> <input type="submit" value="trier"> </form> <?php mysql_close($liendb); include("bas.inc.php"); ?> "</table>";

LIMIT

Il est possible de limiter le nombre de rsultats retourns par un SELECT avec LIMIT. Ainsi, SELECT * FROM eleve LIMIT 10 retourne 10 lves. La commande LIMIT peut tre complte par un WHERE et un ORDER BY, mais doit cependant tre place la n de la requte.

336 LE GUIDE COMPLET

Check-list

Chapitre 11

Figure 11.11 : Classement par prnoms

11.6. Check-list
j j j j j

Une authentication HTML ncessite de travailler au niveau de len-tte HTTP et dutiliser de la fonction header(). Les requtes de type UPDATE permettent de mettre jour des informations de la base. Les requtes de type DELETE permettent de supprimer un enregistrement de la base. Il est toujours possible de limiter la porte dune requte SQL en lenrichissant dune clause WHERE. La factorisation est une notion essentielle en informatique. Il est ainsi possible, pour un code PHP utilis en diffrents endroits, de le placer dans un chier extrieur et de linclure via la fonction include(). Au niveau de la prsentation de la page, il est prfrable de passer par un chier CSS plutt que placer des consignes visuelles au sein mme des lments qui la composent. Lvolution sera en effet largement facilite.

LE GUIDE COMPLET 337

La gestion des chiers


Manipuler des fichiers ....................................................................................................... 340 Crer des fichiers spciaux ............................................................................................. 351 Check-list ............................................................................................................................. 382

Chapitre 12

La gestion des fichiers

Dans le cadre de ce chapitre, nous nous intresserons principalement la manipulation des chiers en PHP. Vous tudierez dans un premier temps les diffrentes actions qui peuvent tre ralises sur un chier, puis la prsentation de diffrents formats de chiers qui peuvent tre gnrs avec PHP : GZIP (archives), CSV (Excel), PNG (image), PDF, SWF (Flash).

12.1. Manipuler des chiers


Comme beaucoup de langages de programmation, PHP permet de manipuler les chiers. Toutes les oprations habituelles sont disponibles :
j j j j j j

lire crire renommer dplacer copier supprimer

Prenez un premier exemple : quand vous envoyez un chier hello.html sur votre serveur dhbergement (par FTP ou via le navigateur), une commande PHP vous permet en une ligne de le renommer :
Listing 12-1 : Renomme le fichier hello.html en hello.htm rename("hello.html","hello.htm");

Ces fonctions permettent donc de manipuler les chiers distants (prsents sur le serveur dhbergement).

Les chiers de cache


Ces fonctions rendent possible le stockage de donnes dans des chiers. Cela va a priori lencontre de ce qui a t dit prcdemment au sujet des bases de donnes, savoir quil est souvent prfrable dutiliser une base de donnes pour stocker des informations. Il faut cependant garder lesprit que les requtes SQL utilisent beaucoup de ressources et quil est judicieux, pour accrotre les performances dun script, de les rduire le plus possible.
340 LE GUIDE COMPLET

Manipuler des fichiers

Chapitre 12

La mise en uvre dune base de donnes est en effet trs lourde grer pour le systme : la couche rseau, le systme de chiers, ainsi que le SGBD sont mis contribution.
Impact des requtes SQL

Pour ceux qui souhaitent optimiser leur code, sachez que la diminution du nombre de requtes SQL est de loin ce qui peut amliorer le plus les performances de vos scripts. Les optimisations sur les boucles et les diverses nesses du langage sont, en comparaison, ngligeables.

Pour allger les ressources du serveur et acclrer vos scripts, il peut donc tre intressant de mettre en place un systme de cache. Le principe dun chier de cache consiste contenir de manire statique et pendant une dure dtermine des informations qui ne sont pas susceptibles dtre modies rgulirement, mais qui ont de fortes chances dtre rclames frquemment. Pour crer ce chier, il suffit dextraire les informations de la base de donnes et de les crire dans un chier selon une certaine norme. Lavantage rside dans le fait que ce chier devient aussi facile traiter pour le serveur quun simple chier .html. Ds lors, vous navez pas craindre que lafflux soudain dun grand nombre dinternautes freine lensemble du site. Imaginez quun site web partenaire ait besoin daccder aux noms et aux prnoms des lves de lcole. Ce site na pas accs la base de donnes et ne peut donc pas extraire directement les informations dont il a besoin. Vous allez par consquent mettre sa disposition un chier de cache contenant la liste des noms et des prnoms. Ce chier sera disponible ladresse http://localhost/eleves.cache. Votre politique de cache sera alors de mettre en uvre deux scripts :
j j

Le script ecrit-cache.php va permettre dcrire les informations dans le chier. Le script lit-cache.php, sera utilis par le site partenaire pour accder votre chier via le Web (en sachant videmment que votre partenaire dispose du PHP).

LE GUIDE COMPLET 341

Chapitre 12

La gestion des fichiers

Lcriture
Commencez par le stockage de vos donnes dans le chier eleves.cache :
Listing 12-2 : Le script ecrit-cache.php <?php $fichier = fopen ("eleves.cache", "w+"); $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve"; $resultat = mysql_query ($sql); while ($eleve = mysql_fetch_array ($resultat)) { $nom = $eleve[nom]; $prenom = $eleve[prenom]; fwrite($fichier, "$nom,$prenom\n"); } mysql_close($liendb); fclose($fichier); echo "fichier enregistr"; ?>

Comme vous pouvez vous en rendre compte, le principe de fonctionnement est assez similaire celui des bases de donnes. Il convient, dans un premier temps, de crer un descripteur de chier avec fopen() : $fichier. Le premier argument de fopen() correspond au nom du chier avec lequel vous allez travailler. Dans cet exemple, le nom est simple : eleves.cache. Celui-ci peut cependant tre moins vident. Il peut ainsi tre prcd dun chemin (path). Si vous crivez ../eleves.cache, cela signie que vous ouvrez le chier eleves.cache dans le rpertoire au-dessus du rpertoire courant.
Rpertoire courant

Le rpertoire courant est le rpertoire o se trouve le script PHP qui a t appel. En crivant eleves.cache, vous ouvrez donc un chier qui sera situ dans le mme rpertoire que le script dappel.

342 LE GUIDE COMPLET

Manipuler des fichiers

Chapitre 12

Le nom du chier peut aussi tre une URL : il est ainsi possible douvrir un chier prsent sur le Web (http://localhost/eleves.cache) ou sur un serveur FTP (ftp://ftp.kernix/eleves.cache). Le deuxime argument transmis fopen() correspond au mode douverture du chier. Plusieurs modes existent :
Tableau 12.1 : Les modes douverture dun chier avec fopen()

Mode douverture

Signication Ouverture en lecture seule (read) Ouverture en criture seule (write) ; le chier est cr sil nexiste pas Ouverture en lecture/criture Ouverture en lecture/criture ; le chier est cr sil nexiste pas et, sil existe, il est pralablement mis zro Ouverture en criture (append) ; le chier est cr sil nexiste pas et, sil existe, le pointeur est plac la n du chier Ouverture en lecture/criture ; le chier est cr sil nexiste pas et, sil existe, le pointeur est plac la n du chier

r w r+ w+

a+

Dans ce cas, choisissez le mode "w+" car vous devez crire dans le chier eleves.cache. Lors du premier appel au script ecrit-cache.php, le chier est cr ; lors des appels suivants, vous najouterez pas de donnes aux chiers ("a+"), mais remplacerez le contenu par de nouvelles donnes. Une fois le chier ouvert, il est possible dy crire avec la fonction
fwrite(). Cette fonction prend, elle aussi, deux arguments : le premier

argument est le descripteur de chier et le second correspond la chane de caractres que vous souhaitez stocker dans le chier. Il est important de placer un retour chariot (\n) la n de la chane si lon ne veut pas avoir toutes ces donnes sur la mme ligne. Il convient de noter quune manipulation de chier se conclut toujours par la fermeture du chier avec fclose().

LE GUIDE COMPLET 343

Chapitre 12

La gestion des fichiers

La lecture
Passons maintenant la lecture du chier . Nous supposons dans un premier temps que le script lit-cache.php est sur le mme compte que le script ecrit-cache.php.

La lecture locale
Vous pouvez ouvrir le chier en lecture ("r") en lappelant directement par son nom :
Listing 12-3 : Le script lit-cache.php $fichier = fopen ("eleves.cache", "r"); $eleves = fread ($fichier, filesize("eleves.cache")); fclose ($fichier); echo $eleves;

Vous faites dans ce cas appel la fonction fread(). Cette fonction prend deux arguments : le premier est le descripteur de chier et le second correspond la quantit de donnes (en octets) que vous souhaitez lire dans le chier. Faites appel la fonction filesize() pour trouver cette valeur. Cette fonction retourne la taille du chier, dont le nom lui est pass en paramtre. Grce cette fonction, vous lisez lintgralit du chier avec un seul appel fread().

La lecture distante
Supposons maintenant que ce script soit hberg sur un autre serveur. Le chier doit cette fois tre ouvert via le Web. Passez fread() le nom "http://localhost/eleves.cache".
Ouverture de chier web

Il est impossible douvrir des chiers web en criture car cela reviendrait permettre nimporte qui de modier le contenu de vos pages !

la diffrence de la version locale, vous ne pouvez pas utiliser la fonction filesize() avec un chier distant. Vous tes donc oblig de lire le chier morceau par morceau avec une boucle while :

344 LE GUIDE COMPLET

Manipuler des fichiers


$eleves = ""; while ($str = fread($fichier,16)) { $eleves .= $str; }

Chapitre 12

chaque itration de la boucle while, vous compltez la variable $eleves avec 16 octets du chier eleves.cache. Cest le descripteur de chier qui garde en mmoire lendroit o vous vous trouvez dans le chier. La boucle sarrte naturellement ds quil ny a plus rien lire dans le chier. Si vous souhaitez revenir au dbut dun chier, vous avez (au moins) deux possibilits : la premire, peu lgante, consiste fermer le chier et le rouvrir ; la seconde consiste utiliser la fonction rewind().
rewind() prend en paramtre un descripteur de chier. Cette deuxime

solution est beaucoup plus intressante car moins consommatrice en ressources. crivez maintenant le script lit-cache.php qui va lire le chier
eleves.cache via le Web :
Listing 12-4 : ouverture dun fichier web <?php $fichier = fopen ("http://localhost/eleves.cache", "r"); $eleves = ""; while ($str = fread($fichier,16)) { $eleves .= $str; } fclose($fichier); echo $eleves; ?>

Vous prenez conscience, avec cet exemple, de lextrme simplicit du langage PHP, mme pour raliser des tches a priori complexes sur les chiers. Voyez la fonction fread() avec un autre exemple :
<?php $url = "http://www.google.com";

$fichier = fopen ($url, "r"); while ($str = fread ($fichier, 16)) {

LE GUIDE COMPLET 345

Chapitre 12

La gestion des fichiers

$src .= $str; } fclose($fichier); echo "<textarea rows=10 cols=80>$src</textarea>"; ?>

Ce script rcupre les sources de la page http://www.google.com et les affiche dans une zone de texte.

Figure 12.1 : Affichage des sources de www.google.com

Il est bien videmment possible douvrir plusieurs chiers au mme moment. Il suffit pour cela dutiliser des noms de descripteurs diffrents. crivez un petit script qui lit le chier eleves.cache (via le Web) et qui gnre un chier eleves2.cache, o, cette fois, le nom apparat aprs le prnom, avec un deux-points comme caractre de sparation. Utilisez les fonctions file_get_contents() (qui retourne le contenu dun chier) et strlen() pour trouver la taille du chier distant.
Listing 12-5 : Le script lit-cache.php <?php $fichier1 = fopen ("http://localhost/eleves.cache", "r"); $fichier2 = fopen ("eleves2.cache", "w+"); $taille = strlen (file_get_contents("http://localhost /eleves.cache")); $eleves = fread ($fichier1,$taille); $tab_eleves = split ("\n",$eleves);

346 LE GUIDE COMPLET

Manipuler des fichiers


foreach ($tab_eleves as $ligne) { list ($nom,$prenom) = split(",",$ligne); fwrite($fichier2,"$prenom:$nom"); } fclose ($fichier2); fclose ($fichier1); ?>

Chapitre 12

Ne laissez pas traner ce chier eleves2.cache. La fonction unlink() permet de leffacer :


unlink("eleves2.cache");

Vous vous apercevez, avec cette dernire fonction (ainsi quavec la fonction rename() vue plus haut), quil est inutile dutiliser fopen() quand vous ne cherchez pas travailler sur le contenu du chier.

Les chiers modles : templates


tudions enn un dernier exemple qui illustre la lecture de chier avec PHP. Vous avez vu dans les chapitres prcdents limportance, en programmation web, de la sparation entre le contenu et le visuel. Lutilisation de chiers templates (modles) est une bonne faon dy parvenir. Le principe est trs simple : plutt que de mettre dans le mme chier le code PHP et la page HTML, stockez sparment ces deux parties. Le chier .html comporte des balises indiquant ainsi o les informations issues de la base doivent tre places. Le script PHP se charge quant lui de lire le chier et de complter les manques avec les donnes quil est all rcuprer dans la base (ou nimporte o ailleurs). Dans cet exemple, le chier modele1.html comporte deux balises qui seront remplaces :
j j

%%NBELEVES%% correspond au nombre dlves. %%TABELEVES%% sera remplac par la liste des lves.
Listing 12-6 : Le contenu du fichier modle modele1.html
<html> <body bgcolor="white"> <p>%%NBELEVES%% lves</p> <hr/>

LE GUIDE COMPLET 347

Chapitre 12

La gestion des fichiers

<table align="center" border="1"> <tr> <td> <font size="small">%%LISTELEVES%%</font> </td> </tr> </table> <hr/> </body> </html>

Figure 12.2 : Le premier modle

crivez maintenant ce que lon qualie gnralement de wrapper, cest--dire le script qui va construire la page nale partir du modle :
<?php $fichier = fopen ("modele1.html", "r"); $html = fread ($fichier, filesize("modele1.html")); fclose ($fichier); $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve"; $resultat = mysql_query ($sql); $nb = mysql_num_rows($resultat); $eleves = ""; while ($eleve = mysql_fetch_array ($resultat)) { $nom = $eleve[nom]; $prenom = $eleve[prenom]; $eleves .= "$nom,$prenom<br>"; }

348 LE GUIDE COMPLET

Manipuler des fichiers


mysql_close ($liendb);

Chapitre 12

$html = str_replace ("%%NBELEVES%%","$nb",$html); $html = str_replace ("%%LISTELEVES%%",$eleves,$html); echo $html; ?>

Figure 12.3 : Les balises ont t remplaces

Le grand avantage de ce mode de fonctionnement est de permettre de changer laspect visuel sans modier le code. Cela rend la mise jour de la page extrmement aise. Si vous travaillez avec un client, celui-ci peut raliser un nouveau design trs simplement sous Dreamweaver et vous transmettre le chier en tant que modle. Imaginez maintenant que plusieurs partenaires veuillent pointer sur cette page, mais que chacun dsire que la page soit habille sa faon. Rien de plus simple : vous prvoyez dans le script que le partenaire transmet en paramtre ladresse du template, puis le script ouvre ce template via le Web pour gnrer la page. crivez un deuxime template :
Listing 12-7 : autre modle <html> <body bgcolor="#C7D0D9"> <table align="center" width="100%"> <tr><td bgcolor="white">%%NBELEVES%%</td></tr>
LE GUIDE COMPLET 349

Chapitre 12

La gestion des fichiers

<tr><td bgcolor="#CCCCCC">%%LISTELEVES%%</td></tr> </table> </body> </html>

Figure 12.4 : Le deuxime modle

Modiez maintenant le script pour quil accepte en paramtre ladresse du chier modle :
Listing 12-8 : le nom du modle est transmis en paramtre <?php $fichier = fopen ($_REQUEST[modele], "r"); while ($str = fread ($fichier, 16)) { $html .= $str; } fclose ($fichier); $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve"; $resultat = mysql_query ($sql); $nb = mysql_num_rows($resultat); $eleves = ""; while ($eleve = mysql_fetch_array ($resultat)) { $nom = $eleve[nom]; $prenom = $eleve[prenom]; $eleves .= "$nom,$prenom<br>"; } mysql_close ($liendb); $html = str_replace ("%%NBELEVES%%","$nb",$html); $html = str_replace ("%%LISTELEVES%%",$eleves,$html); echo $html;

350 LE GUIDE COMPLET

Crer des fichiers spciaux


?>

Chapitre 12

Il devient alors possible de spcier et dhberger son propre modle.

Figure 12.5 : Page obtenue en tapant lURL http://localhost/test.php?modele=http://localhost/modele2.html

Cette solution sera de plus en plus courante car les applicatifs en ligne vont devenir peu peu des services et il sera important que les clients de ces services puissent les adapter.

12.2. Crer des chiers spciaux


Vous avez vu quil tait trs simple, en PHP, de manipuler des chiers. Vous allez voir, dans cette partie, quil est possible, aussi simplement, de gnrer des chiers spciaux : chiers compresss, chiers exploitables sous Excel, chiers image.

Les chiers compresss


Le PHP dispose de fonctions permettant de compresser des donnes. En les compressant, ces donnes prennent moins de place et sont donc beaucoup plus rapides transfrer. Le format de compression par dfaut en PHP est GZIP. Ce format est peu connu en dehors du monde Unix, mais il dispose de nombreux avantages :
LE GUIDE COMPLET 351

Chapitre 12
j j

La gestion des fichiers

Lalgorithme de compression est excellent. Des outils de dcompression existent sur tous les systmes dexploitation (Stuffit Expander sous Mac, WinZip sous Windows).

Ce premier exemple aura pour objet de rcuprer les noms et les prnoms des lves, den faire une liste et de retourner la liste compresse an de la stocker sur votre disque :
<?php $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve"; $resultat = mysql_query ($sql); $liste = ""; while ($eleve = mysql_fetch_array ($resultat)) { $nom = $eleve[nom]; $prenom = $eleve[prenom]; $liste .= "$nom,$prenom\n"; } mysql_close($liendb); echo gzencode($liste); ?>

En appelant le chier directement, vous obtenez un contenu illisible.

Figure 12.6 : Contenu compress illisible

Le problme vient du fait que le chier que vous appelez est considr par le navigateur comme un simple chier .html. Son contenu brut est
352 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

donc affich. Il est cependant possible de donner des directives au navigateur pour lui indiquer que le contenu quil reoit est compress et quil doit par consquent le sauvegarder plutt que lafficher. La commande utilise pour y parvenir est header(). Cette fonction permet de modier len-tte dun chier transmis un navigateur. Avec cette fonction, il est possible dintervenir sur :
j j j

les directives de cache (dure de conservation dun chier sur le disque) ; les dates de cration ; le type de contenu du chier.

Le rle de la fonction header() se limite en fait passer des commandes HTTP. La commande permettant de prciser le contenu du chier envoy est Contenttype. Par dfaut, le contenu est de type text/html. Si vous souhaitez indiquer que le chier est compress au format GZIP, il suffit dcrire :
header("Content-type: application/x-gzip");

Il faut aussi ajouter une autre directive an dindiquer quel nom devra prendre le chier sauvegarder :
header(Content-Disposition: attachement; filename="eleves.txt.gz");

En-tte HTTP et courriel

La modication de len-tte HTTP dun chier est rapprocher des ajouts que vous aviez faits dans len-tte dun courriel pour prciser quil tait en HTML. Lavantage de PHP est de permettre daccder ces zones caches et ainsi daller plus loin dans le code et les fonctionnalits. Il est par contre ncessaire de connatre les diffrents protocoles (HTTP, SMTP) pour pouvoir en tirer vritablement parti.

Compltez votre script avec ces deux nouvelles lignes :


<?php header("Content-type: application/x-gzip"); header(Content-Disposition: attachement; filename="eleves.txt.gz"); $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve"; $resultat = mysql_query ($sql);

LE GUIDE COMPLET 353

Chapitre 12

La gestion des fichiers

$liste = ""; while ($eleve = mysql_fetch_array ($resultat)) { $nom = $eleve[nom]; $prenom = $eleve[prenom]; $liste .= "$nom,$prenom\r\n"; } mysql_close($liendb); echo gzencode($liste); ?>

Dsormais, vous obtenez bien le comportement dsir. Le navigateur vous propose de sauvegarder le chier sur le disque.

Figure 12.7 : Le chier compress peut tre sauv sur le disque

Une fois que le chier se trouve sur le disque, il est possible de le dcompresser :

Figure 12.8 : Ouverture du chier compress avec WinRAR

354 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

Le format BZIP2

Un autre format de compression est disponible : BZIP2. Lavantage de ce format est doffrir un meilleur taux de compression que le GZIP. Du fait de la jeunesse de ce format, les dcompresseurs de chiers GZIP ne sont pas trs rpandus. Cela interdit donc son usage si lon souhaite conserver une certaine forme de compatibilit avec le plus grand nombre dinternautes.

Grce la commande header(), vous avez pu forcer le navigateur sauver les donnes qui lui ont t transmises. Cette technique peut se rvler trs intressante si vous souhaitez associer un vnement au tlchargement dun chier. Plutt que donner un lien xe sur le chier (tel
http://localhost/fichier.exe), vous avez la possibilit de

passer par un script qui pourra par exemple, dans un premier temps, vrier un mot de passe, puis logger le tlchargement dans une base avant de transmettre les donnes au navigateur.
La fonction header()

La commande header() doit tre utilise avant que toute donne soit affiche. Si vous laissez une simple ligne vide avant louverture <?php, vous obtiendrez une erreur. En effet, le caractre de saut de ligne aura t affich avant la commande header().

Lexemple suivant retourne le chier prog.exe prsent sur le serveur si linternaute sest identi avec le login "test" :
<?php if ($login == "test") { header("Content-type: application/octetstream"); header(Content-Disposition: attachement; filename="prog.exe"); // possibilit ici denregistrer lvnement dans une base de donnes $fichier = fopen ("prog.exe", "r"); while ($str = fread ($fichier, 1024)) { echo $str; } fclose($fichier);

LE GUIDE COMPLET 355

Chapitre 12
return(1); } ?>

La gestion des fichiers

<form> <input name=login /><input type=submit value=telecharger /> </form>

Les chiers Excel


Il est trs courant, lorsque vous dveloppez un applicatif en ligne, davoir besoin de gnrer un chier dexport des donnes stockes dans votre base. Un tel chier peut tre utilis par un logiciel tiers pour raliser certaines oprations spciques. Vous pourriez ainsi imaginer dexporter les courriels de tous les lves et utiliser ce chier avec un logiciel de publipostage an denvoyer un bulletin dinformation lensemble de la classe. Il savre que la quasi-totalit du march de linformatique grand public est occupe par Windows et quExcel est loutil le plus utilis pour traiter des listings de donnes. Vous allez donc prsenter, dans cette partie, une manire de gnrer des chiers compatibles avec Excel. La mthode se rvle relativement simple : il suffit de gnrer un chier CSV (Comma Separated Value), cest--dire un chier o les enregistrements sont organiss ligne par ligne et o les donnes sont spares par des virgules :
j j j j

"Dupont","Paul" "Pitel","Guillaume" "Metayer","Fabrice" "Marillier","Olivia"

Grce la fonction header() et la directive Contenttype, vous tes en mesure douvrir vos donnes directement sous Excel sans avoir besoin de passer par un chier temporaire :
<?php header("Content-type: text/x-csv"); header(Content-Disposition: attachement; filename="list.csv"); $liendb = mysql_connect("localhost", "root", "");

356 LE GUIDE COMPLET

Crer des fichiers spciaux


mysql_select_db ("test"); $sql = "SELECT * FROM eleve"; $resultat = mysql_query ($sql); $liste = ""; while ($eleve = mysql_fetch_array ($resultat)) { $nom = $eleve[nom]; $prenom = $eleve[prenom]; $liste .= "\"$nom\",\"$prenom\"\r\n"; } mysql_close($liendb); echo $liste; ?>

Chapitre 12

Figure 12.9 : Le navigateur vous propose bien douvrir le chier avec Excel

Figure 12.10 : Les donnes sont directement lisibles dans Excel

LE GUIDE COMPLET 357

Chapitre 12

La gestion des fichiers

Dans Excel, il est possible de traiter vos donnes de manire trs prcise, dutiliser des ltres, dexcuter des oprations complexes. Il est souvent prfrable de fonctionner avec une exportation de chier vers un logiciel volu plutt que de recoder laborieusement une multitude de fonctionnalits qui ne serviront peut-tre jamais. Il vaut mieux limiter lapplicatif en ligne sa fonction premire. Lorsque vous dveloppez une boutique en ligne, il est sans doute prfrable dexporter les commandes vers un logiciel de comptabilit plutt que de crer un module comptable.

Les chiers Flash


PHP est un logiciel dvelopp par des dveloppeurs et pour des dveloppeurs. Dans cette communaut, la notion de d technique et de jeu prend souvent le pas sur les considrations purement conomiques. Trs rapidement, des modules plus ou moins farfelus sont ainsi venus enrichir la librairie dextensions du PHP. Parmi ceux-ci, on peut trouver un module permettant de gnrer des chiers SWF. Un chier SWF est normalement gnr avec le logiciel de Macromedia Flash. Avec PHP, il est cependant possible de crer dynamiquement des animations Flash. Parmi tous les projets consacrs ce sujet sur Internet, le projet Ming semble tre le plus actif et le plus abouti. Grce cette extension, vous tes en mesure, en quelques lignes de PHP, de raliser de vritables animations qui peuvent interagir avec la souris, le clavier, tre accompagnes de musique, etc. Bien que Wamp Server soit livr par dfaut avec lextension permettant de gnrer des SWF, il ne lautorise pas par dfaut. Ltape pralable la manipulation des SWF consiste donc faire en sorte que PHP charge cette extension au dmarrage. La premire solution consiste modier le chier php.ini en supprimant le point-virgule devant linstruction suivante :
extension=php_ming.dll;

Le serveur Apache doit ensuite tre redmarr pour prendre en compte cette modication. La seconde solution consiste passer par licne de Wamp Server et le menu PHP extensions pour slectionner php_ming.

358 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

Extensions sous Linux

Lajout dextensions sous Linux se rvle beaucoup plus complexe. Vous tes en effet oblig de rcuprer les sources de lextension ainsi que celles de PHP. Les deux devront tre recompiles pour pouvoir disposer de cette nouvelle extension. Cette situation est essentiellement due au fait quil existe une multitude de distributions Linux et que ces dernires fonctionnent le plus souvent sur une grande varit de plateformes (PC, Mac, etc.). Cette diversit rend ainsi la distribution en mode binaire extrmement fastidieuse pour les dveloppeurs.

Le code suivant permet ainsi de jouer le chier test.mp3 (plac dans le mme rpertoire que le script) :
<?php $m = new SWFMovie(); $m->setRate(12.0); $m->streamMp3(fopen("test.mp3", "r")); $m->setFrames(141); header(Content-type: application/x-shockwave-flash); $m->output(); ?>

Notez le Contenttype : application/xshockwaveflash. En six lignes, vous tes en mesure dajouter une dimension musicale votre site. De plus, il est avantageux dutiliser Flash dans ce cas car il sagit de la technologie la plus portable : Flash existe en effet pour tous les navigateurs et les systmes dexploitation. Le code suivant permet, quant lui, de faire tourner sur lui-mme un carr rouge :
<?php $s = new SWFShape(); $s->setRightFill($s->addFill(0xff, 0, 0)); $s->movePenTo(-50,-50); $s->drawLineTo(50,-50); $s->drawLineTo(50,50); $s->drawLineTo(-50,50); $s->drawLineTo(-50,-50); $p = new SWFSprite(); $i = $p->add($s); for($j=0; $j<17; ++$j) { $p->nextFrame(); $i->rotate(5); } $p->nextFrame(); $m = new SWFMovie();

LE GUIDE COMPLET 359

Chapitre 12

La gestion des fichiers

$i = $m->add($p); $i->moveTo(160,120); $i->setName("blah"); $m->setBackground(0xff, 0xff, 0xff); $m->setDimension(320,240); header(Content-type: application/x-shockwave-flash); $m->output(); ?>

Figure 12.11 : Flash gnr par du code PHP

Un des grands avantages de Flash est quil permet dobtenir une interactivit en temps rel avec linternaute. Lexemple suivant permet de dplacer un cercle vert sur un carr rouge et dappeler la fonction Javascript extrieure externAction() lorsque le cercle est plac sur le carr :
Listing 12-9 : Script qui gnre le FLASH <? ming_useswfversion(6); $movie = new SWFMovie(); $movie->setRate(30.000000); $movie->setDimension(500, 500); $movie->setBackground(0xcc,0xcc,0xcc); $square = new SWFShape(); $square->setLine(5,0,0,0); $square->setRightFill(255,0,0); $square->movePenTo(-75,-75); $square->drawLine(150,0);
360 LE GUIDE COMPLET

Crer des fichiers spciaux


$square->drawLine(0,150); $square->drawLine(-150,0); $square->drawLine(0,-150); $sprite = new SWFSprite(); $sprite ->add($square); $sprite ->nextFrame(); $f = $movie->add($sprite); $f->setName("square"); $f->moveTo(250,350); $circle = new SWFShape(); $circle->setLine(5,0,0,0); $circle->setRightFill(0,255,0); $circle->drawCircle(50); $sprite = new SWFSprite(); $sprite ->add($circle); $sprite ->nextFrame(); $f = $movie->add($sprite); $f->setName("circle"); $f->moveTo(250,100);

Chapitre 12

$movie->add(new SWFAction(" circle.onPress = function () { this.startDrag(1); }; circle.onRelease = function () { stopDrag(); if ((circle._x > (square._x - square._width/2)) && (circle._x < (square._x + square._width/2)) && (circle._y > (square._y - square._height/2)) && (circle._y < (square._y + square._height/2))) { circle._x = square._x; circle._y = square._y; _root.getUrl(javascript:externAction()); } }; ")); $movie->output(); ?> Listing 12-10 : page contenant la function javascript appele et lappel au FLASH <html> <head> <title>Exemple Ming</title> </head>

LE GUIDE COMPLET 361

Chapitre 12

La gestion des fichiers

<script> function externAction () { alert("Bravo !"); } </script> <body> <p>Faire un drag&drop du cercle vert dans la carr rouge</p> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/ flash/swflash.cab#version=6,0,29,0" width="300" height="300"> <param name="movie" value="test.php"> <param name="quality" value="high"> <param name="wmode" value="transparent"> <embed src="test.php" width="300" height="300" wmode="transparent" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"></embed> </object> </body> </html>

Figure 12.12 : Dclenchement dune action lorsque le cercle est plac sur

le carr

Si cette extension nest pas prsente chez votre hbergeur, nhsitez pas lui en parler : il y a de fortes chances pour quil vous linstalle

362 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

rapidement. Le projet Ming est hberg ladresse http://ming.sourceforge .net/. Vous trouverez sur le site lextension tlcharger ainsi quune documentation complte.

Les chiers PDF


Le format de chiers PDF est devenu depuis quelques annes un standard pour les changes de documents sur Internet. Le logiciel Acrobat Reader, de la socit Adobe, est en effet prsent sur toutes les plateformes (Windows, Mac, Unix). PHP donne la possibilit de crer la vole des documents PDF. Cette technique peut tre intressante si vous souhaitez crer des documents tlchargeables partir de donnes prsentes dans votre base. Comme pour le Flash, lextension de gestion des PDF doit galement tre autorise dans le chier php.ini. La ligne dcommenter est cette fois : extension=php_pdf.dll. Lalternative consistant slectionner lextension php_pdf dans le menu dextensions de Wamp est galement possible. crivez maintenant un script qui va gnrer un document PDF proposant autant de pages que dlves, avec dans chaque page le nom et le prnom de llve :
Listing 12-11 : Script qui gnre un document PDF <?php $pdf = pdf_new(); if (!pdf_open_file($pdf, "")) { print("error"); exit(0); }; pdf_set_info($pdf, pdf_set_info($pdf, pdf_set_info($pdf, pdf_set_info($pdf, "Author", "fx bois"); "Title", "exemple"); "Creator", "fx bois"); "Subject", "exemple");

$liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve"; $resultat = mysql_query ($sql); $liste = ""; while ($eleve = mysql_fetch_array ($resultat))

LE GUIDE COMPLET 363

Chapitre 12
{

La gestion des fichiers

$nom = $eleve[nom]; $prenom = $eleve[prenom]; pdf_begin_page($pdf, 595, 842); pdf_add_bookmark($pdf, "fiche $nom",0,0); $font = pdf_findfont($pdf, "Helvetica", "host", 0); if ($font) pdf_setfont($pdf, $font, 12); pdf_set_value($pdf, "textrendering", 1); pdf_show_xy($pdf, "$nom $prenom", 50, 750); pdf_moveto($pdf, 50, 740); pdf_stroke($pdf); pdf_end_page($pdf); } mysql_close($liendb); pdf_close($pdf); $buf = pdf_get_buffer($pdf); $len = strlen($buf); header("Content-type: application/pdf"); header("Content-Length: $len"); header("Content-Disposition: inline; filename=fichier -eleve.pdf"); print($buf); pdf_delete($pdf); ?>

Figure 12.13 : Document PDF gnr par du PHP ouvert dans Internet

Explorer

364 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

Plutt que de lafficher directement, il est galement possible de sauver le chier PDF sur le disque en remplaant les lignes suivantes :
header("Content-type: application/pdf"); header("Content-Length: $len"); header("Content-Disposition: inline; filename=fichier -eleve.pdf"); print($buf);

par :
$fichier = fopen ("fiche-eleve.pdf", "w+"); fwrite($fichier, $buf); fclose($fichier);

Les chiers image


la diffrence des extensions vues prcdemment, le module de gnration dimages est un des modules les plus populaires de PHP, et il y a de trs fortes chances pour que vous puissiez en disposer chez votre hbergeur. La directive dcommenter dans php.ini est : extension=php
_gd2.dll.

Les fondamentaux
Ce module est bas sur la librairie GD qui contient tout le code permettant de raliser les nombreuses manipulations graphiques. De nombreux autres langages de programmation tels que Perl ou Python permettent de linterfacer. Dveloppe prioritairement pour les environnements Unix/Linux, cette librairie existe aussi sous Windows et peut donc permettre la gnration dimage sur ce systme. Comme pour PDF ou Flash, vous utilisez des fonctions du module pour gnrer le contenu de limage ainsi que la fonction header() pour faire comprendre au navigateur que le chier est de type image. Le module est en mesure de gnrer diffrents formats dimages, chacun disposant de ses points forts.
j

JPEG : trs bonne compression pour des images complexes (photos), trs rpandu.
LE GUIDE COMPLET 365

Chapitre 12
j j j

La gestion des fichiers

GIF : trs bonne compression pour des images simples, trs rpandu, gre la transparence. PNG : trs bonne compression gnrale, gestion avance de la transparence. WBMP : il sagit dun format utilis pour le WAP.

Aujourdhui, le format le plus complet est le PNG. Son seul inconvnient est sa jeunesse. De ce fait, certains navigateurs anciens ne sont pas en mesure de le lire.
Format GIF

Les versions les plus rcentes de la librairie GD autorisent de nouveau la cration dimages au format GIF. Lalgorithme de compression (LZW) est en effet tomb dans le domaine public il y a peu de temps.

Votre premier script va gnrer une image noire contenant un rectangle blanc :
Listing 12-12 : Premire cration dimage <?php header ("Content-type: image/png"); $image = @Imagecreate (150, 150); $noir = ImageColorAllocate ($image, 0, 0, 0); $blanc = ImageColorAllocate ($image, 255, 255, 255); ImageFilledRectangle ($image, 10, 10, 20, 20, $blanc); ImagePng ($image); ?>

Figure 12.14 : Gnration dune image noire contenant un rectangle blanc

366 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

La cration dimages est donc un processus trs simple qui peut tre divis en plusieurs tapes :

1 Prcisez que le chier est de type image avec la commande header(). Dans ce cas, vous gnrez une image PNG en utilisant la directive Contenttype: image/png. Si vous choisissez de gnrer une image JPEG, vous crirez Contenttype: image/jpeg, et Contenttype: image/gif dans le cas dune image GIF. 2 Crez limage avec la fonction Imagecreate(). Vous transmettez cette fonction la largeur et la hauteur et elle retourne un identiant dimage : $image. 3 Dnissez les couleurs utilises dans limage avec la fonction ImageColorAllocate(). Le premier argument est limage ellemme ($image), les trois derniers arguments sont les composantes RVB (rouge, vert, bleu) de la couleur. La couleur noire est reprsente par le triplet (0, 0, 0), la couleur blanche par (255, 255, 255) et la couleur rouge par (255, 0, 0). Cette manire de coder les couleurs est la mme quen HTML, la diffrence quici les valeurs sont dcimales alors quen HTML les couleurs sont hexadcimales : le rouge scrit par exemple #FF0000 en HTML. La manire la plus simple de trouver les codes des couleurs est dutiliser les palettes des outils de cration graphique comme Photoshop, Paint Shop Pro ou Gimp. Il faut savoir que la premire couleur dnie servira de couleur de fond pour limage. Dans le cas prsent, il sagit de la couleur noire ($noir).

Figure 12.15 : La palette de Photoshop donne le codage RVB (ou RGB : Red, Green, Blue)

LE GUIDE COMPLET 367

Chapitre 12

La gestion des fichiers

4 Composez limage avec tous ses lments : formes gomtriques, textes, morceaux dautres images. Dans ce script, choisissez simplement un carr blanc plac dans langle gauche de limage. Utilisez, pour cela, la fonction ImageFilledRectangle() qui prend six arguments : lidentiant de limage, les deux coordonnes de langle suprieur gauche, les deux coordonnes de langle infrieur droit et enn la couleur du rectangle.
Une liste complte des fonctions est fournie dans le chapitre consacr Les fonctions PHP .

5 La dernire tape consiste gnrer le contenu de limage avec la fonction ImagePng(). Les fonctions ImageGIF, ImageJPEG, ImageWBMP sont aussi disponibles pour les autres formats.
Dans lexemple prcdent, vous avez fait le choix dappeler le script directement. Le navigateur naffiche donc que limage. Si vous souhaitez inclure limage au sein dune page web, il suffit de faire appel au script depuis la balise <img>. crivez la page HTML suivante dans ce sens :
Listing 12-13 : Inclusion dimage cre dynamiquement au sein dune page HTML <html> <body> <hr/> <center> <img src="test.php" /> </center> <hr/> </body> </html>

Figure 12.16 : Image dans une page HTML

368 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

crivez maintenant un deuxime exemple, o vous allez exploiter dautres fonctionnalits de ce module (traage de ligne, criture) :
<?php header ("Content-type: image/png"); $image = @Imagecreate (250, 200); $couleur1 = ImageColorAllocate ($image, 212, 208, 200); $couleur2 = ImageColorAllocate ($image, 198, 193, 182); $couleur3 = ImageColorAllocate ($image, 79, 78, 74); for ($i = 0; $i <= 200; $i += 10) { ImageLine ($image, 0, $i, 250, $i, $couleur2); } ImageString ($image,5,10,20, "B o n j o u r",$couleur3); ImageStringUp ($image,4,150,60, "Monde",$couleur3); ImagePng ($image); ?>

Figure 12.17 : Autres fonctionnalits du module image

Vous retrouvez dans cet exemple les principes vus plus haut. La boucle for()permet de tracer des lignes tous les 10 pixels grce la fonction ImageLine(). Les arguments de cette fonction sont

LE GUIDE COMPLET 369

Chapitre 12

La gestion des fichiers

lidentiant de limage, les coordonnes du point de dpart, les coordonnes du point darrive et la couleur. Les textes sont, quant eux, tracs avec les fonctions ImageString() et ImageStringUp() dont les arguments sont lidentiant de limage, la taille de la fonte, les coordonnes du point de dpart, le texte et enn la couleur. Le suffixe Up dans ImageStringUp() signie que le texte est trac verticalement. Comme vous pouvez vous en apercevoir, la fonte est trs sommaire. Heureusement, dautres fonctions permettent de spcier la fonte du texte : ImageTTFText().
ImageTTFText sous Linux

Pour pouvoir utiliser cette fonction, PHP doit avoir t compil avec le support de la librairie Freetype. Il nest donc pas assur que vous puissiez lutiliser.

Cette fonction prend huit arguments : lidentiant de limage, la taille de la fonte, langle, les coordonnes de lorigine, la couleur, le nom de la fonte et le texte. Une fonte doit donc avoir t transfre sur le compte pour pouvoir lutiliser. De nombreux sites web proposent le tlchargement gratuit de fontes : www.fontfreak.com ou www.1001freefonts .com en sont deux bons exemples.
<?php header ("Content-type: image/png"); $image = @Imagecreate (250, 200); $couleur1 $couleur2 $couleur3 $blanc = = = = ImageColorAllocate ImageColorAllocate ImageColorAllocate ImageColorAllocate ($image, ($image, ($image, ($image, 212, 208, 200); 198, 193, 182); 79, 78, 74); 255, 255, 255);

for ($i = 0; $i <= 200; $i += 10) { ImageLine ($image, 0, $i, 250, $i, $couleur2); } ImageTTFText ($image,20,0,5,50,$couleur3,"font1.ttf","B o n j o u r"); ImageTTFText ($image,70,30,60,170,$blanc,"font2.ttf","Monde");

370 LE GUIDE COMPLET

Crer des fichiers spciaux


ImagePng ($image); ?>

Chapitre 12

Figure 12.18 : Des polices TrueType sont utilises pour dessiner les textes

Si la fonte se trouve dans un autre rpertoire, par exemple datas, il faut alors crire datas/font1.ttf. Vous remarquez que lcriture verticale est ici ralise avec la mme fonction que lcriture horizontale. Vous vous contentez en fait de mettre un angle de 30 degrs. PHP, en permettant daccder aux bases de donnes dune part et de gnrer des images dynamiques dautre part, est devenu un langage de choix pour la cration doutils de statistiques et de reporting. Vous allez dans la suite de ce chapitre raliser des graphiques retant les notes de vos lves. Pour cela, il nous faut ajouter la notion de notes et de classement votre base de donnes.

Les bases de donnes relationnelles


Comme vous lavez vu prcdemment, une base de donnes peut contenir plusieurs tables. Lavantage des BDD relationnelles telles que MySQL ou PostgreSQL est de permettre de crer des liens entre ces tables. On parle propos de ces bases de SGBDR (systme de gestion de bases de donnes relationnelles).

LE GUIDE COMPLET 371

Chapitre 12

La gestion des fichiers

Supposons que vous vouliez enregistrer dans votre base de donnes des informations concernant llve, son professeur et ses notes. Spontanment, un utilisateur non expriment pourrait proposer dorganiser ses donnes dans une seule et grande table comportant les champs suivants : nomeleve, prenomeleve, classement, moyenne, nomprofesseur. Cette manire de faire est proscrire tout de suite ! Vous vous apercevez trs vite, en remplissant la table, quil faut enregistrer le nom dun mme professeur pour tous les lves de sa classe :
j j

dupont, eric, 3, 16, mortier durand, michel, 12, 11, mortier

Cela vous fait donc perdre la fois du temps et de lespace disque inutilement. Un autre inconvnient de cette organisation est de ne pas permettre de conserver un historique des classements et des moyennes sur plusieurs trimestres. Les BDD relationnelles viennent alors votre secours. Si vous essayez de sparer intelligemment les donnes en plusieurs tables lies entre elles, ces inconvnients disparaissent instantanment. Vous pouvez en effet envisager lorganisation de vos donnes de cette manire : un professeur possde plusieurs lves et un lve possde plusieurs moyennes et classements. En terme de BDD, on peut dire que la table des professeurs est lie celle des lves et que cette dernire est lie celle des notes. Les liaisons correspondent en fait la prsence de lidentiant (idprof) du professeur dans la table eleve et lidentiant (ideleve) de llve dans la table moyenne. Vos trois tables sont donc :
j prof j j

: idprof, nom, prenom eleve : ideleve, idprof, nom, prenom exam : idexam, ideleve, moyenne, classement, trimestre

Pour slectionner le nom des lves qui ont, dune part, une moyenne suprieure 10 au premier trimestre et qui, dautre part, ont comme professeur M. Paul, vous pouvez utiliser la requte suivante :
372 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

SELECT eleve.nom AS nomeleve, prof.nom AS nomprof, exam .classement FROM prof, eleve, exam WHERE prof.nom = Paul AND eleve.idprof = prof.idprof AND moyenne .ideleve = eleve.ideleve AND exam.classement >= 10 AND exam.trimestre = 1

Analysons minutieusement cette requte. Comme vous avez besoin des trois tables, vous crivez FROM prof, eleve, exam. Les tables prof et eleve contiennent des colonnes intitules de la mme manire : nom et prenom. Il devient donc impossible, en travaillant sur ces deux tables en mme temps, dcrire WHERE nom = dupont car le serveur de BDD ne peut savoir sil doit faire une vrication sur la table prof ou sur la table eleve. Pour prciser de quel nom il sagit, utilisez la notation table.colonne, ds que vous voulez spcier une colonne dans une table en particulier :
WHERE prof.nom = Paul

De la mme manire, un obstacle apparat si vous voulez slectionner la fois le nom de llve et le nom du professeur dans la mme requte. La prcdente mthode ne servirait ici rien :
SELECT eleve.nom, prof.nom, exam.classement

Vous navez en effet aucun moyen, dans le rsultat de la requte, de prciser si vous voulez le nom du professeur ou celui de llve. La technique consiste donc renommer les colonnes au niveau de SELECT : eleve.nom AS nomeleve. De cette manire, en PHP, $tab[nomeleve] contient le nom de llve et $tab[nomprof] celui du professeur.
SELECT dans plusieurs tables

Il est donc trs dangereux dutiliser SELECT table1.*, table2.*, si table1 et table2 contiennent des colonnes de mme intitul.

Dans cet exemple, contentez-vous de crer une table exam :


CREATE TABLE exam ( idexam int(10) unsigned NOT NULL auto_increment, ideleve int(10) unsigned NOT NULL default 0, moyenne float(5,2) unsigned NOT NULL default 0.0, trimestre tinyint(3) unsigned NOT NULL default 0, PRIMARY KEY (idexam), KEY ideleve (ideleve) )

LE GUIDE COMPLET 373

Chapitre 12

La gestion des fichiers

Quelques remarques sur la cration de cette table :


j

La colonne des moyennes prsente des nombres virgule et est donc de type FLOAT. Il est possible avec les FLOAT de dterminer la prcision. (5,2) signie que le nombre peut stendre sur 5 caractres, avec 2 caractres aprs la virgule (19,25 stend bien sur 5 caractres virgule comprise). Il est pertinent de bien xer la prcision dun nombre virgule directement dans MySQL, cela vous vite de faire des conversions en PHP. Vous avez plac un index sur la colonne ideleve car il y a de fortes chances pour que les requtes sur cette table fassent intervenir prcisment cette colonne. La prsence du champ ideleve lie la table eleve la table exam et cre une relation entre ces deux tables.

Ajoutez la variable $table_exam votre chier variables.inc.php et ralisez un petit script qui devra :
j j

crer la table ; associer une note par trimestre chaque lve de la table.
Listing 12-14 : Cration et initialisation de la table exam
<?php include("variables.inc.php"); $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "CREATE TABLE $table_exam ( idexam int(10) unsigned NOT NULL auto_increment, ideleve int(10) unsigned NOT NULL default 0, moyenne float(5,2) unsigned NOT NULL default 0.0, trimestre tinyint(3) unsigned NOT NULL default 0, PRIMARY KEY (idexam), KEY ideleve (ideleve) )"; mysql_query ($sql); echo "cration de la table effectue<hr>"; $sql = "SELECT ideleve FROM $table_eleve"; $resultat = mysql_query ($sql); $i = 0; while ($eleve = mysql_fetch_array ($resultat))

374 LE GUIDE COMPLET

Crer des fichiers spciaux


{ $tab_eleves[$i] = $eleve[ideleve]; $i++; } $i = 0; srand ((double) microtime() * 1000000); while ($ideleve = $tab_eleves[$i]) { echo "eleve [$ideleve] :"; for ($j = 1; $j <= 3; $j++) { $moyenne = rand(0,20); echo " $moyenne"; $sql = "INSERT INTO $table_exam (ideleve,moyenne,trimestre) VALUES ($ideleve,$moyenne,$j)"; mysql_query ($sql); } echo "<br>"; $i++; } echo "<hr>moyennes enregistres<hr>"; mysql_close($liendb); ?>

Chapitre 12

Figure 12.19 : Initialisation de la table et des moyennes

LE GUIDE COMPLET 375

Chapitre 12

La gestion des fichiers

Crer des graphiques


Vous allez, dans cette partie, raliser un script qui permettra de voir lvolution de la moyenne de la classe sur les trois trimestres. Le graphique va tre du type bar chart. Suivez pas pas la faon de le construire. Limage est de type PNG :
header ("Content-type: image/png");

Elle a pour dimensions 340 x 200 :


$image = @Imagecreate (340, 220);

La couleur de fond est le mme vert que vous avez utilis dans le back-office :
$fond = ImageColorAllocate ($image, 208, 216, 213);

Dautres couleurs sont utilises pour les axes, les lgendes, etc. Dclarez-les ds maintenant :
$coul_axes = ImageColorAllocate ($image, 11, 62, 43); $coul_lignes = ImageColorAllocate ($image, 227, 235, 232); $coul_legendes = ImageColorAllocate ($image, 11, 62, 43); $coul_barres = ImageColorAllocate ($image, 42, 124, 94); $coul_orange = ImageColorAllocate ($image, 207, 140, 53);

Deux axes, vertical et horizontal, sont prsents :


imageline ($image,30,30,30,190,$coul_axes); imageline ($image,30,190,320,190,$coul_axes);

Terminez le script avec la gnration de limage :


ImagePng ($image);

Figure 12.20 : Gnration dun graphique

376 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

Origine dune image

Langle suprieur gauche de limage a pour coordonnes (0,0). Les coordonnes vont donc de gauche droite et de haut en bas.

Dessinez les ches lextrmit des axes. Pour cela, vous devez utiliser la fonction imagefilledpolygon() qui permet de dessiner un polygone (une forme gomtrique n cts). Cette fonction prend quatre arguments :
j j j j

lidentiant ; un tableau contenant les coordonnes des diffrents points formant le polygone (x0, y0, x1, y1, etc.) ; le nombre de sommets du polygone ; la couleur du polygone.

$tab_fleche_ord = array (30, 30, 26, 34, 34, 34); $tab_fleche_abs = array (320, 190, 316, 186, 316, 194); imagefilledpolygon ($image, $tab_fleche_ord, 3, $coul_axes); imagefilledpolygon ($image, $tab_fleche_abs, 3, $coul_axes);

Pour vous rendre compte de lavance, dnissez des affichages intermdiaires. Le code contient pour linstant les instructions suivantes :
<?php header ("Content-type: image/png"); // cration de limage $image = @Imagecreate (340, 220); // dfinition des couleurs $fond = ImageColorAllocate ($image, 208, 216, 213); $coul_axes = ImageColorAllocate ($image, 11, 62, 43); $coul_lignes = ImageColorAllocate ($image, 227, 235, 232); $coul_legendes = ImageColorAllocate ($image, 11, 62, 43); $coul_barres = ImageColorAllocate ($image, 42, 124, 94); $coul_orange = ImageColorAllocate ($image, 207, 140, 53); // les axes imageline ($image,30,30,30,190,$coul_axes); imageline ($image,30,190,320,190,$coul_axes); // les flches au bout des axes $tab_fleche_ord = array (30, 30, 26, 34, 34, 34);
LE GUIDE COMPLET 377

Chapitre 12

La gestion des fichiers

$tab_fleche_abs = array (320, 190, 316, 186, 316, 194); imagefilledpolygon ($image, $tab_fleche_ord, 3, $coul_axes); imagefilledpolygon ($image, $tab_fleche_abs, 3, $coul_axes); // gnration de limage ImagePng ($image); ?>

Passez maintenant laffichage des lgendes des axes :


ImageTTFText ($image,10,0,5,20,$coul_legendes,"arial.ttf","moyenne"); ImageTTFText ($image,10,0,280,180,$coul_legendes,"arial .ttf", "trimestre");

Laxe des ordonnes dispose dune graduation de 0 20 :


imageline imageline imageline imageline imageline ($image,26,190,30,190,$coul_axes); ($image,26,155,30,155,$coul_axes); ($image,26,120,30,120,$coul_axes); ($image,26,85,30,85,$coul_axes); ($image,26,50,30,50,$coul_axes);

Les ordonnes sont indiques au niveau de la graduation :


ImageTTFText ImageTTFText ImageTTFText ImageTTFText ImageTTFText ($image,8,0,6,190,$coul_legendes,"arial.ttf", "0"); ($image,8,0,6,155,$coul_legendes,"arial.ttf", "5"); ($image,8,0,6,120,$coul_legendes,"arial.ttf", "10"); ($image,8,0,6,85,$coul_legendes,"arial.ttf", "15"); ($image,8,0,6,50,$coul_legendes,"arial.ttf", "20");

Pour faciliter la lecture des valeurs, affichez une trame horizontale lgre :
imageline imageline imageline imageline ($image,31,155,320,155,$coul_lignes); ($image,31,120,320,120,$coul_lignes); ($image,31,85,320,85,$coul_lignes); ($image,31,50,320,50,$coul_lignes);

Affichez maintenant les barres avec des valeurs xes. Moyenne de la classe :
j j j

Premier trimestre : 13,5. Deuxime trimestre : 12. Troisime trimestre : 16.

378 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

Figure 12.22 : Ajout de la graduation et des lgendes

La difficult est de trouver la hauteur des barres. Vous disposez de 140 pixels (190-50) pour afficher des donnes qui vont au maximum jusqu 20. Comme les coordonnes vont de haut en bas, cest en fait la diffrence entre la note et la note maximale (20) qui doit vous intresser. Une simple rgle de trois permet ensuite de trouver lordonne du sommet des barres : (20 note) * 7 + 50.
imagefilledrectangle ($image, 40, (20-13.5)*7+50, 110, 189, $coul_barres); imagefilledrectangle ($image, 120, (20-12)*7+50, 190, 189, $coul_barres); imagefilledrectangle ($image, 200, (20-16)*7+50, 270, 189, $coul_barres);

Affichez dans les barres la valeur de la moyenne :


ImageTTFText ($image,10,0,50,180,$coul_orange,"arial.ttf", "13.5"); ImageTTFText ($image,10,0,130,180,$coul_orange,"arial.ttf", "12"); ImageTTFText ($image,10,0,210,180,$coul_orange,"arial.ttf", "16");

Regroupez maintenant toutes les parties au sein dun script graph.php et allez chercher les vritables valeurs dans la table exam :
Listing 12-15 : Script graph.php <?php include("variables.inc.php");

LE GUIDE COMPLET 379

Chapitre 12

La gestion des fichiers

// rcupration de la moyenne de la classe sur les 3 trimestres $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_exam"; $resultat = mysql_query ($sql); // le tableau $tab contient 3 cases pour les 3 trimestres // (de 0 2) // chaque case contient la somme de toutes les moyennes // des lves pour le trimestre donn $i = 0; while ($tmp = mysql_fetch_array ($resultat)) { $tab[$tmp[trimestre] - 1] += $tmp[moyenne]; $i++; } mysql_close($liendb); // la variable $i contient le nombre de notes totales dans // la table exam elle permet dobtenir le nombre dlves $nb_eleves = $i / 3; // utilisez la fonction number_format pour navoir que // 2 chiffres aprs la virgule for ($i = 0; $i < 3; $i++) { $tab[$i] = number_format($tab[$i] / $nb_eleves, 2); } //--------------------------------------------------------header ("Content-type: image/png"); // cration de limage $image = @Imagecreate (340, 220); // dfinition des couleurs $fond = ImageColorAllocate ($image, 208, 216, 213); $coul_axes = ImageColorAllocate ($image, 11, 62, 43); $coul_lignes = ImageColorAllocate ($image, 227, 235, 232); $coul_legendes = ImageColorAllocate ($image, 11, 62, 43); $coul_barres = ImageColorAllocate ($image, 42, 124, 94); $coul_orange = ImageColorAllocate ($image, 207, 140, 53); // les axes imageline ($image,30,30,30,190,$coul_axes); imageline ($image,30,190,320,190,$coul_axes); // les flches au $tab_fleche_ord = $tab_fleche_abs = imagefilledpolygon bout des axes array (30, 30, 26, 34, 34, 34); array (320, 190, 316, 186, 316, 194); ($image, $tab_fleche_ord, 3, $coul_axes);

380 LE GUIDE COMPLET

Crer des fichiers spciaux

Chapitre 12

imagefilledpolygon ($image, $tab_fleche_abs, 3, $coul_axes); // lgendes ImageTTFText ($image,10,0,5,20,$coul_legendes,"arial .ttf","moyenne"); ImageTTFText ($image,10,0,280,180,$coul_legendes,"arial .ttf","trimestre"); // graduations imageline ($image,26,190,30,190,$coul_axes); imageline ($image,26,155,30,155,$coul_axes); imageline ($image,26,120,30,120,$coul_axes); imageline ($image,26,85,30,85,$coul_axes); imageline ($image,26,50,30,50,$coul_axes); // ordonnes ImageTTFText ($image,8,0,6,190,$coul_legendes,"arial .ttf","0"); ImageTTFText ($image,8,0,6,155,$coul_legendes,"arial .ttf","5"); ImageTTFText ($image,8,0,6,120,$coul_legendes,"arial .ttf","10"); ImageTTFText ($image,8,0,6,85,$coul_legendes,"arial .ttf","15"); ImageTTFText ($image,8,0,6,50,$coul_legendes,"arial .ttf","20"); // lignes lgres imageline ($image,31,155,320,155,$coul_lignes); imageline ($image,31,120,320,120,$coul_lignes); imageline ($image,31,85,320,85,$coul_lignes); imageline ($image,31,50,320,50,$coul_lignes); // affichage des barres imagefilledrectangle ($image, 40, (20 - $tab[0]) * 7 + 50, 110, 189, $coul_barres); imagefilledrectangle ($image, 120, (20 - $tab[1]) * 7 + 50, 190, 189, $coul_barres); imagefilledrectangle ($image, 200, (20 - $tab[2]) * 7 + 50, 270, 189, $coul_barres); // affichage de la valeur de la barre ImageTTFText ($image,10,0,50,180,$coul_orange,"arial .ttf",$tab[0]); ImageTTFText ($image,10,0,130,180,$coul_orange,"arial .ttf",$tab[1]); ImageTTFText ($image,10,0,210,180,$coul_orange,"arial .ttf",$tab[2]); ImagePng ($image); ?>

Ajoutez nalement la ligne suivante en bas du script admin.php an davoir un aperu de la moyenne de la classe :
<img src="graph.php" />

LE GUIDE COMPLET 381

Chapitre 12

La gestion des fichiers

Figure 12.23 : Un graphique inclus dans la page

12.3. Check-list
j

j j j

j j

PHP dispose de toutes les fonctions permettant de travailler sur les chiers texte : ouverture, modication, suppression, dplacement, etc. La technique dite des chiers de cache est particulirement intressante pour allger les ressources utilises par un script. Des extensions peuvent tre charges an de permettre PHP de gnrer des chiers plus complexes : PDF, Flash, image, etc. PHP, via la librairie GD, permet de travailler trs nement sur les images. Cette extension est compatible avec la plupart des formats de chiers image actuels : GIF, JPEG, PNG, etc. La gnration dun chier spcial ncessite lutilisation de la fonction header(). Le format XML permet de stocker des informations et se rvle tre le meilleur choix pour les changes de chiers structurs.

382 LE GUIDE COMPLET

La programmation objet
Classes et objets ................................................................................................................ 385 Les mthodes magiques .................................................................................................. 393 Polymorphisme ................................................................................................................... 398 Les interfaces ...................................................................................................................... 401 Itrateurs .............................................................................................................................. 403 Exceptions ........................................................................................................................... 405 Rflexion .............................................................................................................................. 409 Version objet de la gnration de graphique .............................................................. 410 Check-list ............................................................................................................................. 416

Chapitre 13

La programmation objet

Les exemples tudis jusqu maintenant taient dvelopps de faon procdurale. Fonctions et variables taient mlanges au sein de vos sources, sans relle cohrence ni logique. La programmation oriente objet (POO) propose un nouveau paradigme en vous permettant de manipuler des entits disposant chacune de leurs propres informations et traitements. Lapplicatif nal consiste ensuite faire fonctionner ces diffrents objets de faon collaborative et intelligente. Cette faon doprer facilite la fois
j j j j

la modlisation ; la maintenance ; la relecture ; lvolutivit.

Longtemps dcrie, la dimension objet de PHP a gagn ses lettres de noblesse avec larrive de la version 5 du langage. Cette volution devenait indispensable dans une industrie informatique o tout applicatif denvergure se doit dtre crit en objet. Parmi les volutions majeures, la version 5 a notamment apport :
j j j j j j j j j j j j j

une distinction claire entre la copie et la duplication dobjets ; la gestion des interfaces ; loprateur instanceof ; le mot-cl final ; les constantes de classe ; les mthodes abstraites ; les mthodes et les attributs statiques ; les constructeurs et destructeurs ; la syntaxe $monObjet>bonjour()>monde() ; les exceptions ; les itrateurs ; la possibilit de dnir une fonction __autoload() ; lapparition de diffrents niveaux de visibilit : public, protected, private.

384 LE GUIDE COMPLET

Classes et objets

Chapitre 13

Plus gnralement, les concepteurs du langage tendent rendre la plateforme PHP rellement objet en fournissant la plupart des nouvelles extensions sous forme de classes (ex: PDO, XML, SOAP, etc.). Cette objectisation correspond prcisment au d majeur que PHP devra relever dans les annes venir :

1 Devenir un vritable langage objet o tout lment est lui-mme objet (types de donnes, I/O, etc.) an dattirer les dveloppeurs chevronns et les acteurs majeurs de lindustrie informatique (chasse garde actuelle de Java et C#). 2 Ne pas perdre cette facilit daccs ingalable qui lui a permis de devenir le premier langage de programmation web mondial.

13.1. Classes et objets


Deux notions fondamentales interviennent en POO : les classes et les objets.

Classes
Une classe peut tre assimile un moule qui permet de crer des objets. Cette opration de cration est appele une instanciation.

Dclaration dune classe


Le mot-cl class est utilis pour dnir une classe.
Listing 13-1 : Dfinition de la classe Rectangle class Rectangle { }

Cette classe doit maintenant tre complte de fonctions et de donnes qui lui sont propres. En POO, les fonctions sont appeles mthodes et les donnes, attributs. La classe Rectangle peut disposer par exemple :
j j

des mthodes : surface(), perimetre() ; des attributs : longueur, largeur et couleur.

LE GUIDE COMPLET 385

Chapitre 13

La programmation objet

Les mthodes surface() et perimetre() ont la possibilit daccder aux attributs de la classe par lintermdiaire de la variable $this qui peut tre assimile une rfrence lobjet lui-mme.
Listing 13-2 : Dclaration de la classe Rectangle <?php class Rectangle { public $longueur = null; public $largeur = null; public $couleur = "rouge"; function perimetre() { if ($this->longueur!=null && $this->largeur!=null) { return (2*$this->longueur+2*$this->largeur); } } function surface() { if ($this->longueur!=null && $this->largeur!=null) { return ($this->longueur*$this->largeur); } } }

Nom des mthodes

Il est vivement dconseill de commencer le nom des mthodes par deux caractres __ (caractre espace soulign). PHP utilise en effet cette norme pour nommer ses mthodes, dites magiques .

Initialisation des attributs


Un attribut ne peut tre initialis quavec une valeur constante. Les initialisations suivantes ne sont par consquent pas valides :
Listing 13-3 : Initialisation interdites public $date = date(); public $id = "Paul"."Dupont";

La fonction array() peut cependant tre utilise si tous les lments du tableau correspondent des donnes statiques.
386 LE GUIDE COMPLET

Classes et objets
Listing 13-4 : Initialisation autorise public $tab = array("abc",123);

Chapitre 13

Objets
Linstanciation dun objet utilise le mot-cl new. Un objet $rectangle peut tre cr avec la syntaxe suivante :
Listing 13-5 : Instanciation dun objet $rect = new Rectangle();

Une fois lobjet cr, vous pouvez accder ses attributs et ses mthodes avec le sparateur >.
Listing 13-6 : Rcupration de la valeur dun attribut et utilisation dune mthode $rect = new Rectangle(); echo $rect->couleur; $rect->longueur = 3; $rect->largeur = 5; $tmp = $rect->perimetre();

PHP autorise galement lutilisation dune variable pour spcier un attribut derrire le sparateur >.
Listing 13-7 : Lattribut est spcifi laide dune variable $rect = new Rectangle(3,5); $attr = "longueur"; $rect->$attr = 4;

Cration dynamique dattributs

PHP permet de crer des attributs la vole :


$monrect = new Rectangle(); $monrect>toto = 1;

Lobjet $monrect contient dsormais lattribut $toto.

La fonction var_dump() permet de visualiser les attributs dune classe.


Listing 13-8 : Utilisation de var_dump() $rect = new Rectangle(); print("<pre>"); var_dump($rect);
LE GUIDE COMPLET 387

Chapitre 13

La programmation objet

print("</pre>");

Figure 13.1 : Contenu de lobjet $rect

La vrication de la correspondance dun objet linstanciation dune classe donne peut tre ralise avec loprateur instanceof.
Listing 13-9 : Vrification quun objet est bien linstance dune classe donne $rect = new Rectangle(3,5); if ($rect instanceof Rectangle) { print("Lobjet est un rectangle"); }

Variables globales et classes

Le mot-cl global et la super globale $GLOBALS peuvent tre utiliss au sein dune classe pour faire rfrence aux variables globales du script.

Fonction __autoload()
PHP doit disposer, pour instancier un objet, de la dnition de la classe associe. Les sources de la classe peuvent tre places au sein mme du script ou dans un chier extrieur inclus via la fonction require_once(). Cette seconde possibilit a lavantage dautoriser le partage de la classe avec dautres scripts de lapplicatif. Linclusion dun chier de dnition de classe est moins fastidieuse depuis PHP5. Si votre script dispose dune fonction __autoload(), PHP y fera appel pour chaque instanciation dobjet de la classe duquel il ne dispose pas.
388 LE GUIDE COMPLET

Classes et objets

Chapitre 13

Listing 13-10 : Dfinition de la fonction __autoload() qui ira chercher toutes les dfinitions de classe dans le rpertoire class function __autoload($nom_classe) { require_once("class/".$nom_classe.".php"); }

__autoload()

La fonction __autoload() ne doit tre dnie quune fois dans votre script !

Mot-cl static et constantes de classe


Les attributs et les mthodes dont les dnitions sont compltes du mot-cl static peuvent tre utiliss sans ncessiter linstanciation dun objet. Le sparateur :: remplace alors > pour y accder.
Listing 13-11 : Utilisation dun attribut et dune mthode static class Rectangle { public static $nom = rectangle; static function presentation() { print("Bonjour je suis un rectangle"); } } echo Rectangle::$nom; Rectangle::presentation();

Une mthode (static ou non) ne peut utiliser la variable $this pour accder un lment static (attribut ou mthode) de la classe. En effet, vous ntes pas au niveau objet mais au niveau classe. Le mot-cl self est alors utilis pour faire rfrence la classe elle-mme.
Listing 13-12 : Utilisation dun attribut static au sein de la classe class Rectangle { public static $nom = rectangle; static function presentation() { print("Bonjour je suis un ".self::$nom); } }

Les constantes de classe ne diffrent des attributs static que du point de vue de leur syntaxe : le mot-cl const est utilis pour leur dclaration et aucun $ ne les prcde.

LE GUIDE COMPLET 389

Chapitre 13

La programmation objet

Listing 13-13 : Utilisation dune constante de classe class Rectangle { const NOM = rectangle; static function presentation() { print("Bonjour je suis un ".self::NOM); } } echo Rectangle::NOM;

Comme les attributs, ces constantes ne peuvent tre initialises quavec des valeurs statiques.

Conversion
PHP donne la possibilit de convertir un objet en tableau et inversement. Le moyen pour y parvenir consiste utiliser une opration de cast.
Listing 13-14 : Conversion dun objet en tableau. class Test { public $a = 1; public $b = 2; function hello {} } $test = new Test(); $tab = (array) $test;

Figure 13.2 : Tous les attributs sont conservs

Listing 13-15 : Conversion dun tableau en objet $tab = array("a"=>1, "b"=>2); $obj = (object) $tab; var_dump($obj);

390 LE GUIDE COMPLET

Classes et objets

Chapitre 13

Figure 13.3 : Conversion du tableau

Constructeur et destructeur
La classe Rectangle reposant sur deux attributs essentiels ($longueur et $largeur), la grande majorit des instanciations sera suivie de leur initialisation. Pour viter cette situation, la POO prvoit lutilisation dune fonction spcique : le constructeur. En PHP, le constructeur correspond une mthode portant le nom __contruct(). Cette fonction est appele au moment de linitialisation de lobjet et reoit les arguments transmis la classe lors de linstanciation de lobjet. Lutilisation principale dun constructeur reste linitialisation des attributs de la classe.
Listing 13-16 : Initialisation automatique de lobjet grce au constructeur class Rectangle { public $longueur = null; public $largeur = null; public $couleur = "rouge"; const NOM = "Super Rectangle"; function __construct($longueur,$largeur) { $this->longueur = $longueur; $this->largeur = $largeur; } function perimetre() { if ($this->longueur!=null && $this->largeur!=null) { return (2*$this->longueur+2*$this->largeur); } }

LE GUIDE COMPLET 391

Chapitre 13

La programmation objet

function surface() { if ($this->longueur!=null && $this->largeur!=null) { return ($this->longueur*$this->largeur); } } } $rect = new Rectangle (3,5);

PHP prvoit galement la possibilit de dnir une mthode __destruct() qui, si elle existe, sera appele juste avant la suppression de lobjet. Ce destructeur est extrmement utile pour les objets utilisant des ressources extrieures telles quune base de donnes, un chier ou un service web. Au moment de la destruction de lobjet, le destructeur se charge alors de nettoyer son environnement en fermant les ressources ouvertes.
Listing 13-17 : Appels au constructeur et au destructeur class Rectangle { public $longueur = null; public $largeur = null; public $couleur = "rouge"; const NOM = "Super Rectangle"; function __construct($longueur,$largeur) { print("Hello ".self::NOM."<br/>"); $this->longueur = $longueur; $this->largeur = $largeur; } function perimetre() { if ($this->longueur!=null && $this->largeur!=null) { return (2*$this->longueur+2*$this->largeur); } } function surface() { if ($this->longueur!=null && $this->largeur!=null) { return ($this->longueur*$this->largeur); } } function __destruct() { print("Bye bye ".self::NOM."<br/>"); }

392 LE GUIDE COMPLET

Les mthodes magiques

Chapitre 13

} $rect = new Rectangle(3,5); unset($rect);

Figure 13.4 : Les deux fonctions sont bien appeles

Valeur null

Le destructeur est galement appel lorsque la variable $rect prend la valeur null.

13.2. Les mthodes magiques


Il sagit de mthodes optionnelles normalises par PHP et appeles suite certains vnements sur les objets. Les mthodes __construct() et __destruct() appeles lors de la cration et la destruction dun objet sont de bons exemples de mthodes magiques.

__sleep() et __wakeup()
Les fonctions serialize() et unserialize() prsentes dans le chapitre consacr aux tableaux peuvent galement tre utilises sur des objets. Dans un tel cas, PHP appelle, si elles existent dans la classe, les mthodes __sleep() avant la srialisation et __wakeup() aprs la dsrialisation. Cette fonctionnalit est particulirement utile lorsque votre objet repose sur une connexion ou un chier extrieur. La fonction __sleep() peut alors tre utilise pour fermer les connections et __wakeup() pour les rouvrir.

LE GUIDE COMPLET 393

Chapitre 13

La programmation objet

__toString()
Cette mthode est appele lorsque PHP se retrouve devoir afficher un objet avec print() ou echo() (lobjet doit tre seul entre parenthses !). Si cette mthode existe, PHP affichera la valeur de retour de __toString() plutt que le message Object id #X. Cette fonctionnalit est particulirement utile pour debugger vos scripts.
Listing 13-18 : Utilisation de la mthode __toString() class Rectangle { public $longueur = null; public $largeur = null; public $couleur = "rouge"; const NOM = "Super Rectangle"; function __construct($longueur,$largeur) { $this->longueur = $longueur; $this->largeur = $largeur; } function __toString() { return (self::NOM." [".$this->longueur."x". $this->largeur."]"); } } $rect = new Rectangle(3,5); print($rect);

Figure 13.5 : La fonction print()affiche la valeur retourne par la mthode

__toString()

Surcharge des accesseurs


Lorsque la mthode __call() est incluse au sein dune classe, PHP lutilise pour chaque appel une mthode non dnie de lobjet. Le

394 LE GUIDE COMPLET

Les mthodes magiques

Chapitre 13

premier argument de __call() correspond au nom de la mthode appele et le second argument, un tableau des diffrents arguments de la mthode appele.
Listing 13-19 : Utilisation de la mthode __call() class Rectangle { public $longueur = null; public $largeur = null; public $couleur = "rouge"; const NOM = "Super Rectangle"; function __construct($longueur,$largeur) { $this->longueur = $longueur; $this->largeur = $largeur; } function __call($methode,$arguments) { return ("Appel la methode ".$methode."() de ".self::NOM ); } function surface() { if ($this->longueur!=null && $this->largeur!=null) { return ($this->longueur*$this->largeur); } } } $rect = new Rectangle(3,5); echo $rect->coucou()."<br/>"; echo $rect->surface();

Figure 13.6 : Lappel de la mthode coucou()conduit un appel de __call()

Associe la fonction call_user_func(), la mthode __call() peut tre utilise pour tracer puis dlguer de faon gnrique les appels des mthodes internes.

LE GUIDE COMPLET 395

Chapitre 13

La programmation objet

Listing 13-20 : Utilisation de __call() pour dlguer les appels de mthodes class Rectangle { public $longueur = null; public $largeur = null; public $couleur = "rouge"; const NOM = "Super Rectangle"; function __construct($longueur,$largeur) { $this->longueur = $longueur; $this->largeur = $largeur; } function __call($methode,$arguments) { print ("Mthode [ ".$methode." ]<br/>"); $tmp = _.$methode; return call_user_func(array($this,$tmp),$arguments); } function _perimetre() { if ($this->longueur!=null && $this->largeur!=null) { return (2*$this->longueur+2*$this->largeur); } } function _surface() { if ($this->longueur!=null && $this->largeur!=null) { return ($this->longueur*$this->largeur); } } } $rect = new Rectangle(3,5); echo $rect->surface(); echo "<br/>"; echo $rect->perimetre();

Figure 13.7 : Chaque appel une mthode est trac

Les mthodes __set() et __get() sont appeles lorsque vous souhaitez modier ou rcuprer des attributs qui nexistent pas.
396 LE GUIDE COMPLET

Les mthodes magiques

Chapitre 13

Lexemple suivant montre comment utiliser ces deux mthodes pour travailler avec lattribut virtuel dim.
Listing 13-21 : Utilisation des mthodes __get() et __set() class Rectangle { public $longueur = null; public $largeur = null; public $couleur = "rouge"; const NOM = "Super Rectangle"; function __construct($longueur,$largeur) { $this->longueur = $longueur; $this->largeur = $largeur; } function __set($nom,$val) { if ($nom=="dim" && count($val)==2) { list ($this->longueur, $this->largeur) = $val; } } function __get($nom) { if ($nom=="dim") { return array($this->longueur,$this->largeur); } } function surface() { if ($this->longueur!=null && $this->largeur!=null) { return ($this->longueur*$this->largeur); } } } $rect = new Rectangle(3,5); $rect->dim = array(2,3); $dim = join("x",$rect->dim); echo "Surface dun rectangle de $dim = "; echo $rect->surface();

Figure 13.8 : Affichage du rsultat

LE GUIDE COMPLET 397

Chapitre 13

La programmation objet

Sur le mme principe, les mthodes __isset() et __unset() peuvent tre dnies.

13.3. Polymorphisme
Le polymorphisme est un des principes les plus importants de la programmation objet. Lide principale consiste crer un lien dhritage entre deux classes.

Principe gnral
En drivant dune classe mre, la classe lle hrite de ses mthodes et de ses attributs qui viendront sajouter celles et ceux dj dnis. Encore plus intressant, la classe lle peut rednir les attributs et les mthodes de la classe mre : on dit alors quelle les surcharge. En favorisant lhritage entre vos classes vous augmentez la gnricit de vos classes et favorisez leur rutilisation. Tout le code gnrique est plac dans les classes parentes, et les codes spciques dans les classes lles. Au niveau syntaxique, une classe B hrite de la classe A en utilisant le mot-cl extends :
Listing 13-22 : La classe B tend la classe A class B extends A { }

En considrant quun carr est un rectangle dont les cts sont gaux, vous pouvez modliser cette relation en dclarant une classe Carr qui tend la classe Rectangle. Le mot-cl parent permet daccder aux mthodes et attributs de la classe mre. Il est particulirement utile pour faire remonter les paramtres dinitialisation la classe mre.
Listing 13-23 : La classe Carre hrite de la mthode surface() de la classe Rectangle class Rectangle { public $longueur = null; public $largeur = null; const NOM = "Rectangle";

398 LE GUIDE COMPLET

Polymorphisme

Chapitre 13

function __construct($longueur,$largeur) { $this->longueur = $longueur; $this->largeur = $largeur; } function surface() { if ($this->longueur!=null && $this->largeur!=null) { return ($this->longueur*$this->largeur); } } } class Carre extends Rectangle { public $cote = null; const NOM = "Carr"; function __construct($cote) { parent::__construct($cote,$cote); $this->cote = $cote; } } $carre = new Carre(5); echo $carre->surface();

Mot-cl final

Le mot-cl final accol la dnition dune classe interdit quelle soit tendue. Accol la dnition dune mthode, il interdit que cette mthode soit surcharge.

Visibilit
Une notion de visibilit peut tre associe la dnition des mthodes et des attributs. La visibilit par dfaut correspond public et autorise un accs sans restriction. Les modes private et protected limitent quant eux les accs de la faon suivante :
j

private signie que seule la classe associe peut accder la

mthode (ou lattribut) ;

LE GUIDE COMPLET 399

Chapitre 13
j

La programmation objet

protected signie que seules les classes disposant dun lien

dhritage peuvent accder la mthode (ou lattribut). La visibilit doit prcder la dnition de lattribut ou de la mthode :
Listing 13-24 : Exemple de dfinition dun attribut en mode protected et dune mthode en mode private protected $str = ""; private function maMethode() {}

PHP met une erreur en cas de non-respect de la rgle de visibilit :


Listing 13-25 : Laccs une mthode protge dclenche laffichage dune erreur class Rectangle { private $longueur = null; private $largeur = null; function __construct($longueur,$largeur) { $this->longueur = $longueur; $this->largeur = $largeur; } protected function surface() { if ($this->longueur!=null && $this->largeur!=null) { return ($this->longueur*$this->largeur); } } } $rect = new Rectangle(3,2); echo $rect->surface();

Figure 13.9 : Erreur correspondant laccs une mthode protge

400 LE GUIDE COMPLET

Les interfaces

Chapitre 13

13.4. Les interfaces


Certains langages de programmation permettent une classe dhriter de plusieurs classes mres. Les concepteurs de PHP nont pas souhait mettre uvre cet hritage multiple et ont prfr travailler sur la notion dinterface. Une interface correspond un ensemble de dnitions de mthodes quune classe devra surcharger si elle souhaite limplmenter. Une classe peut implmenter plusieurs interfaces. La dnition dune interface utilise le mot-cl interface suivi dun bloc contenant la dnition des mthodes.
Listing 13-26 : Dfinition dune interface interface MonInterface { public function methode1 (); public function methode2 (); // etc. }

Une classe implmente une interface en utilisant le mot-cl implements.


Listing 13-27 : Chaque classe doit implmenter la mthode aCotesEgaux() interface ObjetGeom { public function aCotesEgaux (); } class Rectangle implements ObjetGeom{ private $longueur = null; private $largeur = null; function __construct($longueur,$largeur) { $this->longueur = $longueur; $this->largeur = $largeur; } function aCotesEgaux () { if ($this->largeur==$this->longueur) { return true; } return false; } }

LE GUIDE COMPLET 401

Chapitre 13

La programmation objet

class Carre extends Rectangle { public $cote = null; function __construct($cote) { parent::__construct($cote,$cote); $this->cote = $cote; } function aCotesEgaux () { return true; } }

Toutes les mthodes des interfaces doivent tre implmentes par la classe. Une erreur est dclenche dans le cas contraire.
Listing 13-28 : La classe Carre nimplmente pas getNbCotes() interface ObjetGeom { public function aCotesEgaux (); public function getNbCotes (); } class Carre implements ObjetGeom { public $cote = null; function __construct($cote) { parent::__construct($cote,$cote); $this->cote = $cote; } function aCotesEgaux () { return true; } }

Figure 13.10 : Affichage du rsultat

402 LE GUIDE COMPLET

Itrateurs

Chapitre 13

Une interface peut tre assimile un contrat que doit respecter la classe qui limplmente.

13.5. Itrateurs
La boucle foreach() peut tre utilise sur un objet an dafficher ses diffrents attributs.
$rect = new Rectangle(3,5); foreach ($rect as $attr => $val) { print("$attr = $val<br/>"); }

Figure 13.11 : Affichage des diffrents attributs de lobjet $rect avec la boucle foreach()

Le comportement par dfaut consiste passer, chaque itration de la boucle, dun attribut visible lautre. PHP vous permet dimplmenter linterface Iterator an de dnir vous-mme le comportement de la boucle foreach() :
Tableau 13.1 : Diffrentes fonctions devant tre implmentes pour dnir

votre propre itrateur. Mthode Rle Revient au dbut de la liste Valeur de llment en cours Valeur de la cl de llment en cours Passer llment suivant Retourne false lorsque vous tes la n de la ligne (true sinon)

rewind() current() key() next() valid()

LE GUIDE COMPLET 403

Chapitre 13

La programmation objet

Lexemple suivant permet ditrer parmi les diffrentes valeurs de lattribut $tab plutt que parmi les attributs de lobjet.
Listing 13-29 : Dfinition de votre propre itrateur class Rectangle implements Iterator{ public public public public public $longueur = null; $largeur = null; $couleur = "rouge"; $tab = array("mm","cm","m"); $i = 0;

function __construct($longueur,$largeur) { $this->longueur = $longueur; $this->largeur = $largeur; } public function rewind() { print("rewind<br/>"); $this->i = 0; } public function current() { print("current<br/>"); return ($this->tab[$this->i]); } public function key() { print("key<br/>"); return ($this->i); } public function next() { print("next<br/>"); $this->i++; } public function valid() { print("valid<br/>"); if ($this->i<count($this->tab)) return true; return false; } } $rect = new Rectangle(3,5); foreach ($rect as $attr => $val) { print("<b>$attr = $val</b><br/>"); }

404 LE GUIDE COMPLET

Exceptions

Chapitre 13

Figure 13.12 : Trace des diffrents appels de PHP lors de la mise en uvre dun itrateur avec la boucle foreach

13.6. Exceptions
La gestion derreurs en POO fait intervenir une notion supplmentaire : les exceptions. Ces dernires correspondent des signaux pouvant tre mis par une mthode et capturs ailleurs dans le code.

Principe gnral
Lmission dune exception utilise le mot-cl throw.
Listing 13-30 : La mthode test() met une exception lorsque $n est null class MonObjet { function test($n=null) { if ($n==null) throw new Exception("La valeur ne convient pas"); return true; } }

LE GUIDE COMPLET 405

Chapitre 13

La programmation objet

Mot cl throw

Lmission dune exception termine la mthode la manire dun return ().

La capture dune exception fait intervenir la structure try { }


catch () { }.

Le bloc try permet denglober lensemble des appels aux mthodes susceptibles dmettre des exceptions. Le bloc catch() se charge quant lui de recevoir lensemble des exceptions mises par ces mthodes. Un bloc try doit obligatoirement tre suivi dun bloc catch().
Listing 13-31 : Contrle dun code susceptible dmettre une exception $obj = new MonObjet(); try { // utilisation dune mthode susceptible // dmettre une exception $obj->test(); } catch (Exception $e) { // traitement de lexception print($e->getMessage()); }

De la bonne utilisation des exceptions

Les exceptions ne doivent en aucun cas remplacer une gestion standard derreur. Elles ne doivent tre utilises que pour signaler des situations exceptionnelles.

Lexemple suivant montre comment mettre une exception quand la mthode surface() est appele sur un rectangle invalide.
Listing 13-32 : Gestion dune exception dans la mthode surface() class Rectangle { public $longueur = null; public $largeur = null; function __construct($longueur,$largeur) { $this->longueur = $longueur; $this->largeur = $largeur; }

406 LE GUIDE COMPLET

Exceptions

Chapitre 13

function surface() { if ($this->longueur<1 || $this->largeur<1) { throw new Exception("Valeurs incohrentes"); } return ($this->longueur*$this->largeur); } } $rect = new Rectangle(-1,4); try { echo $rect->surface(); } catch (Exception $e) { print("<hr/>".$e->getMessage()."<hr/>"); }

Figure 13.13 : Affichage de lexception

La classe Exception
Une exception correspond une instance de la classe Exception. Chaque nouvelle instance peut tre initialise avec un ou deux arguments. Le premier argument correspond au texte du message derreur et le second, optionnel, au code derreur. Cette classe dispose dun certain nombre de mthodes pouvant tre trs utiles dans une phase de dbogage.
Tableau 13.2 : Mthodes proposes par la classe Exception

Mthode

Rle Retourne la valeur du message Retourne la valeur du code derreur Retourne le nom du chier do lexception a t mise

getMessage() getCode() getFile()

LE GUIDE COMPLET 407

Chapitre 13

La programmation objet

Tableau 13.2 : Mthodes proposes par la classe Exception

Mthode

Rle Retourne le numro de la ligne o lexception a t mise Retourne un tableau de la trace derreur Retourne une chane de caractres correspondant la trace de lerreur

getLine() getTrace() getTraceAsString()

Listing 13-33 : Utilisation de toutes les mthodes proposes par la classe Exception $rect = new Rectangle(-1,4); try { echo $rect->surface(); } catch (Exception $e) { print("<hr/>". "<i>Message</i> : ".$e->getMessage()."<br/>". "<i>Code</i> : ".$e->getCode()."<br/>". "<i>File</i> : ".$e->getFile()."<br/>". "<i>Line</i> : ".$e->getLine()."<br/>". "<i>TraceAsString</i> : <br/><pre>" .$e->getTraceAsString()."</pre>". "<hr/>"); }

Figure 13.14 : Affichage des valeurs retournes par les diffrentes

mthodes

Cette classe peut tout fait tre tendue de faon surcharger ses mthodes et attributs ou les complter avec les vtres. En dnissant vos propres exceptions, vous vous donnez galement la possibilit den capturer plusieurs mises dans un mme bloc try.

408 LE GUIDE COMPLET

Rflexion

Chapitre 13

try { // code susceptible dmettre plusieurs exceptions } catch (MonException $monexception) { } catch (Exception $exception) { }

Constructeur et exceptions

Un constructeur ne pouvant retourner de valeur, les exceptions sont la seule solution pour avertir dune erreur.

13.7. Rexion
PHP vous donne dsormais la possibilit dobtenir des informations sur la structure interne dune classe. La classe mise en uvre porte le nom Reflection.
<?php class Rectangle { public $longueur = null; public $largeur = null; public $couleur = "rouge"; const NOM = "Super Rectangle"; function __construct($longueur,$largeur) { print("Hello ".self::NOM."<br/>"); $this->longueur = $longueur; $this->largeur = $largeur; } function perimetre() { if ($this->longueur!=null && $this->largeur!=null) { return (2*$this->longueur+2*$this->largeur); } } function surface() { if ($this->longueur!=null && $this->largeur!=null) { return ($this->longueur*$this->largeur); } } }

LE GUIDE COMPLET 409

Chapitre 13

La programmation objet

print("<pre>"); Reflection::export(new ReflectionClass(Rectangle));

Figure 13.15 : Affichage de la structure interne de la classe Rectangle

Cette fonctionnalit est particulirement intressante pour la cration automatique de documentation et pour obtenir des informations sur une classe des sources et de lAPI de laquelle vous ne disposez pas.

13.8. Version objet de la gnration de graphique


Le script de gnration de graphique tudi dans le chapitre prcdent souffre de nombreux inconvnients :
j

la rcupration des donnes nest pas clairement spare de laffichage graphique ;

410 LE GUIDE COMPLET

Version objet de la gnration de graphique


j j

Chapitre 13

les donnes lies la prsentation (couleurs, polices) ne sautent pas aux yeux ; le script nest pas rutilisable sans un changement important du code.

Utilisez le concept de classe pour remdier ces faiblesses. Voyez les attributs et les mthodes dont vous avez besoin.
j j

les attributs : toutes les couleurs, le nom de la fonte, le tableau contenant les moyennes, lidentiant de limage ; les mthodes : __construct(), le constructeur pour initialiser la taille de limage et les couleurs, enregistre_donnees() qui permet de transmettre les donnes, cree_image() qui contient tout le code, genere_image() qui gnre le contenu de limage.

Il suffit ensuite de placer le code dj crit dans les bonnes mthodes et de passer par les attributs pour accder aux variables :
Listing 13-34 : Le fichier class_graph.inc.php <?php class Graph { public public public public public public public public public public public $coul_fond; $coul_axes; $coul_lignes; $coul_legendes; $coul_barres; $coul_orange; $image; $font = "verdana.ttf"; $abs = "trimestre"; $ord = "moyenne"; $donnees;

public function __construct ($largeur, $hauteur, $font = "arial.ttf") { $this->image = Imagecreate ($largeur, $hauteur); if ($this->image===false) throw new Exception (); $this->coul_fond = ImageColorAllocate ($this->image, 208, 216, 213); $this->coul_axes = ImageColorAllocate ($this->image, 11, 62, 43); $this->coul_lignes = ImageColorAllocate ($this->image, 227, 235, 232); $this->coul_legendes = ImageColorAllocate ($this->image, 11, 62, 43);

LE GUIDE COMPLET 411

Chapitre 13

La programmation objet

$this->coul_barres = ImageColorAllocate ($this->image, 42, 124, 94); $this->coul_orange = ImageColorAllocate ($this->image, 207, 140, 53); $this->font = $font; } public function enregistre_donnees ($datas) { $this->donnees = $datas; } public function cree_image () { imageline ($this->image,30,30,30,190,$this->coul_axes); imageline ($this->image,30,190,320,190,$this->coul _axes); $tab_fleche_ord = array (30, 30, 26, 34, 34, 34); $tab_fleche_abs = array (320, 190, 316, 186, 316, 194); imagefilledpolygon ($this->image, $tab_fleche_ord, 3, $this->coul_axes); imagefilledpolygon ($this->image, $tab_fleche_abs, 3, $this->coul_axes); ImageTTFText ($this->image,10,0,5,20, $this->coul_legendes, $this->font,$this->ord); ImageTTFText ($this->image,10,0,280,180, $this->coul_legendes, $this->font,$this->abs); imageline imageline imageline imageline imageline ($this->image,26,190,30,190,$this->coul_axes); ($this->image,26,155,30,155,$this->coul_axes); ($this->image,26,120,30,120,$this->coul_axes); ($this->image,26,85,30,85,$this->coul_axes); ($this->image,26,50,30,50,$this->coul_axes);

ImageTTFText ($this->image,8,0,6,190, $this->coul_legendes, $this->font,"0"); ImageTTFText ($this->image,8,0,6,155, $this->coul_legendes, $this->font,"5"); ImageTTFText ($this->image,8,0,6,120, $this->coul_legendes, $this->font,"10"); ImageTTFText ($this->image,8,0,6,85, $this->coul_legendes, $this->font,"15"); ImageTTFText ($this->image,8,0,6,50, $this->coul_legendes, $this->font,"20"); imageline ($this->image,31,155,320,155, $this->coul_lignes); imageline ($this->image,31,120,320,120, $this->coul_lignes);
412 LE GUIDE COMPLET

Version objet de la gnration de graphique


imageline ($this->image,31,85,320,85, $this->coul_lignes); imageline ($this->image,31,50,320,50, $this->coul_lignes);

Chapitre 13

imagefilledrectangle ($this->image, 40, (20-$this->donnees[0])*7+50, 110, 189, $this->coul_barres); imagefilledrectangle ($this->image, 120, (20-$this->donnees[1])*7+50, 190, 189, $this->coul_barres); imagefilledrectangle ($this->image, 200, (20-$this->donnees[2])*7+50, 270, 189, $this->coul_barres); ImageTTFText ($this->image,10,0,50,180,$this->coul_orange, $this->font,$this->donnees[0]); ImageTTFText ($this->image,10,0,130,180,$this->coul_orange, $this->font,$this->donnees[1]); ImageTTFText ($this->image,10,0,210,180,$this->coul_orange, $this->font,$this->donnees[2]); } public function genere_image () { header ("Content-type: image/png"); ImagePng ($this->image); } } ?>

Deux remarques peuvent tre faites sur le code


j

observez la signature assez trange du constructeur : function __construct($largeur,$hauteur,$font = "arial.ttf"). Cela signie que lon peut crer un objet class de deux manires :
$mongraph = new Graph (340,220);

Dans ce cas, la variable font prend la valeur "arial.ttf".


$mongraph = new Graph (340,220,"verdana.ttf");

Dans ce cas, lattribut font est initialis "verdana.ttf". Pour obtenir ce rsultat, vous pouvez aussi crire :
$mongraph = new Graph (340,220); $mongraph->font = "verdana.ttf";

LE GUIDE COMPLET 413

Chapitre 13
j

La programmation objet

il nest pas ncessaire que les variables $largeur et $hauteur existent en tant quattributs car vous nen avez besoin que dans le constructeur.

Grce cette classe, le script graph.php se simplie normment :


Listing 13-35 : Le script graph.php include("variables.inc.php"); include("class_graph.inc.php"); $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_exam"; $resultat = mysql_query ($sql); $i = 0; while ($tmp = mysql_fetch_array ($resultat)) { $tab[$tmp[trimestre] - 1] += $tmp[moyenne]; $i++; } mysql_close($liendb); $nb_eleves = $i / 3; for ($i = 0; $i < 3; $i++) { $tab[$i] = number_format($tab[$i] / $nb_eleves,2); }

try { $mongraph = new Graph(340,220); $mongraph->enregistre_donnees($tab); $mongraph->cree_image(); $mongraph->genere_image(); } catch (Exception $e) { die (erreur); }

Le script class_graph.inc.php

Noubliez pas dinclure le chier class_graph.inc.php sous peine derreur !

Vous voyez que ce nouveau code prsente lavantage dtre beaucoup plus clair. Les parties acquisition des donnes et affichage de limage sont dsormais clairement spares et le code est parfaitement factoris.

414 LE GUIDE COMPLET

Version objet de la gnration de graphique

Chapitre 13

Crez maintenant un chier graph_eleve.php qui permettra dafficher lvolution des notes dun lve :
Listing 13-36 : Le fichier graph_eleve.php include("variables.inc.php"); include("class_graph.inc.php"); $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_exam ". "WHERE ideleve = ".$_REQUEST[id].""; $resultat = mysql_query ($sql); while ($tmp = mysql_fetch_array ($resultat)) { $tab[$tmp[trimestre] - 1] = $tmp[moyenne]; } mysql_close($liendb); try { $mongraph = new Graph (340,220,"verdana.ttf"); $mongraph->enregistre_donnees($tab); $mongraph->ord = "moyenne de llve"; $mongraph->cree_image(); $mongraph->genere_image(); } catch (Exception $e) { die (erreur); }

Dans ce script, vous utilisez la fonte verdana.ttf plutt que la fonte arial.ttf. De plus, vous changez lintitul de lordonne en "moyenne de llve". Cest possible car vous avez fait en sorte de placer de nombreuses donnes en attributs. Vous voyez galement lintrt de diviser la gnration dimages en plusieurs mthodes et de ne pas avoir lintgralit du code dans le constructeur.
Envoi des fontes

Noubliez pas denvoyer sur votre compte les fontes que vous utilisez dans vos scripts.

Incluez la balise suivante en bas du script eleve_edite.php :


<img src="graph_eleve.php?id=<?php echo $id; ?>" />

LE GUIDE COMPLET 415

Chapitre 13

La programmation objet

Vous obtenez le rsultat suivant :

Figure 13.16 : Une nouvelle version de la che lve

13.9. Check-list
j j j

La dimension objet de PHP a largement volu avec la version 5. Une classe peut tre considre comme une entit regroupant les donnes et les fonctions qui lui sont propres. Les classes, par leur nature, sont particulirement faciles inclure dans une application. Cest aujourdhui principalement sous cette forme que lon trouve le code PHP sur le Web. Les techniques permettant de mieux organiser votre code sont au nombre de trois : les include(), les fonctions et les classes.

416 LE GUIDE COMPLET

XML

Le format .............................................................................................................................. SimpleXML .......................................................................................................................... Formats spciaux .............................................................................................................. Check-list .............................................................................................................................

418 421 426 437

Chapitre 14

XML

Peu de formats de documents ont autant inuenc lindustrie informatique que le XML (Extensible Markup Language). Datant du milieu des annes 1990, ce format est aujourdhui la rfrence pour les changes de donnes notamment sur Internet. Les avantages de ce format sont nombreux :
j j j

Un document XML est lisible, structur et comprhensible. Le format respecte un standard et assure, par l mme, une vritable portabilit et prennit des donnes. Tous les langages de programmation proposent dsormais des bibliothques permettant un accs facile ce format.

14.1. Le format
la manire du HTML, qui comme lui est issu du SGML, le format XML sorganise avec des balises. Cependant, la diffrence de HTML, les balises ne sont pas prdnies et peuvent tre choisies en fonction des besoins de lapplication. Le document suivant par exemple reprsente une classe :
<classe> <eleve>Paul Dupont</eleve> <eleve>Eric Durant</eleve> </classe>

La hirarchie saute aux yeux : une classe est compose dlves. Il est galement possible de dire que llment <classe> dispose de plusieurs enfants : les lments <eleve>. Cette hirarchie peut tre affine si le besoin se fait ressentir. Les nom et prnom dun lve peuvent faire lobjet dlments spciques :
<classe> <eleve> <nom>Dupont</nom> <prenom>Paul</prenom> </eleve> <eleve> <nom>Durant</nom> <prenom>Eric</prenom> </eleve> </classe>

418 LE GUIDE COMPLET

Le format

Chapitre 14

Commentaires

Tout comme pour lHTML les commentaires sont entours des balises <! et >.

Tout comme les balises HTML, les balises XML peuvent galement disposer dattributs. Ces derniers sont, eux aussi, librement dnissables. Le niveau de la classe peut tre prcis de la manire suivante :
<classe niveau="cp"> <eleve> <nom>Dupont</nom> <prenom>Paul</prenom> </eleve> <eleve> <nom>Durant</nom> <prenom>Eric</prenom> </eleve> </classe>

Les documents XML prcdents sont pour linstant incorrects. La premire ligne dun document XML doit en effet prciser deux informations : j la version de la norme XML ; j lencodage des donnes. Cette ligne prend la forme suivante :
<?xml version="1.0" encoding="UTF-8"?>

Cette gestion de lencodage permet XML de contenir des donnes crites dans toutes les langues. Lencodage UTF-8 notamment pourrait tre assimil un alphabet universel des caractres de toutes les langues mondiales. Pour des langues europennes, lencodage ISO-8859-1 peut suffire. Cet encodage permet en effet un document XML de contenir des donnes accentues. Dautres contraintes doivent tre respectes pour obtenir un document valide : j Le document ne doit contenir quune racine (dans cet exemple, il sagit de <classe>). Un document XML dispose dune vritable structure darbre compose dlments (nuds) pouvant avoir des enfants. j Les balises orphelines doivent contenir une barre oblique (/) avant le chevron nal > (par exemple <voyages />).
LE GUIDE COMPLET 419

Chapitre 14
j j j

XML

Tous les attributs doivent tre entours de guillemets ou de primes (", ). La casse doit tre respecte entre une ouverture et une fermeture de balise. Certains caractres doivent tre convertis au sein du contenu dun lment (<, >, , ", & sont remplacs respectivement par <, >, , , &). La fonction PHP htmlspecialchars() permet de raliser cette conversion. Les balises douverture et de fermeture ne peuvent sentremler (exemple qui ne fonctionne pas : <eleve><nom>Dupont </eleve></nom>).

La fonction header() est une nouvelle fois ncessaire an dindiquer au navigateur que le document reu est de type XML et quil doit par consquent lafficher dans une vue adapte. Le script suivant permet dobtenir les lves dans le cadre dun document XML.
Listing 14-1 : Gnration dun document XML include("variables.inc.php"); $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_eleve"; $resultat = mysql_query ($sql); header(Content-Type: application/xml); $xml = <?xml version="1.0" encoding="ISO-8859-1"?>; $xml .= "\n<classe>\n"; while ($eleve = mysql_fetch_array ($resultat)) { foreach ($eleve as &$valeur) { $value = htmlspecialchars($value); } $xml .= " <eleve id=".$eleve[ideleve].">\n"; $xml .= " <nom>".$eleve[nom]."</nom>\n"; $xml .= " <prenom>".$eleve[prenom]."</prenom>\n"; $xml .= " <adresse>".$eleve[adresse]."</adresse>\n"; $xml .= " <ville>".$eleve[ville]."</ville>\n"; $xml .= " <cp>".$eleve[cp]."</cp>\n"; $xml .= " <pays>".$eleve[pays]."</pays>\n"; $xml .= " </eleve>\n"; } mysql_close($liendb); $xml .= "</classe>\n"; print($xml);

420 LE GUIDE COMPLET

SimpleXML

Chapitre 14

Figure 14.1 : Affichage des donnes en mode XML dans Firefox

CDATA

Il est possible de dnir un contenu dlment sans se proccuper des contraintes dcrites plus haut. La section dchappement spciale suivante <![CDATA[ ]]> permet dindiquer que tout ce qui est plac entre <![CDATA[ et ]]> ne doit pas tre interprt mais considr comme du texte brut. Lcriture suivante devient donc possible
<test><![CDATA[pas de problme de balise orpheline : <img>]]></test>

14.2. SimpleXML
Au lieu de manipuler directement les balises comme dans les exemples prcdents, PHP propose lextension SimpleXML pour construire un

LE GUIDE COMPLET 421

Chapitre 14

XML

document XML mais aussi et surtout le lire et accder directement nimporte quel nud du document. Autre avantage non ngligeable de SimpleXML, cette extension est incluse par dfaut dans PHP5.

Cration
La cration dun document XML avec SimpleXML est trs simple. Le point de dpart consiste crer llment racine ; un lment est reprsent par la classe SimpleXMLElement. Le constructeur de cette classe prend en argument une chane de caractres reprsentant une donne XML valide.
$racine = new SimpleXMLElement(<classe/>);

Ltape suivante consiste attacher des lments enfants cette racine laide de la mthode addChild() qui prend en premier argument le nom de llment et en second argument la valeur de llment.
$racine->addChild(eleve, Paul Dupont); $racine->addChild(eleve, Eric Durant);

La reprsentation textuelle peut ensuite tre obtenue en faisant appel la mthode asXML() de llment racine ($classe).
echo $racine->asXML();

Cette mthode retourne une chane de caractres et ne prend en aucun cas soin de modier le ContentType pour indiquer au navigateur que le contenu est de type XML. La fonction header() doit par consquent tre utilise.
Listing 14-2 : Cration dun document XML laide de lextension SimpleXML $racine = new SimpleXMLElement(<classe/>); $racine->addChild(eleve, Paul Dupont); $racine->addChild(eleve, Eric Durant); header(Content-Type: application/xml); echo $racine->asXML();

SimpleXML permet galement dajouter des attributs aux lments laide de la mthode addAttribute().

422 LE GUIDE COMPLET

SimpleXML

Chapitre 14

Figure 14.2 : La mthode asXML() retourne bien une chane de caractres correspondant la reprsentation XML

Listing 14-3 : Utilisation de la mthode addAttribute() $eleves = array(array(id => 1, nom => gueudet, prenom => edouard), array(id => 2, nom => henry, prenom => thomas)); $racine = new SimpleXMLElement(<classe/>); foreach ($eleves as $eleve) { $noeud = $racine->addChild(eleve); $noeud->addChild(nom, $eleve[nom]); $noeud->addChild(prenom, $eleve[prenom]); $noeud->addAttribute(id, $eleve[id]); } header(Content-Type: application/xml); echo $racine->asXML();

Figure 14.3 : Lattribut id a bien t ajout aux lments <eleve>

LE GUIDE COMPLET 423

Chapitre 14

XML

SimpleXML (comme les autres extensions PHP relatives XML) manipule en interne des chanes de caractres au format UTF-8. Il convient donc de vrier que les donnes transmises sont au bon format.
Listing 14-4 : Utilisation de caractres non ASCII $racine = new SimpleXMLElement(<tests/>); header(Content-Type: application/xml); $racine->addChild(test, hlne); echo $racine->asXML();

Figure 14.4 : La chane "hlne", non convertie, saffiche mal

Deux solutions permettent de rsoudre cette problmatique. La premire consiste utiliser la fonction utf8_encode() pour transmettre toutes les chanes dans le bon encodage.
$racine->addChild(test, utf8_encode(hlne));

La seconde repose sur lditeur utilis pour crire les sources du script. Si le format dencodage slectionn est bien UTF-8, la donne apparatra alors sans erreur.

Figure 14.5 : Notepad++ permet de forcer lencodage du script en UTF8

424 LE GUIDE COMPLET

SimpleXML

Chapitre 14

Figure 14.6 : Le prnom "hlne" apparat sans erreur quand lencodage UTF8 est utilis

Lecture
Lopration de lecture repose en grande partie sur la mthode children(). Cette dernire retourne lensemble des enfants dun lment donn. Fonctionnalit extrmement pratique, un lment (SimpleXMLElement) donne accs aux valeurs de ses enfants directement via ses attributs. Lexemple suivant montre comment un lment (coords) peut accder la valeur de ses deux enfants : x et y.
$coords = new SimpleXMLElement(<coords><x>2</x><y>3</y> </coords>); echo "x=".$coords->x." y=".$coords->y;

Laffichage des noms et prnoms des lves dune classe devient donc un jeu denfant.
Listing 14-5 : Parcours des lves de la classe $str = <classe> <eleve id="1"> <nom>gueudet</nom> <prenom>edouard</prenom> </eleve> <eleve id="2"> <nom>henry</nom> <prenom>thomas</prenom> </eleve> </classe>; $classe = new SimpleXMLElement($str); $eleves = $classe->children();

LE GUIDE COMPLET 425

Chapitre 14

XML

foreach ($eleves as $eleve) { echo $eleve->prenom." ".$eleve->nom."<br/>"; }

Figure 14.7 : Les 2 lves ont bien t trouvs

La mthode attributes() donne accs lensemble des attributs dun lment. Lexemple prcdent peut tre modi de la faon suivante pour afficher lid de llve.
foreach ($eleves as $eleve) { $attributs = $eleve->attributes(); echo "[".$attributs["id"]."] "; echo $eleve->prenom." ".$eleve->nom."<br/>"; }

Figure 14.8 : Affichage de lid

14.3. Formats spciaux


Le format XML permet dorganiser les donnes selon son bon vouloir tout en tant certain quun partenaire sera en mesure de le manipuler. Il conviendra cependant, en mme temps que la transmission des donnes, de fournir une documentation dcrivant comment sont agencs les attributs et les balises, quoi ils correspondent, etc. Pour viter cette fastidieuse tche de description, lindustrie sest trs vite organise pour faire merger des structures de documents XML prdnies (spcications).
426 LE GUIDE COMPLET

Formats spciaux

Chapitre 14

RSS
Le format RSS est un cas typique de standardisation dune structure XML pour rpondre un besoin partag par de nombreux intervenants du monde du web. Lide est ici de permettre un site de contenu de pouvoir fournir des partenaires un document contenant un rsum des derniers articles mis en ligne. Ces documents sont gnralement qualis de ux (feed) RSS.

Figure 14.9 : Icne utilise par les diffrents navigateurs pour indiquer la prsence dun ux RSS

En tablissant ce standard, lindustrie informatique a pu miser et investir dessus. Les navigateurs web peuvent directement les afficher, des appareils lectroniques tels que des iPods sont en mesure dimporter leur contenu, des sites web tels que Google Reader ne servent qu les agrger pour pouvoir les consulter en un point central.

LE GUIDE COMPLET 427

Chapitre 14

XML

Figure 14.10 : Google Reader, lecteur de ux RSS

Figure 14.11 : Affichage du ux RSS High Tech du Figaro

428 LE GUIDE COMPLET

Formats spciaux

Chapitre 14

Figure 14.12 : Laffichage des sources prouve bien quil sagit dun document XML de type RSS

Structure
Llment de plus haut niveau est la balise <rss> incluant en attribut la version du format. La version la plus rcente et la plus rpandue est la 2.0 : <rss version= "2.0">. Le seul enfant de llment <rss> est llment <channel>.
Tableau 14.1 : Enfants de llment channel

Elment

Usage Titre du ux Url permettant daccder ce ux Description Langue

Remarque Obligatoire Obligatoire Obligatoire

title link description language

LE GUIDE COMPLET 429

Chapitre 14

XML
Tableau 14.1 : Enfants de llment channel

Elment

Usage Image Copyright Adresse email de la personne responsable du ux Adresse email du webmaster Date de publication Date de dernire gnration

Remarque

Image copyright managingEditor

webMaster pubDate lastBuildDate rating category generator

Format RFC 822 Format RFC 822

Catgories Nom du logiciel qui a permis de construire le ux Dure de vie en minutes

ttl

Llment <channel> peut disposer galement de plusieurs lments enfants <item> qui correspondent vritablement aux histoires/articles associs au ux. Un <channel> contient donc plusieurs <item>. Une analogie possible consisterait comparer un <channel> un journal et les <item> des articles. Le journal dispose bien dun titre et dun rdacteur en chef, comme les articles ont un titre et un auteur. Chaque <item> dispose de plusieurs lments enfants.
Tableau 14.2 : Enfants de llment item

Elment

Usage Titre Lien direct vers larticle Description Auteur

Remarque Obligatoire Obligatoire Obligatoire Adresse email

title link description author

430 LE GUIDE COMPLET

Formats spciaux
Tableau 14.2 : Enfants de llment item

Chapitre 14

Elment

Usage Catgories Lien vers la page de commentaires Numro/Code unique de larticle Date de publication

Remarque

category comments guid pubDate

RFC 822

Le script suivant liste les enfants dune classe mais cette fois sous la forme dun ux RSS.
Listing 14-6 : Gnration dun flux RSS $classe = array(array(id => 1, nom => gueudet, prenom => edouard), array(id => 2, nom => henry, prenom => thomas)); $rss = new SimpleXMLElement(<rss/>); $rss->addAttribute(version, 2.0); $channel = $rss->addChild(channel); $channel->addChild(title, la classe); $channel->addChild(link, http://localhost/test.php); $channel->addChild(description, lves de la classe); $channel->addChild(generator, a la mano); $lien_edit = http://localhost/eleve_edite.php?id=; foreach ($classe as $eleve) { $item = $channel->addChild(item); $item->addChild(title, $eleve[prenom]. .$eleve[nom]); $item->addChild(link, $lien_edit.$eleve[id]); $item->addChild(guid, eleve-.$eleve[id]); $item->addChild(description, id=.$eleve[id]); } header(Content-Type: application/xml); echo $rss->asXML();

LE GUIDE COMPLET 431

Chapitre 14

XML

Figure 14.13 : Laffichage dun document XML est spcial dans le cadre

dun ux RSS

Figure 14.14 : Chaque navigateur a un mode daffichage des ux XML qui lui

est propre

432 LE GUIDE COMPLET

Formats spciaux

Chapitre 14

Inclusion dans un site


Tous les navigateurs sont aujourdhui en mesure dindiquer la prsence dun ux RSS sur un site web. Pour Firefox, il sagit dune petite icne orange situe droite de ladresse du site.

Figure 14.15 : Le site kernix.com dispose bien dun ux RSS associ

Le site indique la prsence dun ux en utilisant une balise <LINK> spcique dans len-tte (<HEADER>) de la page.
Listing 14-7 : Balise ajouter pour indiquer au navigateur que le site dispose dun flux RSS <link rel="alternate" type="application/rss+xml" title="RSS" href="/test.php" />

Lattribut href permet de prciser lemplacement du ux.


Flux multiples

Il est possible dassocier plusieurs ux une page en multipliant les balises <LINK> dans len-tte. En cliquant sur licne de ux, le navigateur propose alors de slectionner le ux souhait. Lattribut title est dans ce cas trs utile.

LE GUIDE COMPLET 433

Chapitre 14

XML

XHTML
LXHTML est une version de lHTML pour laquelle les contraintes de lXML sont respectes. En dveloppant des pages la norme XHTML, ces dernires deviennent directement manipulables comme tout autre document XML. Lexemple suivant permet de rcuprer tous les liens (<a href="">) de la page du W3C consacre lXHTML : www.w3.org/TR/xhtml1. Le constructeur de la classe SimpleXMLElement peut prendre en premier paramtre une URL correspondant un document XML. Pour cela, le troisime paramtre vaut true, et le second, null.
$liens = array(); function extraitLiens($noeud) { if (strtoupper($noeud->getName()) == A) { $attributs = $noeud->attributes(); $href = (string) $attributs[href]; if (strlen($href) > 1) { $GLOBALS[liens][] = $href; } } foreach ($noeud->children() as $enfant) { extraitLiens($enfant); } } $xml = new SimpleXMLElement("http://www.w3.org/TR/xhtml1/", null, true); extraitLiens($xml); print("<pre>"); print_r($liens); print("</pre>");

Le script repose sur une utilisation rcursive de la fonction extraitLiens(), qui, pour chaque nud reu en paramtre, teste si ce dernier correspond un lien ( == A) et sappelle de nouveau pour tous les ventuels enfants.

434 LE GUIDE COMPLET

Formats spciaux

Chapitre 14

Figure 14.16 : Liste des liens

SVG
SVG est une spcication XML permettant de construire des images au format vectoriel. Une telle image a lavantage de pouvoir tre dformable sans perte de qualit. Parmi les logiciels graphiques, Illustrator appartient au monde du vectoriel et Photoshop celui des images bitmap. Lexemple suivant permet de construire pas pas un chiquier de 64 pices.
Listing 14-8 : Construction dun chiquier $nb_pieces = 8; $taille_piece = 30; $couleurs = array(#FFFFFF, #000000); $svg = new SimpleXMLElement(<svg/>); $svg->addAttribute(width, $nb_pieces * $taille_piece); $svg->addAttribute(heigth, $nb_pieces * $taille_piece); $svg->addAttribute(xmlns, http://www.w3.org/2000/svg); for ($i = 0; $i < $nb_pieces; $i++) { for ($j = 0; $j < $nb_pieces; $j++) { $carre = $svg->addChild(rect); $carre->addAttribute(x, $j*$taille_piece); $carre->addAttribute(y, $i*$taille_piece); $carre->addAttribute(width, $taille_piece); $carre->addAttribute(height, $taille_piece); $carre->addAttribute(style, fill:.$couleurs[($i+$j)%2]); }

LE GUIDE COMPLET 435

Chapitre 14
}

XML

header(Content-Type: application/xml); echo $svg->asXML();

Figure 14.17 : Affichage de lchiquier dans un navigateur

Figure 14.18 : Les sources de la page rvlent bien quun document XML se cache derrire limage

436 LE GUIDE COMPLET

Check-list

Chapitre 14

Cration dimages au format SVG

Le logiciel Inkscape est un concurrent open source dIllustrator. Il peut tre tlcharg gratuitement sur le site www.inkscape.org. Les crations ralises peuvent tre sauvegardes au format SVG et analyses avec un simple diteur de texte pour comprendre la structure.

Figure 14.19 : Inkscape permet de crer des images au format SVG

14.4. Check-list
j j j

Le format XML permet de stocker des informations et se rvle tre le meilleur choix pour les changes de donnes structures. Lutilisation dune extension de type SimpleXML est prfrable une construction " la main" dun chier XML. Les nouveaux formats informatiques prennent de plus en plus souvent la forme de spcications XML (RSS, SVG, ODF, GDATA, SOAP).

LE GUIDE COMPLET 437

Les cookies et les sessions


Les cookies ......................................................................................................................... 440 Les sessions ........................................................................................................................ 472 Check-list ............................................................................................................................. 482

Chapitre 15

Les cookies et les sessions

Nous nous intresserons dans ce chapitre aux diffrentes mthodes qui sont offertes pour associer des donnes un internaute : les cookies et les sessions. Pour illustrer ces diffrentes techniques, vous mettrez en place une mini-boutique.

15.1. Les cookies


En surfant sur le Web, vous avez pu vous apercevoir que certains sites taient en mesure de vous reconnatre. En revenant sur une boutique o vous avez dj achet, il nest pas rare dy trouver des messages du genre : Bienvenue M. Dupont ; Vous avez achet le produit X, nous vous proposons cette liste de produits qui peuvent vous intresser ; Voici les derniers produits apparus dans notre boutique depuis votre dernire visite , etc. En vous connectant depuis une autre machine ou un autre compte, vous vous apercevrez cependant que tous ces messages sont absents. Ces sites utilisent une technique qui leur permet de stocker des informations dans votre ordinateur, informations qui leur sont retransmises ds que vous naviguez sur leur site. Les donnes sont stockes dans de petits chiers appels cookies. Ces cookies ne servent pas que les intrts marketing des grandes boutiques du Web, ils vous permettent aussi :
j j

de ne pas avoir retaper systmatiquement votre identiant et votre mot de passe sur certains sites ; de pouvoir disposer dun systme de panier trs pratique dans les boutiques en ligne.

Ces cookies contiennent tout type dinformation et sont utiliss dans de trs nombreux cas de gure. Souvent diaboliss, ils vous rendent nalement davantage service quils ne vous desservent. Leur prsence est dailleurs dautant moins gnante quils peuvent tre effacs tout moment. Sous Firefox, il suffit daller dans le menu Outils/Vie prive > Afficher les cookies puis dappuyer sur le bouton Supprimer tous les cookies pour les faire disparatre.

440 LE GUIDE COMPLET

Les cookies

Chapitre 15

Figure 15.1 : Suppression des cookies

La perte de lespace disque est aussi un reproche, trs souvent exagr, que lon fait aux cookies. Un cookie fait en moyenne, entre 50 et 150 octets. Il vous faudrait stocker 10 millions de cookies pour perdre 1 Go despace disque !
Ce nest pas gnant, mais quand mme

En identiant de manire unique les internautes, certains services tels que doubleclik.com (gestion de bannires publicitaires) ont constitu une base de donnes mondiale an dtudier leur comportement. Ils savent o vous tes all, quand et pendant combien de temps Big Brother nest alors plus trs loin !

Aspects techniques
Plusieurs fois dans ce livre, nous nous sommes intresss len-tte HTTP des pages web, notamment lors de lutilisation de la fonction header(). Les cookies sont en ralit des donnes stockes en texte, qui sont transmises dans len-tte HTTP des requtes et des rponses :
Listing 15-1 : Exemple de directive HTTP permettant de crer le cookie moncookie Set-Cookie: moncookie=hello; path=/; expires Mon, 09-Dec-2002 13:46:00 GMT

LE GUIDE COMPLET 441

Chapitre 15

Les cookies et les sessions

Listing 15-2 : Directive HTTP contenue dans la requte envoye par un navigateur Cookie: moncookie=hello

La gestion des cookies en PHP est trs simple. Elle ne ncessite que lutilisation de la fonction setcookie(). Cette fonction prend par dfaut deux paramtres : le nom du cookie et sa valeur. crivez deux scripts, lun pour crer le cookie et lautre pour lire sa valeur :
Listing 15-3 : Le script cree_cookie.php <?php setcookie("moncookie","hello"); echo "cookie cr"; ?> Listing 15-4 : Le script lit_cookie.php <?php echo "valeur contenue dans mon cookie : ".$_COOKIE[moncookie]; ?>

Figure 15.2 : Lecture dun cookie

Comme les paramtres avec $_REQUEST[], les cookies peuvent tre rcuprs au sein dune variable super-globale : $_COOKIE. Ce tableau associatif contient autant de cellules que vous avez cr de cookies. Une fois le cookie moncookie cr, la variable $_COOKIE[moncookie] devient accessible dans vos scripts.
Suppression

Pour supprimer un cookie en PHP, il suffit de supprimer le contenu du cookie. Si vous souhaitez supprimer le cookie moncookie, crivez setcookie("moncookie").

442 LE GUIDE COMPLET

Les cookies

Chapitre 15

Comme les cookies sont transmis dans len-tte HTTP, leur utilisation impose les mmes contraintes que pour la fonction header() : interdiction absolue dafficher quoi que ce soit avant dutiliser setcookie().
Limitations

Tout nest tout de mme pas permis avec les cookies. Voici une liste non exhaustive des limitations : j Seul le site qui a cr le cookie peut y accder. j La taille dun cookie doit tre infrieure 4 ko. j Le nombre de cookies crs par un domaine donn est limit 20.

La fonction setcookie()peut prendre dautres paramtres


j j j j

La date dexpiration : en secondes, la fonction PHP time() renvoyant la date actuelle en secondes. Le chemin : indique quelle partie du site peut avoir accs au cookie. Le domaine : indique quel domaine peut avoir accs au site. Un indicateur de scurit : si sa valeur est 1, il indique que la valeur du cookie ne peut tre transmise que si vous tes en HTTS (HTTP scuris par du SSL).

Voyez ces quelques exemples Premier exemple : modiez le chier cree_cookie.php.


<?php setcookie("moncookie","hello",time()+5); echo "cookie cr"; ?>

Si vous appuyez, au bout de 5 secondes, sur le bouton Rafrachir (reload) de la page http://localhost/lit_cookie.php, le cookie disparatra.
Heure du serveur

Il est courant que lheure du serveur web soit dcale par rapport lheure de votre machine. Cela peut fausser vos tests. Pour voir la date et lheure du serveur web, utilisez la fonction date ("Ymd G:i:s").

LE GUIDE COMPLET 443

Chapitre 15

Les cookies et les sessions

Deuxime exemple :
setcookie("moncookie","hello",time()+3600,"/",".kernix .com",1);

Le cookie est, cette fois, cr pour une heure. Tous les scripts situs sur le domaine .kernix.com peuvent y accder, la condition que les transmissions soient cryptes. Troisime exemple :
setcookie("moncookie","hello");

En ne prcisant pas de date dexpiration, vous crez cette fois un cookie de session. Le cookie existera tant que le navigateur restera ouvert. Ds sa fermeture, le cookie sera automatiquement effac. Pour tester ce comportement, enchanez les tapes suivantes :

1 Appelez le script http://localhost/cree_cookie.php (en ayant modi son contenu au pralable !). 2 Appelez le script http://localhost/lit_cookie.php. 3 Fermez le navigateur. 4 Appelez de nouveau le script http://localhost/lit_cookie.php. Le cookie a disparu.
Pour changer la valeur du cookie moncookie, il suffit dappeler la fonction setcookie() en modiant la valeur du cookie.

Application : la mini-boutique FoxShop


Pour appliquer les concepts que vous venez de voir, vous allez dvelopper une boutique extrmement simplie. Les cookies seront utiliss plusieurs endroits :
j j

pour la gestion du panier ; pour enregistrer le prol du client et lui pargner une nouvelle saisie chaque achat.

Pour ne pas mlanger les scripts de cette boutique avec votre applicatif de gestion dcole, vous allez crer le rpertoire boutique sur votre compte distant et y placer tous vos dveloppements. Pour accder la page daccueil de la boutique, lURL sera donc http://localhost/boutique. Au niveau de la base de donnes, vous avez besoin de deux tables. j produit : idproduit, rfrence produit, nom, prix, description. j commande : idcommande, liste des produits, montant global, nom client, prnom client, adresse client, date.
444 LE GUIDE COMPLET

Les cookies

Chapitre 15

Votre applicatif sera compos de deux parties : front-office et back-office. Le front-office, qui permet un internaute dacheter en ligne, contient les chiers suivants : j index.php (page daccueil de la boutique) ; j boutique.php (affichage du catalogue) ; j ajout_caddie.php (ajout dun produit au panier) ; j voir_caddie.php (rsum de la commande, identication de paiement) ; j enregistre_commande.php (enregistrement de la commande). Le back-office, qui permet de grer les produits et les commandes, contient les chiers suivants : j adm_produits.php (script permettant lajout de produits) ; j adm_commandes.php (script listant les commandes) ; j identification.inc.php ; j variables.inc.php ; j haut.inc.php ; j bas.inc.php.
Entranez-vous

Ce pourrait tre le bon moment de fermer le livre et dessayer de raliser ce petit applicatif. Si vous cherchez de votre ct, les progrs viendront en effet bien plus vite.

Le back-office
Les tables dont vous avez besoin peuvent tre dnies de la manire suivante : Table produit :
Listing 15-5 : Table produit CREATE TABLE produit ( idproduit int(10) unsigned NOT NULL auto_increment, reference varchar(16) NOT NULL default , nom varchar(16) NOT NULL default , description tinytext NOT NULL, prix float(12,2) unsigned NOT NULL default 0.00, PRIMARY KEY (idproduit) )
LE GUIDE COMPLET 445

Chapitre 15

Les cookies et les sessions

Table commande :
Listing 15-6 : Table commande CREATE TABLE commande ( idcommande int(10) unsigned NOT NULL auto_increment, produits varchar(64) NOT NULL default , montant float(12,2) unsigned NOT NULL default 0.00, nom varchar(16) NOT NULL default , prenom varchar(16) NOT NULL default , adresse tinytext NOT NULL, date datetime NOT NULL default 0000-00-00 00:00:00, PRIMARY KEY (idcommande) ) Listing 15-7 : Le script adm_produits.php <?php include("variables.inc.php"); include("identification.inc.php"); if ($_REQUEST[enregistre] == "oui") { if (empty($_REQUEST[reference]) || empty($_REQUEST[nom]) || empty($_REQUEST[prix]) || empty($_REQUEST[description])) die("ERREUR : tous les champs doivent tre remplis."); if (preg_match("/^\d+(\.\d+)?$/",$_REQUEST[prix]) == false) die("ERREUR : prix non valide."); $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "INSERT INTO $table_produit (reference, nom, prix, description)". " VALUES (". "".$_REQUEST[reference].",". "".$_REQUEST[nom].",". "".$_REQUEST[prix].",". "".$_REQUEST[description].")"; mysql_query ($sql); mysql_close($liendb); } include("haut.inc.php"); ?>

446 LE GUIDE COMPLET

Les cookies

Chapitre 15

<p>:: ajouter un produit au catalogue de la boutique</p> <form action="<?php echo $_SERVER[PHP_SELF]; ?>" method="post"> <input type="hidden" name="enregistre" value="oui" /> <table> <tr> <td>rfrence</td> <td><input type="text" name="reference" /></td> <td rowspan="3" valign="top">description</td> <td rowspan="3"><textarea name="description" rows="8"></textarea></td> </tr> <tr> <td>nom</td> <td><input type="text" name="nom" /></td> </tr> <tr> <td>prix</td> <td><input type="text" name="prix" /></td> </tr> </table> <br/> <input type="submit" value="enregistrer le produit" /> </form> <hr> <p>:: les produits de la boutique</p> <table width="98%" align="center" border="1"> <tr> <td class="intitule">id</td> <td class="intitule">rfrence</td> <td class="intitule">nom</td> <td class="intitule">prix </td> </tr> <?php $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_produit"; $resultat = mysql_query ($sql); if (mysql_num_rows($resultat) > 0) {
LE GUIDE COMPLET 447

Chapitre 15

Les cookies et les sessions

while ($produit = mysql_fetch_array ($resultat)) { $id = $produit[idproduit]; $reference = $produit[reference]; $nom = $produit[nom]; $prix = $produit[prix]; echo "<tr>"; echo " <td>$id</td>"; echo " <td>$reference</td>"; echo " <td>$nom</td>"; echo " <td>$prix</td>"; echo "</tr>"; } } else { echo "<tr><td colspan=4 align=center>aucun produit</td></tr>"; } echo "</table>"; mysql_close($liendb); include("bas.inc.php"); ?>

Figure 15.3 : Page dadministration de la boutique

448 LE GUIDE COMPLET

Les cookies
Listing 15-8 : Le script adm_commandes.php <?php include("variables.inc.php"); include("identification.inc.php"); include("haut.inc.php"); ?> <p>:: les commandes</p> <table> <tr> <td class="intitule">id</td> <td class="intitule">contenu</td> <td class="intitule">client</td> <td class="intitule">montant </td> <td class="intitule">date</td> </tr> <?php $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_commande"; $resultat = mysql_query ($sql); if (mysql_num_rows($resultat) > 0) {

Chapitre 15

while ($produit = mysql_fetch_array ($resultat)) { $id = $produit[idcommande]; $produits = str_replace(",","<br/>",$produit[produits]); $client = $produit[prenom]." ".$produit[nom]."<br/>".nl2br($produit[adresse]); $montant = $produit[montant]; $date = $produit[date]; echo "<tr>"; echo "<td>$id</td>"; echo "<td>$produits</td>"; echo "<td>$client</td>"; echo "<td>$montant</td>"; echo "<td>$date</td>"; echo "</tr>"; } } else echo "<tr><td colspan=5>aucune commande</td></tr>";

LE GUIDE COMPLET 449

Chapitre 15

Les cookies et les sessions

echo "</table>"; mysql_close($liendb); include("bas.inc.php"); ?> Listing 15-9 : Le script haut.inc.php <html> <head> <title>Admin Boutique</title> <style type="text/css"> <!-* { font-family:verdana; font-size:10px;} BODY { background:#D1DAE3; color:#01291A; } TABLE {width:100%; } H1 { background: #091F35; color: white; font-size:22px; font-weight: bold; } P { background:#8F9BB7; color:#091F35; font-size:13px; font-weight:bold; text-align:left; } TD { background:white; color:#091F35; font-family:arial; font-size:16px; font-weight:normal; vertical-align:top; } TD.intitule { background:#091F35; color:white; font-size:14px; font-weight:bold; text-align:center; } INPUT { background:#FCF0E9; color:#01291A; width:100%; } TEXTAREA { background:#FCF0E9; color:#01291A; width:100%; }

450 LE GUIDE COMPLET

Les cookies

Chapitre 15

SELECT { background:#FCF0E9; color:#01291A; } HR { color: #091F35; } A { color: #6C111E; } A:hover { background:#6C111E; color:white; font-weight:bold;} --> </style> </head> <body> <center> <h1>Admin - Boutique</h1> <hr/> Listing 15-10 : Le script bas.inc.php <br/><br/><hr/> <a href="adm_commandes.php">gestion des commandes</a> <a href="adm_produits.php">gestion des produits</a> <hr/> libre </center> </body> </html> Listing 15-11 : Le script identification.inc.php <?php if ($_SERVER[PHP_AUTH_USER]!= "essai" || $_SERVER[PHP_AUTH_PW]!="essai") { header("status: 401 Unauthorized"); header("HTTP/1.0 401 Unauthorized"); header("WWW-authenticate: basic realm=\"acces securise\"");

LE GUIDE COMPLET 451

Chapitre 15

Les cookies et les sessions

print("Echec"); exit(0); } ?> Listing 15-12 : variables.inc.php <?php $bddserver $bddlogin $bddpassword $bdd $table_commande $table_produit $url ?> = = = = = = = "localhost"; "root"; ""; "test"; "commande"; "produit"; "http://localhost/boutique";

Vous constatez la prsence, dans le script adm_produits.php, de la ligne suivante :


<form action="<?php echo $PHP_SELF; ?>" method="post">

La variable $_SERVER[PHP_SELF] est une variable interne de PHP, qui contient tout moment lURL du script appel.
Variables prdnies

PHP dispose, par dfaut, dun certain nombre de variables prdnies. Celles-ci contiennent des informations sur le serveur web, la page appele, linternaute, etc.

Une liste exhaustive de ces variables est fournie dans les annexes.

Figure 15.4 : Contenu de la variable PHP_SELF

452 LE GUIDE COMPLET

Les cookies

Chapitre 15

Il peut tre trs intressant de passer par cette variable quand vous souhaitez faire rfrence au script dans lequel vous vous trouvez. De cette manire, vous limitez le nombre de mises jour si vous devez renommer le script.
$_SERVER[PHP_SELF] et include()

Si un chier f1.php (http://localhost/f1.php) inclut un chier f2.php, la variable $_SERVER[PHP_SELF] contiendra /f1.php dans f1.php ET dans f2.php. $_SERVER[PHP_SELF] contient lURL appele, et non le chemin du chier dans lequel on se trouve !

Dans le script adm_commandes.php, vous remarquez lutilisation des fonctions nl2br() et str_replace().
j

nl2br() : lorsque vous enregistrez dans une table, une donne multiligne provenant dun textarea, cette donne est stocke avec des retours la ligne (cods \n). Pour lafficher dans une page web, il est donc ncessaire dutiliser la fonction nl2br() pour convertir les retours la ligne texte (\n) en retours la ligne HTML (<br/>). str_replace() : permet de remplacer un texte par un autre

dans une chane de caractres. Si vous souhaitez remplacer la chane "toto" par la chane "titi" dans la chane $ch et stocker le rsultat dans la chane $ch2, il suffit dcrire $ch2 = str_replace("toto","titi",$ch);. Une description plus approfondie de cette fonction est fournie dans le chapitre Fonctions PHP . Vous y dcouvrirez notamment les possibilits impressionnantes quelle offre lorsquelle est utilise en adquation avec les expressions rgulires.

Le front-office
Le front office correspond dans cet exemple la zone du site qui permettra linternaute de slectionner ses achats et de passer sa commande. Commencez par raliser la page daccueil et la page catalogue :

LE GUIDE COMPLET 453

Chapitre 15

Les cookies et les sessions

Listing 15-13 : Le fichier index.html <html> <head> <title>Boutique FoxShop</title> <link href="look.css" rel="stylesheet" type="text/css" /> </head> <body> <div class=titre><a href=boutique.php>Boutique <i>FoxSHOP</i></a></div> <div class=bienvenue>Welcome</div> </body> </html>

Figure 15.5 : Page daccueil de la boutique

A priori, rien signaler, si ce nest la gestion des styles (CSS). Comme la page daccueil est de type HTML, vous ne pouvez recourir la

454 LE GUIDE COMPLET

Les cookies

Chapitre 15

technique dinclusion et utiliser un chier haut.inc.php pour inclure les caractristiques visuelles de la boutique. Heureusement, une autre technique permet disoler les CSS en un endroit unique. Les proprits CSS peuvent tre incluses dans un chier extrieur qui sera li la page web de la manire suivante :
<link href="look.css" rel="stylesheet" type="text/css" />

Dans ce cas, ce chier sappelle look.css, il se situe au mme niveau que le script index.php et contient les instructions suivantes :
BODY {background: #025053;} TD {background: #C2DADB; color: #022324; font-family: georgia; font-weight: bold; font-size: 14px; letter-spacing: 1px;} A {color: #EB8814; font-family: georgia; font-weight: bold; font-size: 14px; letter-spacing: 1px;} .titre {color: #047F84; font-family: georgia; font-weight: bold; font-size: 24px; letter-spacing: 1px;} .reference {color: #047F84; font-family: arial; font-weight: bold; font-size: 12px; letter-spacing: 1px;} .description {background: #DAE9EA; color: #047F84; font-family: verdana; font-weight: normal; font-size: 12px; letter-spacing: 1px;}

Passez maintenant au script boutique.php, qui permet daccder lensemble du catalogue :


Listing 15-14 : boutique.php <?php include("variables.inc.php"); if (!isset($_REQUEST[id])) $id = 1; else $id = $_REQUEST[id]; ?> <html>

LE GUIDE COMPLET 455

Chapitre 15

Les cookies et les sessions

<head> <title>Boutique FoxShop - catalogue</title> <link href="look.css" rel="stylesheet" type="text/css" /> </head> <body> <div class=titre><a href=boutique.php>Boutique <i>FoxSHOP</i></a></div> <table class=catalogue> <tr> <td class=liste> <div class=tdTitre>Nos produits</div> <?php $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_produit"; $resultat = mysql_query ($sql); while ($produit = mysql_fetch_array ($resultat)) { print(" - "); print("<a href=".$_SERVER[PHP_SELF]."?id=".$produit [idproduit].">". $produit[nom]."</a>"); print("<br/>"); } ?> </td> <td class=detail> <?php $sql = "SELECT * FROM $table_produit WHERE idproduit = $id"; $resultat = mysql_query ($sql); $produit = mysql_fetch_array ($resultat); print("<div class=tdTitre>".$produit[nom]. " [ref#".$produit[reference]."]</div>"); ?> <div class=description> <?php print(nl2br($produit[description])."<br/><br/>"); print($produit[prix]." <br/><br/>"); mysql_close($liendb); ?> <form action="ajout_caddie.php" method="post"> <input type="hidden" name="id" value="<?php echo $id; ?>" />
456 LE GUIDE COMPLET

Les cookies

Chapitre 15

<input type="submit" value="ajouter au panier" /> </form> </div> </td> </tr> </table> </body> </html>

Figure 15.6 : Catalogue de la boutique

Quand aucun produit nest spci, vous prenez la valeur par dfaut 1 :
if (!isset($_REQUEST[id])) $id = 1; else $id = $_REQUEST[id];

Cest par exemple le cas quand vous venez de la page daccueil. En revanche, lorsque vous cliquez sur le nom dun produit, vous passez le paramtre id au script et lui permettez ainsi daller chercher les caractristiques du produit associ. Vous pouvez donc dire que le catalogue de la boutique est entirement dynamique. Le bouton "ajouter au panier" va permettre de passer la commande en basculant sur ajout_caddie.php.
LE GUIDE COMPLET 457

Chapitre 15

Les cookies et les sessions

Venons-en justement au cur du problme : la gestion du panier. Lide est de construire un cookie monpanier qui contiendra les id de tous les produits qui y ont t ajouts. Pour faire simple, vous choisirez le format de stockage idprod1,idprod2,idprod3, etc. Le chier ajout_caddie.php se contente donc de concatner la chane ,idprodN la n du cookie existant (sil nexiste pas, il sinitialise). Une fois la manipulation sur le cookie ralise, vous tes redirig sur la che du produit que vous venez dacheter. Le code du script ajout_caddie.php devient maintenant vident :
Listing 15-15 : Le script ajout_caddie.php <?php include("variables.inc.php"); setcookie("monpanier",$_COOKIE[monpanier].",".$_REQUEST [id],time()+86400); header("Location: $url/boutique.php?id=".$_REQUEST[id]); ?>

Vous disposez donc dun panier et il devient ncessaire dy faire rfrence dans la boutique. Apportez quelques modications boutique.php de manire que les lments suivants soient affichs (lorsque le panier existe) :
j j j

le message "Votre panier contient N articles" ; un bouton pour valider la commande ; le contenu du panier pour rendre compte, de visu, du contenu du cookie.
Listing 15-16 : Vous disposez maintenant dun panier dans la boutique
<?php include("variables.inc.php"); if (!isset($_REQUEST[id])) $id = 1; else $id = $_REQUEST[id]; ?> <html> <head> <title>Boutique FoxShop - catalogue</title> <link href="look.css" rel="stylesheet" type="text/ css" />

458 LE GUIDE COMPLET

Les cookies
</head> <body>

Chapitre 15

<div class=titre><a href=boutique.php>Boutique <i>FoxSHOP</i></a></div> <table class=catalogue> <tr> <td class=liste> <div class=tdTitre>Nos produits</div> <?php $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_produit"; $resultat = mysql_query ($sql); while ($produit = mysql_fetch_array ($resultat)) { print(" - "); print("<a href=".$_SERVER[PHP_SELF]."?id=" .$produit[idproduit].">". $produit[nom]."</a>"); print("<br/>"); } ?> </td> <td class=detail> <?php $sql = "SELECT * FROM $table_produit WHERE idproduit = $id"; $resultat = mysql_query ($sql); $produit = mysql_fetch_array ($resultat); print("<div class=tdTitre>".$produit[nom]. " [ref#".$produit[reference]."]</div>"); ?> <div class=description> <?php print(nl2br($produit[description])."<br/><br/>"); print($produit[prix]." <br/><br/>"); mysql_close($liendb); ?> <form action="ajout_caddie.php" method="post"> <input type="hidden" name="id" value="<?php echo $id; ?>" /> <input type="submit" value="ajouter au panier" /> </form>

LE GUIDE COMPLET 459

Chapitre 15
<?php

Les cookies et les sessions

if (isset($_COOKIE[monpanier])) { print("<div class=panier>"); $tab = split(",",$_COOKIE[monpanier]); $nb_prod = sizeof($tab) - 1; print("votre panier contient ".$nb_prod." produit(s)<br/>"); print("<form action=voir_caddie.php method=post>"); print("<input type=submit value=valider la commande/></form>"); print("cookie = {".$_COOKIE[monpanier]."}"); print("</div>"); } ?> </div> </td> </tr> </table> </body> </html>

Figure 15.7 : Vous avez achet un sweater (id=2) et une casquette

(id=3)
460 LE GUIDE COMPLET

Les cookies

Chapitre 15

Vous utilisez pour trouver le nombre dlments dans le panier la fonction split(). Utilise sur la chane ",2,3", la fonction split(",",",2,3") retourne un tableau de trois lments avec un premier lment vide. De ce fait, vous tes oblig de dcrmenter de 1 la taille du tableau pour trouver le nombre exact de produits :
$nb_prod = sizeof($tab) - 1;

Passez maintenant la validation de la commande. Vous avez deux scripts crire :


j j

Le script voir_caddie.php liste les produits prsents dans le panier et vous permet denregistrer vos informations client. Le script enregistre_commande.php, appel par voir_caddie.php, enregistre la commande dans la base et supprime le caddie.
Listing 15-17 : Le script voir_caddie.php (voir Figure 12.8)
<?php include("variables.inc.php"); ?> <html> <head> <title>Boutique FoxShop - validation commande</title> <link href="look.css" rel="stylesheet" type="text/ css" /> </head> <body> <div class=titre><a href=boutique.php>Boutique <i>FoxSHOP</i></a></div> <div class=caddie> <?php $montant = 0; $listeproduits = " "; $_COOKIE[monpanier][0] = ; $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_produit ". "WHERE idproduit IN (".$_COOKIE[monpanier].")"; $resultat = mysql_query ($sql); print("<table width=100%>"); while ($prod = mysql_fetch_array ($resultat)) { print("<tr>");
LE GUIDE COMPLET 461

Chapitre 15

Les cookies et les sessions

print("<td class=prod>[".$prod[reference]."] ".$prod[nom]."</td>"); print("<td class=montant>".$prod[prix]." </td></tr>"); $montant += $prod[prix]; $listeproduits .= , . $prod[reference]; } $listeproduits[0] = ; // frais de port $montant += 5; print("<tr><td class=total>MONTANT + PORT</td>"); print("<td class=total>$montant </td></tr>"); print("</table>"); mysql_close($liendb); ?> <form action="enregistre_commande.php" method="post"> <input type="hidden" name="montant" value="<?php echo $montant; ?>"> <input type="hidden" name="listeproduits" value="<?php echo $listeproduits; ?>"> <label>nom</label><br/><input type="text" name="nom" /><br/> <label>prnom</label><br/><input type="text" name="prenom" /><br/> <label>adresse</label><br/><input type="text" name="adresse" /><br/> <label>code postal</label><br/><input type="text" name="cp" /><br/> <label>ville</label><br/><input type="text" name="ville" /><br/> <input type="submit" value="enregistrer ma commande" /> </form> </div> </body> </html>

(voir Figure 12.8) tre gn

Pour

$_COOKIE[monpanier]
$monpanier[0] = ;

par les virgules initiales dans et $listeproduits, remplacez la premire lettre par un caractre blanc :

ne

pas

462 LE GUIDE COMPLET

Les cookies

Chapitre 15

Figure 15.8 : Visualisation du caddie

Vous avez vu, en effet, quune chane de caractres pouvait tre considre comme un tableau de caractres. Il est donc possible de modier un un les caractres en y accdant par un index. Supposons maintenant que vous ayez, dans votre panier, les produits 2 et 3. Pour les slectionner dans la base, la solution la plus vidente est la requte SQL suivante :
SELECT * FROM $table_produit WHERE idproduit = 2 OR idproduit = 3

Dans le cas prsent, vous allez tirer parti dune autre syntaxe, plus compacte, qui permet daboutir au mme rsultat. La ligne suivante :
SELECT * FROM $table_produit WHERE idproduit IN (2,3)

est quivalente la requte prcdente et signie : slectionner tous les produits dont lidproduit est contenu sur la liste suivante (2,3) . Ce procd comporte cependant un srieux dfaut : si vous ajoutez plusieurs fois le mme produit au panier, celui-ci napparat quune
LE GUIDE COMPLET 463

Chapitre 15

Les cookies et les sessions

seule fois dans votre rcapitulatif. Il faut donc prciser pour chaque produit sa quantit dans le panier. La fonction array_count _values(), qui dnombre le nombre doccurrences dune donne dans un tableau, peut vous tre utile.
Listing 15-18 : Le script voir_caddie.php <?php include("variables.inc.php"); ?> <html> <head> <title>Boutique FoxShop - validation commande</title> <link href="look.css" rel="stylesheet" type="text/css" /> </head> <body> <div class=titre><a href=boutique.php>Boutique <i>FoxSHOP</i></a></div> <div class=caddie> <?php $montant = 0; $listeproduits = " "; $_COOKIE[monpanier][0] = ; $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_produit ". "WHERE idproduit IN (".$_COOKIE[monpanier].")"; $resultat = mysql_query ($sql); print("<table width=100%>"); $tab = array_count_values(split(",",$_COOKIE[monpanier])); while ($prod = mysql_fetch_array ($resultat)) { print("<tr><td class=prod>"); print("[".$prod[reference]."] ".$prod[nom]); print(" (x".$tab[$prod[idproduit]].")"); print("</td><td class=montant>"); print($prod[prix]." "); print("</td></tr>"); $montant += $prod[prix]*$tab[$prod[idproduit]]; $listeproduits .= , . $prod[reference]; } $listeproduits[0] = ; // frais de port $montant += 5; print("<tr><td class=total>MONTANT + PORT</td>"); print("<td class=total>$montant </td></tr>"); print("</table>");
464 LE GUIDE COMPLET

Les cookies
mysql_close($liendb); ?>

Chapitre 15

<form action="enregistre_commande.php" method="post"> <input type="hidden" name="montant" value="<?php echo $montant; ?>"> <input type="hidden" name="listeproduits" value="<?php echo $listeproduits; ?>"> <label>nom</label><br/><input type="text" name="nom" /><br/> <label>prnom</label><br/><input type="text" name="prenom" /><br/> <label>adresse</label><br/><input type="text" name="adresse" /><br/> <label>code postal</label><br/><input type="text" name="cp" /><br/> <label>ville</label><br/><input type="text" name="ville" /><br/> <input type="submit" value="enregistrer ma commande" /> </form> </div> </body> </html>

Figure 15.9 : Le mme produit est dsormais list deux fois

LE GUIDE COMPLET 465

Chapitre 15

Les cookies et les sessions

Passez maintenant lenregistrement de la commande :


Listing 15-19 : Le script enregistre_commande.php <?php include("variables.inc.php"); if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[cp]) || empty($_REQUEST[ville])) die("ERREUR : tous les champs doivent tre remplis."); $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $date = date("Y-m-d G:i:s"); $_COOKIE[monpanier][0] = ; $tab_prod = split(",",$_COOKIE[monpanier]); $i = 0; while ($id = $tab_prod[$i]) { $sql = "SELECT * FROM $table_produit WHERE idproduit = $id"; $resultat = mysql_query ($sql); $produit = mysql_fetch_array ($resultat); $montant += $produit[prix]; $listeproduits .= , . $produit[reference]; $i++; } $listeproduits[0] = ; $montant += 5; $date = date("Y-m-d G:i:s"); $sql = "INSERT INTO $table_commande (produits, montant, nom, prenom, adresse, date) VALUES (" .$_REQUEST[listeproduits].", ".$_REQUEST[montant ].", ".$_REQUEST[nom].", ".$_REQUEST[prenom].", ".$_REQUEST[adresse]."\n".$_REQUEST[cp]."\n" .$_REQUEST[ville].", $date)"; mysql_query ($sql); mysql_close($liendb); setcookie("monpanier","",time()-3600); header("Location: $url/boutique.php"); ?>

466 LE GUIDE COMPLET

Les cookies

Chapitre 15

La suppression du cookie est ralise avec linstruction suivante :


setcookie("monpanier","",time()-3600);

Choix du procd

Nous prfrons, pour supprimer le cookie, cette dernire syntaxe la syntaxe setcookie("monpanier"), car elle est plus radicale. Lide ici est de mettre une date dexpiration dans le pass pour sassurer que le navigateur efface bien le cookie.

La mini-boutique est donc acheve, les commandes sont bien enregistres dans la base.

Figure 15.10 : Administration des commandes

Est-ce satisfaisant ? Certainement pas. Imaginez ce que pourrait entraner le fait de taper lURL suivante : http://localhost
/boutique/enregistre_commande.php?montant=10&liste produits=PROD001,PROD002,PROD002&nom=Daunou&prenom =Sophie&adresse=41+rue+voltaire&cp=75002&ville=Paris.

Cette commande permet de valider une commande de trois produits pour un montant de 10 euros ! Lexemple montre bien que, ds que vous ralisez le moindre applicatif vocation publique, il est impratif, un moment donn, de se mettre dans ltat desprit dune personne aux intentions douteuses. Lerreur ici est de passer directement en paramtre le montant de la commande. Le fait davoir la liste des produits permet cependant
LE GUIDE COMPLET 467

Chapitre 15

Les cookies et les sessions

dviter cela. Cest le script enregistre_commande.php qui doit calculer lui-mme le montant de la commande. Comme vous allez vous baser sur le contenu du cookie, vous pouvez aussi vous dbarrasser du paramtre listeproduits. Les paramtres hidden, du script voir_caddie.php, peuvent donc tre supprims :
Listing 15-20 : Version scurise de enregistre_commande.php <?php include("variables.inc.php"); if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[cp]) || empty($_REQUEST[ville])) die("ERREUR : tous les champs doivent tre remplis."); $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $date = date("Y-m-d G:i:s"); $_COOKIE[monpanier][0] = ; $tab_prod = split(",",$_COOKIE[monpanier]); $i = 0; while ($id = $tab_prod[$i]) { $sql = "SELECT * FROM $table_produit WHERE idproduit = $id"; $resultat = mysql_query ($sql); $produit = mysql_fetch_array ($resultat); $montant += $produit[prix]; $listeproduits .= , . $produit[reference]; $i++; } $listeproduits[0] = ; $montant += 5; $date = date("Y-m-d G:i:s"); $sql = "INSERT INTO $table_commande (produits, montant, nom, prenom, adresse, date) VALUES ($listeproduits, $montant, ".$_REQUEST[nom].", " .$_REQUEST[prenom].", ".$_REQUEST[adresse]."\n" .$_REQUEST[cp]."\n".$_REQUEST[ville].", $date)"; mysql_query ($sql);

468 LE GUIDE COMPLET

Les cookies
mysql_close($liendb); setcookie("monpanier","",time()-3600); header("Location: $url/boutique.php"); ?>

Chapitre 15

Dans le cadre de cette application, les cookies vont servir galement stocker le prol client et lui prremplir son formulaire didentication en cas de nouvel achat. Lide est donc de crer un nouveau cookie,
$_COOKIE[monprofil], qui contient toutes les informations des

clients. La cration doit se faire lors de lenregistrement de la commande dans enregistre_commande.php. Vous allez choisir la norme nom1=valeur1;;nom2=valeur2;; pour stocker les donnes et ajouter la ligne suivante dans enregistre_commande.php :
setcookie("monprofil","nom=".$_REQUEST[nom].";;prenom=" .$_REQUEST[prenom].";;adresse=".$_REQUEST[adresse] .";;cp=".$_REQUEST[cp].";;ville=".$_REQUEST[ville] ."",time()+604800);

Norme pour le stockage de donnes

Il est courant en PHP de stocker les donnes dans son propre format. Veillez alors ne pas utiliser de caractres trop rpandus comme caractres de sparation an dviter tout risque de conit avec lune des valeurs. Dans lexemple suivant, si vous choisissez la virgule comme caractre de sparation, vous serez bien ennuy pour diffrencier la virgule de sparation de la virgule prsente dans ladresse : adresse=9, rue JeanJaurs,CP=75015,ville=Paris.

La deuxime tape consiste prremplir le formulaire. La seule difficult est de rcuprer chaque caractristique du prol. Il faut utiliser une premire fois la fonction split() avec deux points-virgules (";;") comme premier paramtre et une deuxime fois avec le signe gal (=).
Listing 15-21 : Le formulaire est dsormais pr rempli <?php include("variables.inc.php"); ?> <html>

LE GUIDE COMPLET 469

Chapitre 15

Les cookies et les sessions

<head> <title>Boutique FoxShop - validation commande</title> <link href="look.css" rel="stylesheet" type="text/css" /> </head> <body> <div class=titre><a href=boutique.php>Boutique <i>FoxSHOP</i></a></div> <div class=caddie> <?php $montant = 0; $listeproduits = " "; $_COOKIE[monpanier][0] = ; $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_produit ". "WHERE idproduit IN (".$_COOKIE[monpanier].")"; $resultat = mysql_query ($sql); print("<table width=100%>"); $tab = array_count_values(split(",",$_COOKIE[monpanier])); while ($prod = mysql_fetch_array ($resultat)) { print("<tr><td class=produit>"); print("[".$prod[reference]."] ".$prod[nom]); print(" (x".$tab[$prod[idproduit]].")"); print("</td><td class=montant>"); print($prod[prix]." "); print("</td></tr>"); $montant += $prod[prix]*$tab[$prod[idproduit]]; $listeproduits .= ,.$prod[reference]; } $listeproduits[0] = ; // frais de port $montant += 5; print("<tr><td class=total>MONTANT + PORT</td>"); print("<td class=total>$montant </td></tr>"); print("</table>"); mysql_close($liendb); ?> <form action="enregistre_commande.php" method="post"> <input type="hidden" name="montant" value="<?php echo $montant; ?>"> <input type="hidden" name="listeproduits" value="<?php echo $listeproduits; ?>"> <?php if (!empty($_COOKIE[monprofil])) { $tab_tmp = split(";;",$_COOKIE[monprofil]);

470 LE GUIDE COMPLET

Les cookies
$i = 0; while ($tab_tmp[$i]) { list ($nom,$val) = split("=",$tab_tmp[$i]); $tab_profil[$nom] = $val; $i++; } } ?>

Chapitre 15

<label>nom</label><br/> <input type="text" name="nom" value="<?php echo $tab_profil[nom]?>" /> <br/><label>prnom</label><br/> <input type="text" name="prenom" value="<?php echo $tab_profil[prenom]?>" /> <br/><label>adresse</label><br/> <input type="text" name="adresse" value="<?php echo $tab_profil[adresse]?>" /> <br/><label>code postal</label><br/> <input type="text" name="cp" value="<?php echo $tab_profil[cp]?>" /> <br/><label>ville</label><br/> <input type="text" name="ville" value="<?php echo $tab_profil[ville]?>" /> <br/><input type="submit" value="enregistrer ma commande" /> </form> </div> </body> </html>

Plutt quun deuxime tableau temporaire pour recueillir les donnes issues du deuxime split(), utilisez la fonction list qui vous permet de placer directement les donnes dans deux variables. Si linternaute nest pas encore client, le tableau $tab_profil est vide. De ce fait, afficher $tab_profil[nom] nest pas gnant, car cela quivaut ne rien afficher. Si, par contre, il est dj client, $tab_profil[nom] contiendra le nom quil avait spci lors de son dernier achat. Quand cest possible, comme ici, il est intressant de ne pas multiplier les cas (avec des if) et dessayer dtre le plus gnrique possible.

LE GUIDE COMPLET 471

Chapitre 15

Les cookies et les sessions

15.2. Les sessions


Vous venez de voir que les cookies permettent de transmettre de linformation dune page lautre. Certains inconvnients peuvent cependant tre nots :
j j

lobligation de les grer en haut du script avant que des donnes ne soient affiches ; le format assez primaire de stockage de linformation (une chane de caractres).

Pour rpondre ces limitations, le langage PHP vous propose dutiliser un systme de session. nimporte quel endroit de votre script, il est possible de dnir certaines variables en tant que variable de session. Une fois enregistres, ces variables sont propages dune page lautre. Elles deviennent schmatiquement des variables globales lensemble du site, tout en restant associes un visiteur donn. Si vous modiez le contenu dune variable de session dans un script A, vous rcuprez le contenu modi dans un script B. Il est important de signaler que le nombre de variables de session nest pas limit : vous pouvez en enregistrer autant que ncessaire. Le mode de fonctionnement des sessions est extrmement simple. Il sappuie sur :
j j

la fonction session_start() qui indique au script que vous souhaitez rcuprer les variables de session. la variable super-globale $_SESSION qui contient lensemble des variables de session.
$_SESSION[x] = 2;

Ralisez ce petit exemple, qui permet de savoir combien de fois une personne est venue sur une page :
Listing 15-22 : Exemple simple dutilisation des sessions <?php session_start(); if (!isset($_SESSION[visite])) { echo "premire visite"; $_SESSION[visite] = 1; } else {

472 LE GUIDE COMPLET

Les sessions

Chapitre 15

$_SESSION[visite]++; echo "vous avez visit cette page ".$_SESSION[visite ]." fois"; } ?>

Figure 15.11 : Message apparaissant en arrivant pour la premire fois sur

la page

Figure 15.12 : Message apparaissant lorsque la page est rafrachie

Analysons cet exemple Dans ce script, vous souhaitez faire usage de variables de session. Vous lindiquez PHP en excutant la fonction session_start(). Votre seule contrainte est de faire appel cette fonction avant le premier affichage du script.

Figure 15.13 : Erreur gnre la suite dun affichage de la chane "test" avant lappel session_start()

LE GUIDE COMPLET 473

Chapitre 15

Les cookies et les sessions

Vous testez ensuite si la variable $_SESSION[visite] (qui va contenir le nombre de vos visites) existe. Si ce nest pas le cas, vous affichez le message "premire visite" et initialisez la variable de session "visite" 1. partir de ce moment, toute modication de sa valeur sera propage dune page lautre. En rafrachissant la page, vous vous retrouvez dans le cas o la variable
$_SESSION[visite] existe. Lors de chaque accs cette page,

vous faites augmenter le compteur de visites en incrmentant directement la variable $_SESSION[visite]. Bien videmment, si vous placez ce mme code dans un autre script, la variable $_SESSION[visite] sera aussi incrmente. La variable de session est en effet partage par tous les scripts dun mme site. Un autre grand avantage des variables de session est de permettre denregistrer des variables de type complexe comme des tableaux. Vous pouvez voir lextrme intrt de cette fonctionnalit dans le cadre de votre applicatif. Plutt que de stocker vos donnes en les sparant par des virgules (valeur1,valeur2, etc.) ou en utilisant une norme boiteuse (nom1=valeur1;;nom2=valeur2;;), autant utiliser dans le premier cas un tableau scalaire, et, dans le deuxime cas, un tableau associatif. Modiez les chiers ajout_caddie.php, boutique.php, voir_caddie.php, enregistre_commande.php an dutiliser des sessions plutt que des cookies. Commencez par lajout au panier :
Listing 15-23 : Le script ajout_caddie.php <?php include("variables.inc.php"); session_start(); if (!isset($_SESSION[monpanier])) $_SESSION[monpanier] = array(); $_SESSION[monpanier][] = $_REQUEST[id]; header("Location: $url/boutique.php?id=".$_REQUEST[id]); ?>

474 LE GUIDE COMPLET

Les sessions
Listing 15-24 : Le script boutique.php <?php include("variables.inc.php"); session_start(); if (!isset($_REQUEST[id])) $id = 1; else $id = $_REQUEST[id]; ?>

Chapitre 15

<html> <head> <title>Boutique FoxShop - catalogue</title> <link href="look.css" rel="stylesheet" type="text/css" /> </head> <body> <div class=titre><a href=boutique.php>Boutique <i>FoxSHOP</i></a></div> <table class=catalogue> <tr> <td class=liste> <div class=tdTitre>Nos produits</div> <?php $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_produit"; $resultat = mysql_query ($sql); while ($produit = mysql_fetch_array ($resultat)) { print(" - "); print("<a href=".$_SERVER[PHP_SELF]."?id=".$produit [idproduit].">". $produit[nom]."</a>"); print("<br/>"); } ?> </td> <td class=detail> <?php $sql = "SELECT * FROM $table_produit WHERE idproduit = $id"; $resultat = mysql_query ($sql); $produit = mysql_fetch_array ($resultat); print("<div class=tdTitre>".$produit[nom]. " [ref#".$produit[reference]."]</div>"); ?>

LE GUIDE COMPLET 475

Chapitre 15

Les cookies et les sessions

<div class=description> <?php print(nl2br($produit[description])."<br/><br/>"); print($produit[prix]." <br/><br/>"); mysql_close($liendb); ?> <form action="ajout_caddie.php" method="post"> <input type="hidden" name="id" value="<?php echo $id; ?>" /> <input type="submit" value="ajouter au panier" /> </form> <?php if (isset($_SESSION[monpanier])) { print("<div class=panier>"); $nb_prod = count($_SESSION[monpanier]); print("votre panier contient ".$nb_prod." produit(s)<br/>"); print("<form action=voir_caddie.php method=post>"); print("<input type=submit value=valider la commande/> </form>"); print("session = {".implode(",",$_SESSION[monpanier])."}"); print("</div>"); } ?> </div> </td> </tr> </table> </body> </html>

Le passage aux sessions a globalement clari et simpli le code. Les diffrents produits ajouts au panier sont dsormais stocks dans une variable de session nomme $_SESSION[monpanier], de type tableau scalaire. Passez maintenant la validation et lenregistrement de la commande :
Listing 15-25 : Le script voir_caddie.php <?php include("variables.inc.php");

476 LE GUIDE COMPLET

Les sessions
session_start(); ?>

Chapitre 15

<html> <head> <title>Boutique FoxShop - validation commande</title> <link href="look.css" rel="stylesheet" type="text/css" /> </head> <body> <div class=titre><a href=boutique.php>Boutique <i>FoxSHOP</i></a></div> <div class=caddie> <?php $montant = 0; $listeproduits = " "; $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $sql = "SELECT * FROM $table_produit ". "WHERE idproduit IN (".implode(,,$_SESSION [monpanier]).")"; $resultat = mysql_query ($sql); print("<table width=100%>"); $tab = array_count_values($_SESSION[monpanier]); while ($prod = mysql_fetch_array ($resultat)) { print("<tr><td class=produit>"); print("[".$prod[reference]."] ".$prod[nom]); print(" (x".$tab[$prod[idproduit]].")"); print("</td><td class=montant>"); print($prod[prix]." "); print("</td></tr>"); $montant += $prod[prix]*$tab[$prod[idproduit]]; $listeproduits .= ,.$prod[reference]; } $listeproduits[0] = ; // frais de port $montant += 5; print("<tr><td class=total>MONTANT + PORT</td>"); print("<td class=total>$montant </td></tr>"); print("</table>"); mysql_close($liendb); ?> <form action="enregistre_commande.php" method="post"> <input type="hidden" name="montant" value="<?php echo $montant; ?>"> <input type="hidden" name="listeproduits"
LE GUIDE COMPLET 477

Chapitre 15

Les cookies et les sessions

value="<?php echo $listeproduits; ?>"> <label>nom</label><br/> <input type="text" name="nom" value="<?php echo $_SESSION[profil][nom]?> "/> <br/><label>prnom</label><br/> <input type="text" name="prenom" value="<?php echo $_SESSION[profil][prenom]?>" /> <br/><label>adresse</label><br/> <input type="text" name="adresse" value="<?php echo $_SESSION[profil][adresse]?>" /> <br/><label>code postal</label><br/> <input type="text" name="cp" value="<?php echo $_SESSION[profil][cp]?>" /> <br/><label>ville</label><br/> <input type="text" name="ville" value="<?php echo $_SESSION[profil][ville]?>" /> <br/><input type="submit" value="enregistrer ma commande" /> </form> </div> </body> </html> Listing 15-26 : Le script enregistre_commande.php <?php include("variables.inc.php"); session_start(); if (empty($_REQUEST[nom]) || empty($_REQUEST[prenom]) || empty($_REQUEST[adresse]) || empty($_REQUEST[cp]) || empty($_REQUEST[ville])) die("ERREUR : tous les champs doivent tre remplis."); $liendb = mysql_connect($bddserver, $bddlogin, $bddpassword); mysql_select_db ($bdd); $date = date("Y-m-d G:i:s"); $i = 0; foreach ($_SESSION[monpanier] as $i) { $sql = "SELECT * FROM $table_produit WHERE idproduit = $id"; $resultat = mysql_query ($sql); $produit = mysql_fetch_array ($resultat); $montant += $produit[prix]; $listeproduits .= , . $produit[reference];

478 LE GUIDE COMPLET

Les sessions
$i++; } $listeproduits[0] = ; $montant += 5;

Chapitre 15

$sql = "INSERT INTO $table_commande (produits, montant, nom, prenom, adresse, date) VALUES (" .$_REQUEST[listeproduits].", ".$_REQUEST[montant ].", ".$_REQUEST[nom].", ".$_REQUEST[prenom].", ".$_REQUEST[adresse]."\n".$_REQUEST[cp]."\n" .$_REQUEST[ville].", $date)"; mysql_query ($sql); mysql_close($liendb); session_unregister(monpanier); $_SESSION[profil][nom] $_SESSION[profil][prenom] $_SESSION[profil][adresse] $_SESSION[profil][cp] $_SESSION[profil][ville] = = = = = $_REQUEST[nom]; $_REQUEST[prenom]; $_REQUEST[adresse]; $_REQUEST[cp]; $_REQUEST[ville];

header("Location: $url/boutique.php"); ?>

Dans voir_caddie.php, vous pouvez parcourir le contenu du panier directement avec la variable $_SESSION[monpanier]. Il en est de mme pour le praffichage des informations client. Tout est stock dans la variable de session $_SESSION[monprofil]. Vous remarquez lusage dune nouvelle fonction dans
enregistre_commande.php : session_unregister(). Cette fonction

permet tout simplement de supprimer la variable de session dont le nom est pass en paramtre.
La fonction session_destroy()

Cette fonction va plus loin que session_unregister() : elle vous permet de supprimer toutes les variables de session.

Les sessions sont donc un outil trs puissant. Elles peuvent vous faciliter grandement la tche pour le dveloppement dapplications en ligne. Il ne faut cependant pas croire que les sessions pallient tous les dfauts des

LE GUIDE COMPLET 479

Chapitre 15

Les cookies et les sessions

cookies. Une erreur courante consiste se dire quavec les sessions vous navez plus vous soucier des internautes qui nacceptent pas les cookies. Ce raisonnement est compltement faux car les sessions utilisent en fait directement les cookies :
Listing 15-27 : La fonction session_id() retourne la valeur de lidentifiant de session unique qui a t allou <?php session_start(); echo "Identifiant de session : ".session_id(); ?>

Figure 15.14 : Valeur de lidentiant de session

Les variables de session sont en ralit stockes sur le serveur web et sont reconnues grce cet identiant unique. Cet identiant est stock dans un cookie sur votre disque. Une personne qui naccepte pas les cookies ne peut propager lid de session qui lui est transmis, et ne peut donc pas proter des sessions. Ce mode de fonctionnement permet en revanche dcarter les limitations des cookies concernant leur nombre et leur taille. Comme les donnes des sessions sont stockes sur le serveur, ces limitations sautent :
Listing 15-28 : Pour les plus curieux, la fonction session_save_path() retourne lendroit o sont stockes les donnes des sessions sur le server (souvent /tmp sous Unix/Linux) <?php session_start(); echo session_save_path(); ?>

Par dfaut, une session est dtruite quand linternaute ferme son navigateur. Vous devinez donc que le cookie qui est cr pour stocker lid de session est un cookie de session. Vous pouvez en avoir la preuve en utilisant la fonction session_get_cookie_params(), qui retourne un tableau contenant tous les paramtres du cookie de session :
480 LE GUIDE COMPLET

Les sessions
Listing 15-29 : Affichage des proprits du cookie de session <?php session_start(); print_r(session_get_cookie_params()); ?>

Chapitre 15

Figure 15.15 : Proprits du cookie de session

Il est possible de faire en sorte quune session subsiste la fermeture du navigateur. Utilisez pour cela la fonction session_set _cookie_params() qui permet de modier les proprits du cookie de session. Transformez ce petit exemple de compteur de manire ce que la session soit conserve une semaine :
Listing 15-30 : Le compteur conserve dsormais la bonne valeur, mme si vous quittez le navigateur <?php session_set_cookie_params(time()+604800); include("variables.inc.php"); session_start(); if (!isset($_SESSION[monpanier])) $_SESSION[monpanier] = array(); $_SESSION[monpanier][] = $_REQUEST[id]; header("Location: $url/boutique.php?id=".$_REQUEST[id]); ?>

La fonction session_set_cookie_params() devant tre appele avant chaque appel session_start(), lidal est de placer lappel ces deux fonctions dans variables.inc.php.

LE GUIDE COMPLET 481

Chapitre 15

Les cookies et les sessions

Listing 15-31 : Les sessions sont maintenant dmarres dans variables.inc.php <?php $bddserver = "localhost"; $bddlogin = "root"; $bddpassword = ""; $bdd = "test"; $table_eleve = "eleve"; $table_exam = "exam"; $url = "http://localhost"; session_set_cookie_params(time()+604800); include("variables.inc.php"); ?>

Cette option peut tre intressante si vous souhaitez mettre en place un systme de panier permanent dans votre boutique : le client retrouve son panier lorsquil se reconnecte au site marchand.
Transmission de lidentiant de session par URL

Lidentiant de session peut galement tre transmis par lURL. Cette technique a lavantage de fonctionner avec tous les internautes (quils acceptent les cookies ou pas). Elle souffre cependant des dfauts suivants : j Elle est beaucoup plus lourde mettre en place. j Elle demande plus de ressources au niveau serveur. j Elle ncessite que linterprteur PHP soit compil avec certaines options.

15.3. Check-list
j j

j j

Les cookies et les sessions permettent de propager des donnes lies un internaute durant toute la dure de sa visite. Les sessions ont lavantage dtre plus simples grer que les cookies. Une session est compose dun cookie contenant son identiant et dun chier sur le serveur contenant les donnes. Les variables $_SESSION et $_COOKIE sont utilises pour y avoir accs. Longtemps dcris, les cookies sont dsormais entrs dans les murs du Web.

482 LE GUIDE COMPLET

La gestion de la scurit
La scurit avec PHP ........................................................................................................ 485 Scuriser les bases de donnes .................................................................................... 493 Scuriser le serveur web .................................................................................................. 496 Les outils danalyse ........................................................................................................... 503 Check-list ............................................................................................................................. 504

Chapitre 16

La gestion de la scurit

La popularit des applications web a non seulement attir les utilisateurs et les dveloppeurs, mais galement les pirates informatiques (souvent appels hackers). Les sites spcialiss en scurit tels que phpsec.org, secunia.com ou www.securityfocus.com signalent dsormais quotidiennement des failles dans des outils tels que le forum phpBB (www.phpbb.com), loutil de gestion de contenu (CMS) PHP-Nuke (phpnuke.org), la plateforme de-commerce osCommerce (www .oscommerce.com), le gestionnaire de blog Wordpress (wordpress.org) et plusieurs centaines dautres. PHP ne souffre en lui-mme daucun problme de scurit. Le souci vient plutt du fait quil est extrmement facile de laisser des failles de scurit au cur dapplications crites dune part pour le Web et dautre part en PHP. Listons quelques-uns des aspects les plus problmatiques :
j

j j

PHP est un langage extrmement facile prendre en main. Un dbutant sans connaissance prliminaire en scurit peut raliser et mettre en ligne un applicatif en quelques jours (voir en quelques heures). La scurit dune application web impose des connaissances informatiques relativement larges : serveur web, PHP, Javascript, authentication, base de donnes, sessions, cookies, protocoles, systme dexploitation (droits, chemins), etc. Pour une application en ligne, le nombre potentiel dutilisateurs malintentionns est aussi gigantesque quincontrlable. Les techniques mises en uvre pour exploiter les failles sont souvent triviales et, par consquent, accessibles de jeunes gens en mal damusement (les scripts kiddies). Nous sommes loin de la dcompilation et de lassembleur qui ne permettaient qu un tout petit nombre de pirates de cracker des logiciels. Certains dfauts du langage PHP ont des implications directes dans la nature faillible des applications dont il est lorigine : les nombreuses faons de transmettre des donnes (input, session, cookies), labsence de composants , linconsistance des diffrents noms (variables, objets, fonctions, etc.), la prsence de variables globales rendant la relecture du code ardue et les tests dunit pour le moins complexes.

Ce chapitre vise vous prsenter les failles potentielles les plus rpandues qui peuvent simmiscer au sein dune application. Plus que

484 LE GUIDE COMPLET

La scurit avec PHP

Chapitre 16

cela, il doit vous faire prendre conscience que la scurisation dun code est une tape indispensable et essentielle lors du dveloppement dun applicatif.

16.1. La scurit avec PHP


Commenons par tudier les diffrents points devant tre surveills au sein de vos scripts PHP.

Le b-a ba
Certains dveloppeurs ont tendance concevoir leurs applicatifs en pensant quun certain nombre de tches pourront tre ralises la n du projet. Cette pratique est gnralement proscrire car, comme dans beaucoup dautres domaines, la n dun projet se droule souvent dans lurgence et le stress. Il est donc conseill de ne pas attendre lissue du projet pour initialiser de manire cohrente vos diffrents mots de passe et ne pas laisser des accs de type "admin/admin", "test/test". Pour rappel, un mot de passe doit contenir au minimum huit caractres et inclure des caractres numriques.
Dictionnaires et brute force

Nallez surtout pas croire quun hacker souhaitant trouver le mot de passe de votre site essaiera successivement et pniblement plusieurs dizaines de possibilits. Il existe aujourdhui des dictionnaires de mots et des scripts permettant en quelques minutes de tester plusieurs centaines de milliers de possibilits. Ces dictionnaires disposent galement de tous les prnoms, marques dalcools, noms de plantes et divers termes souvent utiliss en informatique pour initialiser un mot de passe. Lchec dune attaque lance laide dun dictionnaire ne rebutera cependant pas un pirate motiv. Lattaque dite brute force consiste tester toutes les combinaisons de caractres possibles les unes aprs les autres. Cette attaque peut durer des heures, voire des journes, mais noubliez pas que le pirate na pas attendre devant sa machine, quaujourdhui les machines sont extrmement puissantes et que les liaisons Internet sont quasi gratuites.

LE GUIDE COMPLET 485

Chapitre 16

La gestion de la scurit

Il peut donc tre malin dinterdire un trop grand nombre de tentatives daccs successives une zone scurise. Il convient pour cela denregistrer chaque tentative (accompagne de son adresse IP) dans une base de donnes et de vrier, avant dautoriser laccs, quil ny a pas eu plus de n tentatives depuis cette mme adresse auparavant.

Mise jour de PHP


Disposer dun interprteur PHP en permanence jour est crucial pour votre applicatif. Chaque nouvelle version de PHP apporte en effet son lot de nouvelles fonctionnalits, de corrections de bugs et surtout de corrections de failles de scurit. Bien que ces failles soient la plupart du temps mineures, il peut arriver que certaines soient exploitables de faon distante. Vous ne pourrez alors rien y faire, quelles que soient vos comptences de programmeur.

Figure 16.1 : Exemple de lignes prendre en compte dans le rapport de mises jour dune nouvelle version de PHP

La fonction phpversion() ou la constante PHP_VERSION peuvent tre utilises pour obtenir la version de linterprteur.

Initialiser toutes les variables


Cette pratique consiste donner une valeur toutes les variables que vous utilisez au sein de votre script.
486 LE GUIDE COMPLET

La scurit avec PHP

Chapitre 16

if ($_POST[identifiant]==sys && $_POST[pass]==sys) { $status_admin = true; }

Ce code nest pas correct dans la mesure o la variable $status_admin na pas t initialise. La version correcte est la suivante :
$status_admin = false; if ($_POST[identifiant]==sys && $_POST[pass]==sys) { $status_admin = true; }

Le statut dadministrateur est faux si lauthentication na pas t ralise ou si elle choue. Dans le premier code, son statut ne serait pas dni.
CURL

Les programmeurs dbutants ont souvent tendance penser que les tentatives de piratage ne passent que par la mthode GET. Cette supposition est compltement fausse. Des outils tels que CURL (curl.haxx .se) permettent ainsi de raliser des scripts qui simulent lenvoi de paramtres en mode POST. CURL permet mme de simuler la transmission de cookies. La page de documentation est disponible ladresse http://curl.haxx.se/docs/manpage.html.

De la mme manire, le changement des mots de passe par dfaut est essentiel. Ainsi noubliez surtout pas de modier le mot de passe root de MySQL.

Utiliser les constantes


La plupart des attaques visent exploiter une faille qui permettra de modier une variable utilise dans un endroit sensible du script (ex: inclusion, excution etc.). Lutilisation des constantes, dont le contenu nest pas modiable par dnition, permet de rendre la tche du pirate plus ardue.

LE GUIDE COMPLET 487

Chapitre 16

La gestion de la scurit

Se mer de la puissance de certaines fonctions


La fonction extract() permet dimporter dans la table gnrale des variables le tableau qui lui est pass en paramtre. Voyons tout de suite un exemple qui devrait clarier les choses :
Listing 16-1 : utilisation de la fonction extract() print("bonjour : <br/>"); print("hello : <hr/>"); $tab = array(bonjour=>monde, hello=>world); print_r($tab); print("<hr/>"); extract($tab); print("bonjour : $bonjour<br/>"); print("hello : $hello<br/>");

Figure 16.2 : Les cellules du tableau deviennent accessibles en tant que variables

Vous comprenez alors limportance dtre sr de son tableau avant dappeler la fonction extract(). Un internaute qui parviendrait modier le tableau pass en paramtre pourrait craser toutes les variables de lapplication (par exemple $status_admin). La fonction extract() peut galement prendre un second paramtre qui indique le comportement avoir quand une variable est dj dnie avant lappel extract(). Nous vous conseillons dutiliser la valeur EXTR_SKIP qui interdit lcrasement dune variable prexistante.
$bonjour = coucou; print("bonjour : $bonjour<br/>"); print("hello : $hello<hr/>"); $tab = array(bonjour=>monde, hello=>world); print_r($tab); print("<hr/>"); extract($tab,EXTR_SKIP); print("bonjour : $bonjour<br/>"); print("hello : $hello<br/>");

488 LE GUIDE COMPLET

La scurit avec PHP

Chapitre 16

Figure 16.3 : La variable $bonjour conserve sa valeur

Dangers de la fonction mail


Il est courant de composer un mail partir dlments provenant dun formulaire. Ladresse email est souvent utilise pour composer len-tte From: et permettre au destinataire du message, de rpondre directement linternaute.
Listing 16-2 : Les paramtres du formulaire sont directement utiliss dans le mail mail("fx@domain.fr","sujet","contenu","From: {$_REQUEST[email]}");

Figure 16.4 : Lorigine du destinataire apparat bien : internaute@domain.com

Notre erreur consiste ici ne pas vrier le paramtre avant de linclure dans le message. En effet, les spammers parviennent dsormais exploiter les millions de formulaires prsents sur le web pour envoyer des messages non sollicits. Leur technique consiste transmettre au script PHP non pas une adresse email mais une adresse email avec dautres directives exploitables dans len-tte du mail. En transmettant notre script les paramtres suivants :
LE GUIDE COMPLET 489

Chapitre 16

La gestion de la scurit

email=dest%40domain.com%0D%0ACc%3Adest2%40domain.com

le spammer initialise la fois les en-ttes From: et Cc: du mail.

Figure 16.5 : dest2@domain.com va recevoir un email de spam

Pour tre valide, notre script doit donc vrier que le paramtre email ne contient pas de retour la ligne.
Listing 16-3 : Vrification de la validit du paramtre email if (strpos($_REQUEST[email],"\n")!=false || strpos($_REQUEST[email],"\r")!=false) exit (1); else mail("fx@domain.fr","sujet","contenu","From: {$_REQUEST[email]}");

Les cookies et les sessions


Aussi bien les cookies que les sessions prennent une place tous les jours plus importante dans les applications web en tant que point central du systme dauthentication. Il nest donc pas tonnant que le cookie dun internaute soit si convoit par les pirates. Il savre en plus que les techniques existent et quelles ne sont pas si complexes mettre en place. Le fonctionnement avec un passage de lidentiant de session en paramtre est par exemple trs dangereux. Prenez lexemple dun webmail fonctionnant sur ce schma. Une URL typique au sein de
490 LE GUIDE COMPLET

La scurit avec PHP

Chapitre 16

lapplication pourrait tre : www.monmail.com/lire.php?PHPSESSID =1234-5678&num_msg=ABC. Elle pourrait correspondre la lecture du message ABC par le visiteur dont la session porte lidentiant 12345678. Supposons maintenant que le courriel lu comporte dans son contenu un lien vers le site monsite.com et que linternaute clique dessus. Si les dveloppeurs du webmail ne sont pas vigilants, ladministrateur de monsite.com peut se retrouver dans ses logs avec une visite dont lorigine est prcisment www.monmail.com/lire.php?PHPSESSID=1234 -5678&num_msg=ABC. En cliquant sur ce lien qui dispose donc de lidentiant de session, ce cher administrateur aura la surprise de pouvoir lire un courriel qui ne lui est pas du tout adress. Pour parer ce genre de faille, nous recommandons donc de passer par un script dont le rle se limiterait une redirection et qui ne prendrait en paramtre que lURL de destination et en aucun cas lidentiant de session ; par exemple : www.monmail.com/redir.php?url=http://www.monsite.com. Ces techniques sont souvent voques en tant que session hijacking.
LIP dans la session : une fausse bonne ide

Pour parer aux failles dcrites prcdemment, le programmeur peut avoir envie de mettre en uvre un systme permettant de vrier si linternaute qui rclame la session est le mme que celui qui en est lorigine. Une ide pourrait donc consister placer dans la session ladresse IP de linternaute qui vient de la crer et vrier systmatiquement si cette mme IP est identique celle de linternaute qui rclame la session. Cette ide qui peut paratre bonne premire vue est hlas invalide. Il convient en effet de savoir quun visiteur ne garde pas obligatoirement la mme IP durant toute la dure de sa visite. Certains routeurs permettent en effet la connexion deux fournisseurs daccs et autorisent ainsi un passage altern par lun ou lautre des fournisseurs. Si le routeur est connect Free ADSL et Noos, linternaute, dune page lautre, apparatra tour tour avec une IP Free et une IP Noos. Mme si cet aspect nexiste que pour 1 % des internautes, il est prendre en compte.

Les transferts de chiers


Le fait de demander une photo nimplique pas ncessairement que linternaute choisira un chier de type image. Sil envoie au contraire un chier PHP, il pourra alors excuter son script de manire distante au sein mme de votre compte et provoquer de vritables catastrophes.

LE GUIDE COMPLET 491

Chapitre 16

La gestion de la scurit

Le test suivant permet de vrier que le chier transmis se termine bien par .jpeg, .jpg, .gif ou .png :
Listing 16-4 : le fichier est-il de type image ? if (preg_match("/\.(jpeg|jpg|gif|png)$/i", $_FILES[userfile][tmp_name])) { echo "ok"; } else { echo "ko"; }

Inclusion de chier
Soyez extrmement prudent avec les inclusions de chiers faisant intervenir des donnes passes en paramtres. Lexemple suivant est proscrire :
if ($_REQUEST[action]!=accueil) include($_REQUEST[action]); else include("index.php");

Un pirate peut transmettre la valeur suivante action=../ ../WINDOWS/win.ini et obtenir le contenu de nimporte quel chier prsent sur le disque dur.

Figure 16.6 : contenu du chier win.ini prsent dans C:\WINDOWS

Linclusion dun chier avec la fonction include() ne doit donc jamais exploiter directement une donne transmise en paramtre.

492 LE GUIDE COMPLET

Scuriser les bases de donnes

Chapitre 16

16.2. Scuriser les bases de donnes


Les failles lies aux bases de donnes sont aujourdhui les plus rpandues.

Les injections SQL


Le programmeur dbutant ne ralise pas quel point lutilisation des bases de donnes impose une extrme prudence. tudiez le code suivant :
mysql_query("DELETE FROM matable WHERE ID = ".$_REQUEST [monid]);

Cette ligne vise supprimer de la table matable la ligne dont la cl est gale au paramtre monid. Si la variable $_GET[monid] contient la valeur 22, la requte quivaut ceci :
mysql_query("DELETE FROM matable WHERE ID = 22");

Supposons maintenant quune personne mal intentionne transmette lURL suivante : http://127.0.0.1/supprime.php?monid=22+OR+ID+ %3E+0. Vous pouvez alors vous inquiter car la requte devient :
mysql_query("DELETE FROM matable WHERE ID = 22 OR ID > 0");

Elle entrane une suppression complte de la table matable ! Cette attaque est qualie dinjection SQL. Deux habitudes importantes doivent tre prises pour viter cette situation :
j

passer par la fonction mysql_real_escape_string() avant dinsrer des donnes extrieures dans la base (provenant dun formulaire, dun cookie etc.) ; utiliser les guillemets autour des donnes.
Listing 16-5 : version scurise de notre requte
mysql_query("DELETE FROM matable WHERE ID = ". mysql_real_escape_string($_REQUEST [monid])."");

LE GUIDE COMPLET 493

Chapitre 16

La gestion de la scurit

Les Cross Site Scripting


Ces attaques sont plus connues sous le terme gnrique de XSS. Le principe dune attaque XSS est le suivant :
j

Le pirate remplit un formulaire en y incluant des balises nocives. Les donnes du formulaire sont stockes dans une base de donnes sans tre nettoyes pralablement. Un internaute accde au site (par exemple un forum), visualise larticle transmis par le pirate et subit lassaut du pirate.

Les balises nocives dont nous parlons correspondent le plus souvent des liens. Ces derniers sont crits de manire rcuprer le cookie de linternaute et le transmettre au pirate. Illustrons cela laide dun exemple. Le premier script enregistre les donnes dans une table article :
Listing 16-6 : ajout.php <?php if (!empty($_REQUEST[contenu])) { $contenu = $_REQUEST[contenu]; $liendb = mysql_connect("localhost", "root", ""); mysql_select_db("test"); mysql_query("INSERT INTO article (contenu) VALUES ($contenu)"); print("enregistrement ok"); return (true); } ?> <form method=post action=ajout.php> <textarea style=width:100% name=contenu> </textarea><br/> <input type=submit value=enregistrer> </form>

Figure 16.7 : Texte renseign par le pirate

494 LE GUIDE COMPLET

Scuriser les bases de donnes

Chapitre 16

Le second script permet dafficher un article enregistr dans la base et de placer un cookie secret sur la machine de linternaute.
Listing 16-7 : visualisation de larticle <?php setcookie(secret,rand(100,999)); $liendb = mysql_connect("localhost", "root", ""); mysql_select_db("test"); $sql = "SELECT * FROM article"; $resultat = mysql_query ($sql); $article = mysql_fetch_array ($resultat); ?> <div style=width:200px; border:2px solid black; padding:6px; height:200px> <?php print($article[contenu]); ?> </div>

Figure 16.8 : Apparition du cookie

En cliquant sur le lien de larticle, le code secret apparat ! Cest grave car il va sans dire que dans la ralit les pirates font plutt en sorte de se faire envoyer discrtement le code secret. La parade classique pour ces attaques XSS consiste protger les donnes envoyes par les internautes laide de la fonction htmspecialchars(). Cette fonction convertit les caractres &, ", , < et > en leur quivalent HTML : &, , ', < et >. Cela vous permet de ne pas altrer le contenu tout en vous protgeant. Le script ajout.php doit donc tre modi de la faon suivante :
if (!empty($_REQUEST[contenu])) { $contenu = htmlspecialchars($_REQUEST[contenu]); $liendb = mysql_connect("localhost", "root", "");

LE GUIDE COMPLET 495

Chapitre 16

La gestion de la scurit

mysql_select_db("test"); mysql_query("INSERT INTO article (contenu) VALUES ($contenu)"); print("enregistrement ok"); return (true); }

Le mme message est dsormais enregistr de la manire suivante :


cliquez ici pour aller sur <a href=javascript:alert (document.cookie)>mon site</a>

Visuellement, vous obtenez un affichage correct et vous ne subissez plus cette attaque.

Figure 16.9 : Lattaque apparat au grand jour

Figure 16.10 : Les caractres dangereux ont bien t remplacs par leur quivalent HTML

16.3. Scuriser le serveur web


Le serveur web peut tre assimil au socle de votre application web. Un serveur web mal congur, et cest lensemble de votre outil qui peut en ptir. Inversement, certains paramtres peuvent accrotre largement la scurit globale.

496 LE GUIDE COMPLET

Scuriser le serveur web

Chapitre 16

Les directives PHP


La plupart des directives de conguration de PHP peuvent tre initialises au sein du chier php.ini ainsi quau niveau des chiers de conguration dApache. Chaque site web du serveur peut ainsi disposer dun environnement qui lui est propre. Si certains paramtres par dfaut ne vous conviennent pas, il est possible de demander un changement de conguration votre administrateur systme. Un certain nombre de paramtres doivent tre particulirement contrls :
j

magic_quotes_gpc : ce paramtre permet dajouter les fameux caractres dchappement (\, \") pour les donnes transmises via les mthodes GET, POST ou via les cookies. Bien que cela soit

a priori trs pratique, cette fonctionnalit est risque dans la mesure o elle ne conduit pas un systmatisme dans la protection des donnes. Les directives magic_quotes _runtime et magic_quotes_sybase peuvent galement tre forces false pour viter les mmes cueils. register_globals : cette directive est false par dfaut depuis la version 4 de PHP. Il est conseill de la laisser ainsi an dviter au maximum les problmes dinitialisation et dcrasement de variables rencontrs plus haut. display_errors : cette directive peut rester on pendant tout le dveloppement car elle vous permet dafficher des informations prcieuses durant la phase de correction des bugs (souvent qualie de phase de dbogage) . Une fois le site mis en production, il est cependant conseill de la passer off an de ne pas transmettre dinformations stratgiques un ventuel pirate. Une erreur sur une inclusion de script donnera des informations sur lorganisation des rpertoires et des scripts (il saura alors o frapper).

Figure 16.11 : Linternaute sait dsormais que test.php se situe dans C:\wamp\www

LE GUIDE COMPLET 497

Chapitre 16

La gestion de la scurit

Une erreur sur une connexion mysql permettra quant elle dobtenir des informations sur le serveur SGBD (cach jusqu prsent) et dorienter certaines attaques sur celui-ci. Encore une fois, plus votre ennemi dispose dinformations exploiter, plus sa capacit de nuisance sera grande et rapide.

Figure 16.12 : Erreur de connexion au SGBD

De la discrtion

Dans la mme ligne, veillez ce que le chier de log cr par le serveur web ne soit pas accessible en ligne (par exemple www.toto.com/logs/ access.log). Un tel chier contiendrait en effet les mmes informations que celles affiches en mode display_errors on.

La directive display_errors est directement lie error _reporting qui dnit le niveau de prcision des affichages derreur. Il est ainsi possible dindiquer PHP de nafficher que les erreurs ou de les afficher accompagnes davertissements (notice). Prenez le script suivant :
print($tmp); $tmp = 3; print("ici");

Placez-vous

tout

dabord

dans

un

environnement

error

_reporting naffiche pas les avertissements :


error_reporting = E_ALL & ~E_NOTICE

Figure 16.13 : Rien signaler a priori

498 LE GUIDE COMPLET

Scuriser le serveur web

Chapitre 16

Affichez maintenant les avertissements en plus des erreurs :


error_reporting = E_ ALL & E_NOTICE

Vous obtenez le rsultat suivant :

Figure 16.14 : Vous tes prvenu que la variable $tmp na pas t initialise

En augmentant le degr daffichage des erreurs, vous augmentez instantanment le taux de capture derreurs et la qualit globale du code.
La directive error_reporting

Cette directive peut prendre une multitude dautres valeurs dont voici la liste : j E_ALL, E_ERROR ; j E_WARNING ; j E_PARSE, E_NOTICE ; j E_CORE_ERROR ; j E_CORE_WARNING ; j E_COMPILE_ERROR ; j E_COMPILE_WARNING ; j E_USER_ERROR ; j E_USER_WARNING ; j E_USER_NOTICE. En jouant sur ces valeurs, vous obtiendrez un niveau de report en adquation avec votre style de programmation.

Dans la mme ligne, il est conseill de logger tous les vnements inhabituels qui ont lieu au sein de votre applicatif. La fonction error_log() vous permet dajouter vos propres commentaires au sein du chier de log de PHP.
error_log_test("ajout de mes propres logs");

Vous retrouvez ces commentaires dans le chier C:\wamp\logs


\php_error.log.

LE GUIDE COMPLET 499

Chapitre 16

La gestion de la scurit

Figure 16.15 : Vos logs apparaissent au milieu dautres lignes derreur

Cette fonction est particulirement adapte pour signaler des comportements anormaux. Voyez des exemples dvnements pouvant tre loggs :
j j j

un chec rpt lors de lauthentication ; un internaute qui souhaite rgler un panier qui nexiste pas ; une erreur dans une requte SQL.
Fonction error_log() et dbogage

Lavantage de lutilisation de la fonction error_log() par rapport une simple fonction print() pendant une phase de dbogage est de ne pas entrer en conit avec les fonctions setcookie(), header() ou session_start(). En effet, lutilisation de print() avant ces fonctions entranerait laffichage dun message derreur. La fonction error_log() qui naffiche rien lcran, mais qui crit dans le chier de log, ne rencontre pas ce problme.

En plus du message, il peut tre intressant dajouter ladresse IP de linternaute qui est lorigine de lvnement.
error_log_test($_SERVER[REMOTE_ADDR]" : bizarre !");

Sil sagit dun applicatif o linternaute est identi, lajout de lidentiant la ligne de log est galement pertinent.

Les directives Apache


La prsence dun rpertoire contenant tous les chiers inclus (include()) est une situation extrmement courante. Nous avons
500 LE GUIDE COMPLET

Scuriser le serveur web

Chapitre 16

voqu, dans un chapitre prcdent, un moyen dviter lappel direct de ces chiers en les protgeant avec indentification.inc.php. Une solution moins portable, mais largement plus sre, consiste faire en sorte quApache refuse laccs direct ce rpertoire. Si vous souhaitez protger le rpertoire includes situ dans C:/wamp/www, la directive est la suivante :
<Directory "C:/wamp/www/includes"> order deny,allow deny from all </Directory>

Figure 16.16 : Message renvoy par Apache

Laccs direct aux chiers inclus est particulirement dangereux lorsque le dveloppeur utilise une extension non reconnue par Apache. Imaginez que le rpertoire includes contienne le chier de conguration gnral de lapplication : config.inc. Si Apache na pas t paramtr pour considrer les extensions *.inc comme des chiers PHP, vous obtenez ce rsultat catastrophique :

Figure 16.17 : Le chier include non protg

LE GUIDE COMPLET 501

Chapitre 16

La gestion de la scurit

Accs en clair

La recherche suivante "mysql filetype:inc" sur Google vous montre quel point il peut tre simple de dcouvrir les identiants et les mots de passe daccs une multitude de bases de donnes.

Il convient donc de vrier auprs de votre administrateur systme si lextension choisie pour les includes peut convenir.
Ajout dextensions dans Apache

La directive AddHandler permet de dnir les extensions des scripts PHP : AddHandler application/xhttpdphp .php .php3 .inc.

Il conviendra galement de vrier quaucun rpertoire sensible ne soit list. Apache permet en effet de lister lensemble des chiers contenus dans un rpertoire si ce rpertoire contient loption Indexes :
<Directory "C:/wamp/www/testindexes"> Options Indexes </Directory>

Figure 16.18 : Exemple de liste de chiers

Fichier index

La liste des chiers nest propose que si le rpertoire ne contient pas de chier index (par exemple index.html, index.htm, index.php, etc.). La liste de ces chiers peut tre modie dans le chier httpd.conf avec la directive DirectoryIndex.

502 LE GUIDE COMPLET

Les outils danalyse

Chapitre 16

Lajout des directives suivantes en bas du chier de conguration dApache (httpd.conf) permet dinterdire laccs au rpertoire testindexes :
<Directory "C:/wamp/www/testindexes"> Options -Indexes </Directory>

Figure 16.19 : Le rpertoire ne peut plus tre "list"

La scurit HTTPS
HTTPS correspond au protocole HTTP complt dune couche SSL (Secure Socket Layer) de cryptage des donnes. Cette protection est particulirement utile pour lutter contre les attaques de sniffing. Le sniffing peut tre rapproch dune coute des donnes transitant entre votre navigateur et le serveur web. Sans la couche SSL, ces mmes donnes circulent en clair sur le rseau. Lorsquil sagit dune page dinformations, le risque est inexistant. Lorsquil sagit en revanche dune authentication, votre identiant et votre mot de passe apparaissent en clair sur lcran du pirate. En congurant lextension SSL dApache (mod_ssl), vous vous assurez de lanonymat de vos changes. Cette technique se rvle superue dans 90 % des cas. Le point central du sniffing consiste pouvoir se brancher sur la liaison Internet de la cible. Or, ce nest possible que si lattaquant se trouve dans un rseau local, non loin de la machine cible.

16.4. Les outils danalyse


Compte tenu de limportance que prennent les applications web dans lconomie moderne, certains diteurs ont saut sur loccasion pour proposer des outils permettant de les auditer.

LE GUIDE COMPLET 503

Chapitre 16

La gestion de la scurit

Le logiciel Acunetix Web Vulnerability Scanner (www.acunetix.com/wvs) par exemple, permet partir dune simple adresse web, de tester les attaques sur des failles du langage, les injections SQL, les attaques de type XSS (Cross Site Scripting), les attaques concernant les passages de paramtres, les formulaires dauthentication (en veillant ce que les identiants et les mots de passe ne soient pas trop simples trouver), ainsi quune dizaine dautres attaques classiques.

Figure 16.20 : Exemple dinterface du logiciel Acunetix Web Vulnerability Scanner

16.5. Check-list
La scurit est un domaine complexe. Plusieurs rgles doivent systmatiquement rester votre esprit durant la phase de dveloppement :
j

j j

Les paramtres reus dans un script peuvent tre forcs par un utilisateur malicieux qui composerait sa propre Query String ou qui modierait ses cookies. Les paramtres reus dans un script doivent donc toujours tre vris avant dtre exploits. La vrication doit tre encore plus pousse lorsquil sagit de composer une requte SQL partir de paramtres. Il est important de logger les vnements tranges et incohrents qui ont lieu au sein de votre applicatif. Cela sera votre premire source dinformation en cas dattaque. Les rapports derreur doivent tre le plus complets possible durant la phase de dveloppement. Ils vous permettront notamment de dtecter les variables non initialises.

504 LE GUIDE COMPLET

Les trucs et astuces

PHP ....................................................................................................................................... 506 MySQL .................................................................................................................................. 523 HTML et Javascript ........................................................................................................... 525

Chapitre 17

Les trucs et astuces

Comme pour tout langage de programmation, il est possible avec lexprience damliorer et doptimiser son code. Ce chapitre va vous permettre de prsenter quelques fonctionnalits et syntaxes peu connues de PHP et de MySQL.

17.1. PHP
Dnir autrement une chane de caractres
Quand vous souhaitez dnir des chanes de caractres multilignes, il est courant dcrire ceci :
$machaine = "ligne1\n"; $machaine .= "ligne2\n"; $machaine .= "ligne3";

Une syntaxe alternative (trs proche de celle du Perl) est propose par PHP et peut se rvler plus lisible. Elle consiste englober les lignes entre des dlimiteurs, par exemple <<<EOS et EOS; :
$str = <<<EOS ligne1 ligne2 ligne3 EOS;

Le motif EOS nest pas obligatoire et peut tre remplac, par exemple par <<<END END;. Il faut cependant veiller conserver le mme motif pour louverture et la fermeture. La balise de fermeture doit imprativement tre isole sur une ligne. Il nest donc pas question dcrire ceci :
... ligne2 ligne3 EOS;

Le texte peut en revanche contenir des variables :


$x = 1; $y = 2; $str = <<<EOS liste des variables : - x = $x - y = $y EOS;

506 LE GUIDE COMPLET

PHP

Chapitre 17

Pour inclure dans le texte la valeur dun tableau, la syntaxe daccs llment du tableau est un peu particulire :
$tab = array("v1" => 3, "v2" => 4); $str = <<<EOS v1 = {$tab[v1]} v2 = {$tab[v2]} EOS;

Il nest pas indispensable de passer par une variable intermdiaire pour utiliser cette syntaxe, linstruction suivante est tout fait valide :
echo <<<EOS ligne1 ligne2 ligne3 EOS;

Cette syntaxe est extrmement pratique quand vous devez afficher un long texte contenant de nombreuses variables.
HTML brut et echo

Des tests ont montr quil ntait pas vraiment plus rapide dcrire du code HTML brut que de passer par un echo. Les deux syntaxes suivantes sont donc aussi rapides :
valeur de la variable x = <?php echo $x; ?> echo <<<EOS valeur de la variable x = $x EOS;

Cette notation est souvent qualie de here printing.

Raccourcir un if... else...


Il est possible, pour des if else trs courts, de remplacer la syntaxe standard par la suivante :
(instruction 1)?(instruction 2):(instruction 3);

Si la premire expression retourne true, cest la deuxime instruction qui est excute, sinon cest la troisime expression.
$x = 4; ($x > 5)? print "x ($x) est suprieur 5" : print "x ($x) est infrieur 5";
LE GUIDE COMPLET 507

Chapitre 17

Les trucs et astuces

Si vous aviez voulu utiliser la fonction echo, vous auriez pu crire :


$x = 4; echo ($x > 5)?"x ($x) est suprieur 5":"x ($x) est infrieur 5";

Lexemple suivant va permettre de prremplir une CHECKBOX en fonction de la valeur prise par une variable :
Listing 17-1 : prslection dune case cocher <?php $ln = "fr"; ?> <form> franais : <input type=radio <?php echo ($ln == "fr")?"checked=true":""; ?> name="fr" value="fr" /><br/> tranger : <input type=radio <?php echo ($ln != "fr")?"checked=true":""; ?> name="fr" /> </form>

Lautre syntaxe des structures de contrle


Il est courant davoir crire un code de ce type :
if ($reponse == "OK") { echo "le message a bien t envoy<br/>"; echo "merci de votre visite"; } else { echo "problme lors de lexcution<br/>"; echo "merci de recommencer"; }

Les blocs de code entre les if else ne contiennent que du texte brut. PHP propose une syntaxe alternative, plus lgante, pour parvenir au mme rsultat :
508 LE GUIDE COMPLET

PHP
Listing 17-2 : Les blocs HTML et PHP sont plus clairement spars <?php if ($reponse == "OK") : ?> le message a bien t envoy<br/> merci de votre visite <?php else: ?> problme lors de lexcution<br/> merci de recommencer <?php endif; ?>

Chapitre 17

La nouvelle syntaxe est donc la suivante :


if () : ... else () : ... endif;

Cette syntaxe est disponible pour les autres structures de contrle :


if() : ... elseif () : ... else () : ... endif; while () : ... endwhile; for () : ... endfor;

Raccourcir un simple bloc echo


Il est courant de devoir utiliser un bloc PHP uniquement pour afficher une variable :
<form action="<?php echo $_SERVER[PHP_SELF]; ?>">

PHP propose une syntaxe alternative pour y parvenir :


<?=$nom_variable?>

Cet exemple devient alors :


<form action="<?=$_SERVER[PHP_SELF]?>">

Pour afficher deux valeurs, vous pouvez crire :


<?php $x = 2; $y = 3; ?> Valeurs de x, y = <?="$x, $y"?>

Lavantage de cette syntaxe est donc de rduire votre code et de le rendre plus lisible. Plus un chier est court et plus vous pouvez
LE GUIDE COMPLET 509

Chapitre 17

Les trucs et astuces

rapidement en avoir un aperu densemble. Cette syntaxe permet galement de sparer plus clairement les zones de texte brut des zones de code. Cette syntaxe dpend de la directive de conguration short_open_tag prsente dans php.ini. Cette directive doit tre passe on pour permettre lutilisation de ces short tags. Les utilisateurs de Wamp Server devront notamment faire la modication.

Donner une valeur par dfaut un paramtre dune fonction


Nous avons vu que la syntaxe pour dclarer une fonction est la suivante :
function nom_fonction($param1,$parma2) { bloc_de_code; }

Il est possible de donner des valeurs par dfaut aux paramtres de la fonction en la dclarant ainsi :
function nom_fonction($param1 = "valeur_par_dfaut") { bloc_de_code; }

crivez une fonction affiche_retour() et appelez-la de deux faons diffrentes :


<?php function affiche_retour($url = "/") { echo "<a href=$url>retour</a><br/>"; } // version 1 : nous utilisons le paramtre par dfaut echo "merci de votre visite<br/>"; affiche_retour(); //version 2 : nous passons la valeur du paramtre echo "merci de votre visite<br/>"; affiche_retour("/"); ?>

510 LE GUIDE COMPLET

PHP

Chapitre 17

Attention, si la fonction possde plusieurs paramtres, seul le dernier pourra prendre une valeur par dfaut !
<?php function affiche_retour($url,$nomlien = "retour") { echo "<a href=$url>retour</a><br/>"; } //version 2 : valeur par dfaut pour le deuxime paramtre echo "merci de votre visite<br/>"; affiche_retour("/"); //version 2 : nous passons les valeurs des 2 paramtres echo "merci de votre visite<br/>"; affiche_retour("/","back"); ?>

Transmettre un nombre variable de paramtres une fonction


PHP propose un moyen de passer un nombre variable de paramtres une fonction. Deux fonctions doivent tre utilises pour y parvenir :
j j

func_num_args() : retourne le nombre darguments passs en

paramtres.
func_get_arg() : permet daccder par index chacun des

paramtres.
Listing 17-3 : affiche_param() peut recevoir un nombre indfini de paramtres <?php function affiche_param() { $nb_param = func_num_args(); for ($i=0;$i<$nb_param;$i++) { print("paramtre $i : " . func_get_arg($i) . "<hr>"); } } affiche_param("a",2,"e","i",6); ?>

LE GUIDE COMPLET 511

Chapitre 17

Les trucs et astuces

Figure 17.1 : Fonctions avec un nombre indni de paramtres

Utiliser un oprateur de comparaison de type


PHP rend la gestion des types des variables extrmement simple. trop simplier les choses cependant, le risque est parfois de commettre des erreurs. tudiez le code suivant :
Listing 17-4 : comparaison hasardeuse $x = 0; $y = false; if ($x == $y) echo "x et y sont gaux"; else echo "x et y sont diffrents";

Ce script va afficher "x et y sont gaux", bien que $x soit un numrique entier et $y un boolen. Cela peut convenir la plupart du temps, car PHP place souvent au mme niveau 1/true et 0/false. Ce comportement peut cependant devenir gnant quand 0 et false doivent reprsenter deux valeurs diffrentes. La fonction suivante retourne, par exemple, la conversion dun nombre de jours en secondes, et false en cas derreur :
function jour_sec($jour) { if ($jour < 0) { return false; } else {

512 LE GUIDE COMPLET

PHP
return $jour * 24 * 60 * 60; } }

Chapitre 17

Quand vous appelez la fonction avec la valeur 0, la valeur de retour est 0. Quand vous lappelez avec la valeur 12, cest la valeur false qui est cette fois retourne. Pour pouvoir faire la diffrence entre ces deux valeurs, PHP met votre disposition certains oprateurs de comparaison sur les types :
Tableau 17.1 : Oprateurs de comparaison sur les types

Oprateur

Rsultat

$a === $b $a !== $b

$a et $b sont gaux et de mme type $a et $b sont diffrents ou de types diffrents

Vous pouvez donc faire appel votre fonction de la manire suivante :


$nbsec = jour_sec(0); if ($nbsec === false) echo "le paramtre nest pas valide"; else echo "nombre de secondes : $nbsec";

Le script affiche ici "nombre de secondes : 0".

Les attributs __FILE__ et __LINE__


Au cours de lexcution dun script PHP, __FILE__ et __LINE__ contiennent en permanence le chemin du chier dans le lequel vous vous trouvez et le numro de ligne en cours.
Listing 17-5 : Utilisation de __FILE__ et __LINE__ <?php print("Bonjour vous vous trouvez dans le fichier <b>"); print(__FILE__); print("</b> la ligne <b>"); print(__LINE__); print("</b>."); ?>

Figure 17.2 :

Rsultat

LE GUIDE COMPLET 513

Chapitre 17

Les trucs et astuces

Les variables variables


Le nom dune variable peut tre lui-mme une variable. Si $a contient 1 et $b contient a, la variable variable $$b correspond en fait $a.
Listing 17-6 : $$b est une variable variable <?php $a = 1; $b = a; echo $$b; // affiche 1 ?>

Les oprateurs sur les tableaux


Tableau 17.2 : Oprateurs sur les tableaux

Oprateur

Rsultat Union de $a et de $b Renvoie true si $a et $b sont composs des mmes paires cl/valeur ; les tableaux sont alors dits gaux Comme ==, avec des vrications en plus sur lordre et le type des donnes ; les tableaux sont alors dits identiques Renvoie true si $a et $b ne sont pas gaux Renvoie true si $a et $b ne sont pas gaux Renvoie true si $a et $b ne sont pas identiques

$a + $b $a == $b

$a === $b

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

Loprateur dunion a cela de spcial que les cls qui seraient prsentes dans $a et $b ne sont pas rcrites.
$a = array("couleur1"=>"rouge","couleur2"=>"vert"); $b = array("couleur1"=>"jaune","noir","vert"); print_r($a+$b);

Figure 17.3 : Union de $a et $b

514 LE GUIDE COMPLET

PHP

Chapitre 17

Les techniques doptimisation en PHP


Loptimisation dun code ne doit jamais tre ralise au dtriment de sa clart et de sa lisibilit. Cette rgle est dautant plus vraie si vous dbutez en programmation ou si vous ne travaillez pas de manire isole sur le projet. Il est cependant utile de connatre quelques techniques doptimisation, surtout si votre projet ncessite une rapidit extrme, et quil doit tre utilis par un grand nombre de personnes. Un espace mmoire de 100 ko gaspill par un script peut en effet se transformer en plusieurs mgaoctets en cas dafflux important de visiteurs.

Limiter le nombre de variables


Si vous avez besoin de nombreuses variables temporaires et que celles-ci ne soient utilises que localement (pour une seule instruction, par exemple), essayez de conserver la mme variable tout au long du script. Une telle variable est souvent appele $tmp.
Listing 17-7 : Utilisation de deux variables temporaires : $heures et $minutes $jours = 10; $heures = 10 * $jours; echo "nombre de dheures : $heures"; $minutes = $heures * 60; echo "nombre de minutes : $minutes"; Listing 17-8 : Utilisation dune seule variable temporaire : $tmp $jours = 10; $tmp = 10 * $jours; echo "nombre de dheures : $tmp"; $tmp *= 60; echo "nombre de minutes : $tmp";

Vous avez vu quune bonne habitude en programmation consiste passer en variables un grand nombre de paramtres utiliss par vos scripts (notamment tous les paramtres susceptibles dtre modis lors dun changement dhbergeur). Il ne faut cependant pas tomber dans lexcs inverse et passer toutes les donnes (tous les paramtres) en

LE GUIDE COMPLET 515

Chapitre 17

Les trucs et astuces

variables. Une variable est en effet stocke en mmoire, et plus vous en avez dans votre code, plus celui-ci consomme de mmoire lors de son excution.

Utiliser les bons caractres


Quand une chane de caractres ne contient pas de variables, utilisez les simples primes :
$ch1 = bonjour; $ch2 = "valeur de ch1 : $ch1";

En fonctionnant ainsi, vous vitez linterprteur PHP dessayer de remplacer les variables par leur valeur et vous conomisez des ressources.

Limiter les requtes aux bases de donnes


Cest de loin loptimisation qui vous sera le plus utile. Supprimer une requte superue est largement plus important que toutes les optimisations syntaxiques imaginables. Une requte est en effet trs consommatrice en temps et en mmoire. Si vos requtes sont indispensables, essayez alors de les optimiser en utilisant des index sur vos tables ou en choisissant des critres de slection trs stricts. Spcier les colonnes utiles, plutt quun astrisque (*) dans un SELECT, est galement une excellente habitude prendre. Les jointures intelligentes et les requtes imbriques proposes par MySQL 5 permettent trs souvent de limiter le nombre requtes.

Les fonctions include() et require()


La fonction include() nest pas la seule permettre de faire appel des donnes contenues dans un chier extrieur. La fonction require() peut aussi tre utilise dans ce cas. La diffrence entre ces deux fonctions rside dans le fait que le code appel par require() est inclus dans tous les cas et nest excut quune fois.

516 LE GUIDE COMPLET

PHP

Chapitre 17

De ce fait, seule la fonction include() peut tre utilise dans une boucle :
Listing 17-9 : Le script test.php <?php for ($i=0;$i<=10;$i++) { $double = include("double.inc.php"); } ?> Listing 17-10 : Le script double.inc.php <?php return $i * 2; ?>

Lexemple prcdent prsente un autre avantage de la fonction include() sur la fonction require() : la possibilit de rcuprer dans le script appelant (test.php) une valeur retourne par le script appel (double.inc.php). Cette valeur de retour correspond la valeur retourne (return()) par le code inclus (retour qui a mis n, par ailleurs, lexcution de ce mme code). Les fonctions include() et require() peuvent faire appel un chier distant. Il est ainsi tout fait autoris dcrire ceci :
include("http://www.server.com/fonction.txt");

Le code PHP contenu dans le chier fonction.txt sera alors inclus dans le script (le code doit tre entour des balises <?php et ?>). Si en revanche vous faites appel un chier .php, ce nest pas le code que vous allez inclure dans votre script, mais le rsultat de linterprtation du code par le serveur HTTP distant. Si ce code fait appel des variables globales du serveur, le rsultat sera alors diffrent. Une autre fonction peut se rvler intressante : include_once(). Cette fonction permet de ninclure un chier quune fois et vite ainsi de provoquer des erreurs si le chier inclus se connecte une base ou cre un objet (dans ces deux cas, linterprteur indiquerait que la ressource existe dj).

LE GUIDE COMPLET 517

Chapitre 17

Les trucs et astuces

Laffichage tampon : output buffering


Loutput buffering est une technique qui permet de ne pas afficher directement les donnes lcran, mais plutt de les stocker temporairement dans un tampon intermdiaire (buffer). Trois fonctions sont utilises pour loutput buffering.
j j j

ob_start() : pour initialiser loutput buffering. ob_get_contents() : pour rcuprer le contenu du buffer dans

une variable.
ob_end_clean() : pour arrter loutput buffering et vider le buffer.

Considrez lexemple suivant :


<?php ob_start(); echo "toto"; $output = ob_get_contents(); ob_end_clean(); echo "titi"; echo $output; ?>

Ce script naffiche pas tototiti mais tititoto. Laffichage de toto a t fait dans le buffer, et ce buffer nest ensuite affich quaprs titi.
Entrelacement doutput buffering

Un ob_start() peut tre inclus au sein dun autre ob_start().

Si vous aviez utilis la commande readfile() entre ob_start() et ob_end_clean(), le contenu du chier aurait aussi t plac dans le buffer. Grce cette technique, il devient possible de prparer dans un buffer un contenu complexe provenant de sources multiples (chier, bases de donnes) et de nafficher le buffer que si toutes les oprations se sont bien droules. En fonctionnant ainsi, vous vitez de vous retrouver avec des erreurs en plein milieu de la page. Loutput buffering associ la lecture de chier distant peut aussi tre trs intressant pour la gestion de templates.
518 LE GUIDE COMPLET

PHP

Chapitre 17

Fin de bloc PHP


Lorsque votre script se termine par un bloc PHP, lultime balise de fermeture ?> devient facultative. Cette particularit a surtout lavantage dviter de provoquer une erreur lorsque linclusion dun chier se terminant par ?> prcde un appel une des fonctions suivantes : session_start(), header() ou setcookie(). Ces fonctions ne peuvent en aucun cas tre prcdes dun affichage. Or, si vous laissez ne serait-ce quun retour la ligne ou un espace derrire ?>, une erreur sera dclenche.

Le paramtre cach de break et continue


Le chapitre consacr la syntaxe avait prsent les instructions break et continue qui permettent, pour la premire, de stopper lexcution dune boucle et pour la seconde, de forcer le passage litration suivante. Dans le cadre de boucles imbriques, ces deux instructions peuvent prendre en paramtre une valeur numrique. Pour le break, cette valeur correspond au nombre de boucles qui seront arrtes et pour le continue, au nombre de boucles qui seront ignores.
Listing 17-11 : Exemple illustrant lutilisation dun paramtre avec break et continue $tab = array("a","b","c","d","e"); foreach ($tab as $lettre) { print("<br/> $lettre : "); for ($i=0;$i<=5;$i++) { if ($lettre=="a" && $i==1) if ($lettre=="b" && $i==1) if ($lettre=="c" && $i==2) if ($lettre=="d" && $i==2) print($i); } }

continue 1; continue 2; break 1; break 2;

Figure 17.4 : Break et continue

LE GUIDE COMPLET 519

Chapitre 17

Les trucs et astuces

Le fonctionnement de cet exemple et le suivant :


j j j j

si $lettre == a et $i == 1 : nous continuons dans la boucle for en ignorant uniquement laffichage de la valeur 1, si $lettre == b et $i == 1 : nous passons litration suivante de la boucle de niveau suprieur : foreach, si $lettre == c et $i == 2 : nous arrtons la boucle en cours : for, si $lettre == d et $i == 2 : nous arrtons la boucle au niveau suprieur : foreach et ne passons pas au traitement de la lettre "e".

Chane de caractres sous forme de tableau de caractres


Les chanes de caractres peuvent tre considres comme des tableaux scalaires. Le premier caractre ayant comme dhabitude lindice 0.
Listing 17-12 : Affichage de chacun des caractres de la chane $str $str = "Bonjour Mr Gueudet"; print("$str<hr/>"); $n = strlen($str); for ($i=0;$i<$n;$i++) { print("str[$i] = ".$str[$i]."<br/>"); }

Figure 17.5 : Rsultat de laffichage

520 LE GUIDE COMPLET

PHP

Chapitre 17

Rendre disponible un site wamp sur internet


Dans 99 % des cas, un site web fonctionnant avec Wamp ne sera pas accessible sur une autre machine. Pour rendre le site disponible, une modication doit tre ralise au niveau du chier de conguration dApache (httpd.conf). La ligne Allow from 127.0.0.1 doit tre remplace par Allow from all.

Figure 17.6 : Modication de la conguration dApache

Ce changement indique que toutes les machines (All) peuvent dsormais accder Apache et plus uniquement la machine sur laquelle est installe Wamp (127.0.0.1). Un redmarrage dApache doit tre ralis pour prendre en compte la modication. Pour accder au site web, une machine du rseau local devra utiliser ladresse IP de la machine (ex. http://192.168.0.2/test.php) plutt que localhost (http://localhost/test.php). Cette adresse IP peut tre trouve en tapant la commande ipconfig dans un terminal.

Figure 17.7 : Ladresse IP est ici 192.168.0.2

Ltape suivante consiste permettre des ordinateurs situs en dehors du rseau local daccder au site. Il convient pour cela de modier des paramtres au niveau de votre routeur. La Freebox permettra dillustrer ces interventions avec un cas concret.

LE GUIDE COMPLET 521

Chapitre 17

Les trucs et astuces

La premire tape consiste accder lespace Mon Compte du site www.free.fr. Une fois identi, la rubrique Fonctionnalits optionnelles de la Freebox permet de congurer le routeur (Fonction routeur). Lobjectif est alors de crer une redirection du port 80 (TCP) du routeur vers le port 80 de votre machine. L encore, lIP de votre machine (ex. 192.168.0.2) est ncessaire.

Figure 17.8 : Paramtrage dune redirection de port sur la Freebox

Cette redirection indique que tous les accs sur le port 80 de la Freebox sont automatiquement redirigs vers le port 80 de votre machine de travail. Le port 80 est en effet le port par dfaut utilis par Apache et plus gnralement pour le web.

Figure 17.9 : La conguration dApache indique bien que le port dcoute est 80

Cette modication doit tre suivie dun dbranchement de la Freebox an de la redmarrer. Tout est dsormais prt pour quun internaute lambda puisse accder votre site. La seule donne manquante est ladresse Internet de la Freebox. Cest en effet cette dernire qui permettra daccder au site. La rubrique Afficher mon Adresse IP permet de lobtenir. Si cette adresse est 82.239.58.1 un internaute pourra utiliser ladresse http://82.239.58.1 pour visualiser le site. Il est important de rappeler quen ouvrant le port 80 de cette manire, votre machine devient une proie potentielle pour un pirate. La prudence est donc de mise !

522 LE GUIDE COMPLET

MySQL

Chapitre 17

17.2. MySQL
Rcuprer un enregistrement de manire alatoire
Il est souvent trs utile de rcuprer une valeur alatoire dans une table. La premire solution consiste slectionner un grand nombre de valeurs, les placer dans un tableau au niveau de votre script et, enn, choisir un lment au hasard dans ce tableau :
Listing 17-13 : Passage par un tableau pour obtenir un lment alatoire <?php $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve"; $resultat = mysql_query ($sql); while ($eleve = mysql_fetch_array ($resultat)) { $tab[] = $eleve[nom]; } srand ((float) microtime() * 10000000); $randindex = array_rand ($tab); echo $tab[$randindex]; mysql_close($liendb); ?>

Une autre solution, plus pertinente, consiste demander MySQL de ne retourner quune valeur prise au hasard. Lide est de demander MySQL de prendre les enregistrements dans un ordre alatoire (ORDER BY rand()) et de nen slectionner quun (LIMIT 1) :
Listing 17-14 : Slection directe dun lment alatoire <?php $liendb = mysql_connect("localhost", "root", ""); mysql_select_db ("test"); $sql = "SELECT * FROM eleve ORDER BY rand() LIMIT 1"; $resultat = mysql_query ($sql); $eleve = mysql_fetch_array ($resultat);
LE GUIDE COMPLET 523

Chapitre 17

Les trucs et astuces

echo $eleve[nom]; mysql_close($liendb); ?>

Anciennes versions de MySQL

Avec des versions anciennes de MySQL (infrieures la version 3.23), vous ne pouvez utiliser que la premire solution, la syntaxe ORDER BY rand() ntant pas valide avant.

Optimiser ses tables


Il est courant, en cours de dveloppement, dapporter des modications (ALTER TABLE) la structure de ses tables. Bien que ces modications soient parfaitement gres par MySQL, elles peuvent entraner un lger ralentissement des requtes utilisant ces mmes tables. MySQL propose la commande OPTIMIZE TABLE nom_table pour restructurer ses donnes. Cette commande peut aussi tre utilise sur des tables subissant des suppressions (massives) denregistrements. Dans ce cas, elle rcupre lespace perdu et dfragmente le chier de donnes. Un appel OPTIMIZE TABLE entrane galement un tri des pages dindex, ce qui ne fait jamais de mal. Ces fonctions avances (REPAIR TABLE, CHECK TABLE, ANALYSE TABLE, OPTIMIZE TABLE) peuvent tre appeles depuis phpMyAdmin.

Figure 17.10 : Fonctions avances dans phpMyAdmin

524 LE GUIDE COMPLET

HTML et Javascript

Chapitre 17

Autres optimisations
Une table ne contenant que des colonnes de type numrique (INT, TINYINT, FLOAT) et des colonnes de types CHAR ou DATE prsente une structure dite statique. Cette structure lui permet dtre largement plus rapide sur la gestion des index et sur les recherches. La prsence dune seule colonne TEXT, BLOB ou VARCHAR la fera passer en structure dynamique. La taille dun CHAR tant limite 255, il nest pas toujours possible dobtenir une structure statique de table. Diviser une table en plusieurs sous-tables, sous prtexte que cette dernire commence contenir beaucoup de colonnes, est gnralement une mauvaise ide. La recherche de donnes sur le disque dur est en effet lopration la plus longue. En divisant votre table, le SGBD est oblig de rechercher sur le disque les emplacements o se trouvent les sous-tables.

17.3. HTML et Javascript


Empcher lautocompltion
Une fonctionnalit trs pratique propose par les derniers navigateurs est lautocompltion dans les formulaires (autocomplete). Cette autocompltion permet linternaute de ne pas avoir retaper une information quil a dj prcise dans le pass. Dans lexemple suivant, linternaute a entr une premire fois son adresse e-mail : bob@mail.com. En revenant sur le site, cette adresse lui est directement propose :

Figure 17.11 : Lautocompltion

LE GUIDE COMPLET 525

Chapitre 17

Les trucs et astuces

Ce comportement peut cependant tre trs gnant quand vous passez par un formulaire pour demander linternaute de sidentier. Si lordinateur en question est accessible dautres personnes, ces dernires pourront didentier juste en tirant parti de lautocompltion. Il est donc important pour des champs sensibles de dsactiver cette fonctionnalit. Il suffit, pour cela, de mettre la proprit autocomplete off dans lINPUT TEXT :
<input type="text" name="login" autocomplete="off" />

Dnir le rafrachissement automatique dune page


Il peut tre utile davoir rafrachir votre page rgulirement (pour des pages de chat, dinformations en continue). HTML propose une balise META spciale : META HTTPEQUIV="Refresh". Cette balise META permet de prciser la frquence des rafrachissements et lURL de destination :
Listing 17-15 : Au bout dune minute, nous retombons sur la page daccueil <META HTTP-EQUIV="Refresh" CONTENT="60;URL=/">

Le script suivant affiche lheure toutes les 5 secondes :


<html> <head> <META HTTP-EQUIV="Refresh" CONTENT="5;URL=<?php echo $_SERVER[PHP_SELF]; ?>"> </head> <body> <h1><?php echo date("Y-m-d G:i:s"); ?></h1> </body> </html>

Problmatique des frames

Il est impossible, en utilisant cette technique, de prciser une frame de destination. Pour y parvenir, vous tes oblig de passer par une page intermdiaire contenant du Javascript.

526 LE GUIDE COMPLET

Les fonctions PHP

Les fonctions mathmatiques ........................................................................................ 529 Les chanes de caractres ............................................................................................... 538 Les expressions rgulires .............................................................................................. 559 Les tableaux ........................................................................................................................ 561 Les fonctions de dates et dheures ............................................................................... 583 Les fichiers et les rpertoires .......................................................................................... 588 Linterface avec MySQL ................................................................................................... 611 Les images .......................................................................................................................... 622 Les variables ....................................................................................................................... 638 La configuration PHP ........................................................................................................ 642 Fonctions diverses ............................................................................................................ 645

Chapitre 18

Les fonctions PHP

Comme tous les nouveaux langages de haut niveau (C, C++, Java, C#, etc.), PHP est fourni par dfaut avec un grand nombre de fonctionnalits. Cette bibliothque de fonctions peut tre assimile la librairie standard dun langage de programmation (la libc pour le C, par exemple). Quel que soit lendroit du script o vous vous trouvez, quel que soit linterprteur PHP utilis, il vous est notamment possible dappeler des fonctions de manipulation de nombres, de chanes de caractres, de tableaux, etc. En plus de ces fonctions fondamentales, il est galement possible de faire appel des fonctions plus exotiques , qui permettent, par exemple, de grer des bases de donnes, dutiliser le protocole FTP, de gnrer des images ou des chiers .pdf. Ce sont ainsi plusieurs dizaines dextensions (aussi appeles modules ou librairies ) qui sont venues se greffer PHP au cours du temps. La fonction phpinfo()permet dobtenir la liste des modules disponibles ainsi que leur version.

Figure 18.1 : La distribution PHP contient notamment des modules de gnration dimages (GD) et de gestion de protocole FTP

528 LE GUIDE COMPLET

Les fonctions mathmatiques

Chapitre 18

Dans ce chapitre, nous nous intresserons particulirement aux fonctions permettant :


j j j j j j j j j

le traitement des variables numriques ; le traitement des variables de type chane de caractres ; la manipulation des expressions rgulires ; le traitement des tableaux et des tables de hachage (tableaux associatifs) ; la manipulation des dates et des heures ; la manipulation des chiers et des rpertoires ; la gestion des bases de donnes MySQL ; la gnration dimages ; la manipulation des variables.

La liste des fonctions prsentes ici nest pas exhaustive, mais elle permet de rpondre 95 % des besoins dun programmeur PHP. Pour certaines fonctions, le nombre de paramtres peut tre variable. Ces paramtres optionnels seront alors nots entre crochets de la manire suivante : ma_fonction($param1[, $param2]). La fonction ma_fonction() peut prendre un ou deux paramtres. Une telle description dune fonction est appele signature dune fonction . Il est aussi possible de trouver des fonctions prenant par exemple un ou trois paramtres. La notation sera alors : ma_fonction($param1[, $param2, $param3]). Nous prciserons galement partir de quelle version de PHP ces fonctions sont disponibles.

18.1. Les fonctions mathmatiques


Il existe, au sein du langage PHP, des donnes particulires dont la valeur ne peut tre modie dans le script : ces donnes sont appeles constantes . Il existe un certain nombre de constantes mathmatiques qui peuvent tre utilises dans un script PHP.

LE GUIDE COMPLET 529

Chapitre 18

Les fonctions PHP


Tableau 18.1 : Les constantes numriques

Constante

Valeur 3.14159265358979323846 2.7182818284590452354 1.4426950408889634074 0.43429448190325182765 0.69314718055994530942 2.30258509299404568402 1.57079632679489661923 0.78539816339744830962 0.31830988618379067154 0.63661977236758134308 1.77245385090551602729 1.12837916709551257390 1.41421356237309504880 1.73205080756887729352 0.70710678118654752440 1.14472988584940017414 0.57721566490153286061

Description pi e log_2 e log_10 e log_e 2 log_e 10 pi/2 pi/4 1/pi 2/pi sqrt(pi) [4.0.2] 2/sqrt(pi) sqrt(2) sqrt(3) [4.0.2] 1/sqrt(2) log_e(pi) [4.0.2] Euler constant [4.0.2]

M_PI M_E M_LOG2E M_LOG10E M_LN2 M_LN10 M_PI_2 M_PI_4 M_1_PI M_2_PI M_SQRTPI M_2_SQRTPI M_SQRT2 M_SQRT3 M_SQRT1_2 M_LNPI M_EULER

Exemple dutilisation de constantes :


$x = M_E * 4; print(M_PI); // affiche 3.1415926535898

abs()
j j

Signature : abs ($x). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la valeur absolue dun nombre, quel quil soit :
print(abs(-12)); // affiche 12 print(abs(-2.12)); // affiche 2.12

530 LE GUIDE COMPLET

Les fonctions mathmatiques

Chapitre 18

base_convert()
j j

Signature : base_convert ($x, $bo, $ba). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction convertit une valeur $x dune base ($bo) dans une autre ($ba). Les valeurs de bases sont comprises entre 2 et 36 :
print(base_convert(13,10,2)); // conversion de la valeur 13 de la base dcimale (10) dans // la base binaire la valeur affiche est : 1101 print(base_convert("CC",16,10)); // affiche 204 // lquivalent dcimal de la couleur HTML #CCCCCC (gris) // est donc (204,204,204)

bindec()
j j

Signature : bindec ($ch). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction convertit en une valeur dcimale une chane de caractres reprsentant une valeur code en binaire. La plus grande valeur dcimale que lon puisse atteindre est 2 147 483 647 :
print(bindec("1101")); // affiche 13

ceil()
j j

Signature : ceil ($x). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne lentier suprieur :


print(ceil(4.25)); // affiche 5 print(ceil(4.9)); // affiche 5 print(ceil(-2.45)); // affiche -2

cos()
j j

Signature : cos ($x). Versions : PHP 3, PHP 4, PHP 5.

LE GUIDE COMPLET 531

Chapitre 18

Les fonctions PHP

Cette fonction retourne le cosinus de la valeur $x (en radians) :


print(cos(M_PI)); // affiche -1

Dautres fonctions trigonomtriques sont disponibles : acos(), acosh(), asin(), asinh() , atan(), atanh(), atan2(), sin(), sinh(), tan(), tanh().

decbin()
j j

Signature : decbin ($x). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la valeur convertie en binaire dune valeur dcimale $x :


print(decbin(2)); // affiche 10 en effet : 2 = 1 * 2^1 + 0 * 2^0

dechex()
j j

Signature : dechex ($x). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la valeur convertie en hexadcimal (base 16) dune valeur dcimale $x :
print(dechex(204)); // affiche cc

decoct()
j j

Signature : decoct ($x). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la valeur octale (base 8) dune valeur dcimale


$x :
print(decoct(12)); // affiche 14

deg2rad()
j j

Signature : deg2rad ($x). Versions : PHP 3 partir de la 3.0.4, PHP 4, PHP 5.

532 LE GUIDE COMPLET

Les fonctions mathmatiques

Chapitre 18

Cette fonction convertit des degrs en radians :


print(deg2rad(45)); // affiche 0.78539816339745

Linverse est ralis par la fonction rad2deg() :


print(rad2deg(M_PI)); // affiche 180

exp()
j j

Signature : exp ($n). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la puissance $n de la constante e :


print(exp(2)); // affiche 7.3890560989307

oor()
j j

Signature : floor ($x). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne lentier infrieur :


print(floor(4.25)); // affiche 4 print(floor(-2.45)); // affiche -3

getrandmax()
j j

Signature : getrandmax () Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la valeur alatoire la plus grande qui puisse tre gnre sur le systme qui interprte votre script :
print(getrandmax()); // affiche 2147483647 sur un PC sous Linux

Cette valeur dpend essentiellement de larchitecture de votre ordinateur (PC, Mac).

hexdec()
j j

Signature : hexdec ($x). Versions : PHP 3, PHP 4, PHP 5.

LE GUIDE COMPLET 533

Chapitre 18

Les fonctions PHP

Cette fonction convertit une valeur hexadcimale en valeur dcimale :


print(hexdec("A")); // affiche 10

log()
j j

Signature : log ($x). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le logarithme dune variable :


print(log(M_E)); // affiche 1

log10()
j j

Signature : log10 ($x). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le logarithme dcimal dune variable :


print(log10(M_E)); // affiche 0.43429448190325

max()
j j

Signature : max ($x1 [, $x2]). Versions : PHP 3, PHP 4, PHP 5.

La fonction max() peut avoir deux types darguments.


j j

Un tableau : il retourne alors la valeur la plus grande du tableau. Deux nombres : il retourne alors le plus grand.

$tab = array (10,-2,4,2); print(max($tab)); // affiche 10 print(max(3,5,2)); // affiche 5

Si une des valeurs au moins est un nombre ottant (float), la valeur retourne sera un nombre ottant. La fonction inverse de max() est la fonction min() : elle fonctionne exactement sur le mme modle.

534 LE GUIDE COMPLET

Les fonctions mathmatiques

Chapitre 18

mt_rand()
j j

Signature : mt_rand ([$min, $max]). Versions : PHP 3 partir de la 3.0.6, PHP 4, PHP 5.

Cette fonction permet de gnrer des nombres alatoires de meilleure qualit , et quatre fois plus rapidement quavec la fonction standard rand(). Si les valeurs optionnelles $min et $max ne sont pas prcises, la valeur alatoire sera comprise entre 0 et RAND_MAX, sinon entre $min et $max. La fonction mt_srand(), qui initialise le gnrateur de nombres alatoires, doit tre excute avant que mt_rand() soit utilise :
mt_srand ((float) microtime() * 1000000); // initialisation du gnrateur de nombres alatoires print(mt_rand(10,15)); // affiche, par exemple, 14

number_format()
j j

Signature : number_format ($x [, $dec [, $chdec , $chmille]]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne une chane de caractres correspondant au nombre $x format suivant certains paramtres. La fonction number_format() peut prendre plusieurs paramtres
j

Un paramtre : un chiffre. Il place alors une virgule entre les milliers, et les dcimales ne sont pas prises en compte.
print(number_format(1234567890)); // affiche 1,234,567,890 print(number_format(1234567890.234)); // affiche 1,234,567,890

Deux paramtres : un chiffre et le nombre de dcimales afficher. Il place alors une virgule entre les milliers du nombre, et un point devant les dcimales.
print(number_format(1234.987654321,5)); // affiche 1,234.98765

LE GUIDE COMPLET 535

Chapitre 18
j

Les fonctions PHP

Quatre paramtres. Les deux derniers paramtres permettent de modier les caractres de sparation des dcimales et des milliers.
print(number_format(1234.987654321,5,"#","/")); // affiche 1/234#98765

Cette fonction est extrmement pratique pour afficher les nombres suivant les normes des pays :
$n = 12345.60; // affichage la franaise print(number_format($n, 2, ,, )); // affiche 12 345,60 // affichage langlaise print(number_format($n,2)); // affiche 12,345.60

octdec()
j j

Signature : octdec ($x). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction convertit une valeur octale en valeur dcimale :


print(octdec(17)); // affiche 15

pi()
j j

Signature : pi () Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la valeur de pi :


print(pi()); // affiche 3.1415926535898

pow()
j j

Signature : pow ($x,$y). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la puissance $y du nombre $x. Les valeurs $x et $y peuvent tre des nombres ottants :
print(pow(4,2)); // affiche 16

536 LE GUIDE COMPLET

Les fonctions mathmatiques


print(pow(4,0.5)); // affiche 2, il sagit de la racine carre

Chapitre 18

rand()
j j

Signature : rand ([$min, $max]). Versions : PHP 3, PHP 4, PHP 5.

Sans paramtre, cette fonction retourne une valeur alatoire. Avec deux paramtres, $min et $max, elle retourne une valeur alatoire comprise entre ces deux valeurs. Avant dutiliser cette fonction, il est ncessaire dutiliser la fonction
srand() an dinitialiser le gnrateur de nombres alatoires :
srand ((double) microtime() * 1000000); print(rand()); // affiche une valeur alatoire print(rand(3,15)); // affiche une valeur alatoire entre 3 et 15

round()
j j

Signature : round ($x [, $precision]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction arrondit un nombre ottant. La prcision peut tre passe en paramtre :
print(round("10.1")); // affiche : 10 print(round("10.6")); // affiche : 11 print(round("10.129",2)); // affiche : 10.13

srand()
j j

Signature : srand ($seed). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dinitialiser le gnrateur de nombres alatoires. Pour que le hasard soit maximal, il est prfrable de nappeler cette fonction quune fois dans le script.

LE GUIDE COMPLET 537

Chapitre 18

Les fonctions PHP

La valeur (double)microtime()*1000000 est trs courante pour le paramtre $seed. Voyez aussi la fonction rand() pour la gnration effective de nombres alatoires, et les fonctions mt_rand() et mt_srand() comme des alternatives suprieures rand() et srand().

sqrt()
j j

Signature : sqrt ($x). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la racine carre dun nombre :


print(sqrt(121)); // affiche : 11

18.2. Les chanes de caractres


Nous allons nous intresser, dans cette partie, aux fonctions concernant les chanes de caractres. En informatique, une chane de caractres est gnralement appele une string. Nous utiliserons donc rgulirement le paramtre $str quand nous voudrons faire rfrence une variable de type chane de caractres.

addslashes()
j j

Signature : addslashes ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction ajoute des barres obliques inverses (antislashs) devant les caractres (, ", \, NUL) de la chane $str :
print(addslashes("bonjour\"monde")); // affiche bon\jour\"monde

bin2hex()
j j

Signature : bin2hex ($str). Versions : PHP 3 partir de la 3.0.9, PHP 4, PHP 5.

538 LE GUIDE COMPLET

Les chanes de caractres

Chapitre 18

Cette fonction convertit des donnes binaires dans leur reprsentation hexadcimale (le bit de poids fort en premier).

chop()
j j

Signature : chop ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la chane sans les blancs de n de ligne. On regroupe, parmi les caractres dits blancs : les espaces, les tabulations (\t), les sauts de ligne (\n), les retours chariot (\n \r) et le caractre nul (\0) :
$str = " bonjour monde print("|" . $str . "|"); // affiche | bonjour monde print("|" . chop($str) . "|"); // affiche | bonjour monde| ";

chr()
j j

Signature : chr ($n). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le caractre ayant pour code ASCII $n :


print(chr(169)); // affiche : R

chunk_split()
j j

Signature : chunk_split ($str [, $n [, $sep ]]). Versions : PHP 3 partir de la 3.0.6, PHP 4, PHP 5.

Cette fonction dcoupe une chane $str en plusieurs morceaux, de taille $n, spars par la chane $sep :
print(chunk_split("abcde",2,"--<br>")); /* affiche : ab-cd-e-*/

LE GUIDE COMPLET 539

Chapitre 18

Les fonctions PHP

print(chunk_split("0921310571",2); // affiche : 09 21 31 05 71 // pratique pour afficher un numro de tlphone

Si seul le paramtre $str est fourni, $n a pour valeur par dfaut 76 et $sep (\r\n). titre dinformation, la valeur 76 reprsente le nombre maximal de caractres conseill par ligne pour le corps dun e-mail.

count_chars()
j j

Signature : count_chars ($str, $mode). Versions : PHP 4, PHP 5.

Cette fonction permet dobtenir des informations sur les caractres contenus dans $sr. Les modes 1 et 3 sont particulirement intressants.
j

Mode 1 : la fonction retourne un tableau avec comme cl le code ASCII du caractre et comme valeur le nombre doccurrences de ce caractre dans $str.
$tab = count_chars("azeerrrty",1); while (list ($clef, $val) = each ($tab)) { print("$clef : " . chr($clef) . " : [$val]<br>"); } /* affiche : 97 : a : [1] 101 : e : [2] 114 : r : [3] 116 : t : [1] 121 : y : [1] 122 : z : [1] */

Mode 3 : la fonction retourne une chane de caractres contenant tous les caractres diffrents prsents dans $str.
print(count_chars("azeerrrty",3)); // affiche : aertyz

crc32()
j j

Signature : crc32 ($str). Versions : PHP 4, PHP5.

540 LE GUIDE COMPLET

Les chanes de caractres

Chapitre 18

Cette fonction calcule le code redondance cyclique dune chane. titre dinformation, les valeurs utilises dans lalgorithme sont 0xEDB88320 et 0xFFFFFFFF.

crypt()
j j

Signature : crypt ($str [, $salt ]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction crypte la chane $str en utilisant lalgorithme DES.


La fonction uncrypt()

Cette fonction est sens unique. La fonction uncrypt() nexiste pas (et nest pas prs dexister !).

echo()
j

Signature : echo ($str1 [, $str2]).

Cette fonction permet dafficher une ou plusieurs chanes de caractres :


$a = "toto"; $b = "titi"; echo $a, "-", "$b"; // affiche : toto-titi echo ($i > 5) ? "i suprieur 5" : "i infrieur ou gal 5"; // affiche : i infrieur ou gal 5

Le paramtre echo simpli

Les deux lignes suivantes sont quivalentes :


bonjour <?php echo "monde"; ?> bonjour <?="monde"?>

explode()
j j

Signature : explode ($sep, $str [, $limite]). Versions : PHP 3, PHP 4, PHP 5.

LE GUIDE COMPLET 541

Chapitre 18

Les fonctions PHP

Cette fonction retourne un tableau contenant les diffrentes parties de la chane de caractres $str spares par la chane de caractres $sep :
$tab = explode("_","bonjour_monde"); print($tab[1]); // affiche : monde $tab = explode(";;","a;;b;;c;;;d"); print_r($tab); /* affiche Array ( [0] => a [1] => b [2] => c [3] => ;d ) */

Si le paramtre $limite est transmis, le tableau contiendra le plus grand nombre dlments $limite, le dernier contenant le reste de la chane :
$tab = explode(";;","a;;b;;c;;;d",2); print_r($tab); /* affiche Array ( [0] => a [1] => b;;c;;;d ) */

get_meta_tags()
j j

Signature : get_meta_tags ($fichier). Versions : PHP 3 partir de la 3.0.4, PHP 4, PHP 5.

Cette fonction retourne un tableau associatif contenant les mtabalises du chier $fichier. La variable $fichier peut contenir une URL :
$tab = get_meta_tags ("http://www.lemonde.fr"); foreach ($tab as $nom => $valeur) { print("$nom => $valeur<br>"); } /* affiche robots => INDEX,FOLLOW,NOARCHIVE description => LE MONDE, Journal Le Monde, quotidien dinformation francophone / Le Monde, the french quality newspaper of record

542 LE GUIDE COMPLET

Les chanes de caractres

Chapitre 18

keywords => LE MONDE, INFORMATIONS, INFOS, QUOTIDIEN, DAILY NEWS, PRESSE, PRESS, etc. */

htmlentities()
j j

Signature : htmlentities ($str [, $mode ]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction convertit certains caractres spciaux dune chane qui ont un quivalent en HTML. Ainsi, le caractre & peut tre reprsent en HTML par & :
$str = "< bonjour cest lt & il fait trs beau >"; print(htmlentities($str));

Cet exemple affiche bien "< bonjour cest lt & il fait trs beau >". Cependant, en regardant les sources de la page, on saperoit que la chane de caractres est devenue :
"< bonjour cest lt & il fait trs beau >"

Il est possible de passer un deuxime paramtre pour prciser comment les guillemets doivent tre traits. Ce paramtre est une des constantes suivantes
j j j

ENT_COMPAT : seuls les guillemets sont convertis en . ENT_QUOTES : primes et guillemets sont convertis. ENT_NOQUOTES : aucune conversion des guillemets nest ralise.

Cette fonction peut tre trs utile si vous voulez afficher un texte qui soit compatible avec le plus grand nombre de navigateurs. En effet, les vieilles gnrations de navigateurs avaient, par exemple, des problmes pour afficher un caractre accentu qui navait pas t converti. Il existe une fonction similaire, htmlspecialchars(), qui ne convertit quun certain nombre de caractres : &, , ", <, >.

implode()
j j

Signature : implode ($s, $tab). Versions : PHP 3, PHP 4, PHP 5.

LE GUIDE COMPLET 543

Chapitre 18

Les fonctions PHP

Fonction inverse de explode(), elle permet de runir tous les lments dun tableau dans une chane en les joignant avec la chane de caractres $s :
$tab = array("www","kernix","com"); print(implode(".",$tab)); // affiche www.kernix.com

Il existe une fonction parfaitement identique implode() : join().

md5()
j j

Signature : md5 ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction crypte la chane $str en utilisant lalgorithme MD5.

nl2br()
j j

Signature : nl2br ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction convertit les sauts de ligne texte dune chane en saut de ligne HTML : <br/>. Il sagit de <br/> et non de <br>, car le Web va de plus en plus sorienter vers le langage XHTML (plus proche du XML) o les balises orphelines doivent tre fermes .
Balises orphelines

On entend par balises orphelines , les balises qui nont pas besoin dtre fermes : <hr> <input> <img>).
print(nl2br("bonjour\nmonde")); /* affiche : bonjour<br /> monde */

ord()
j j

Signature : ord ($str). Versions : PHP 3, PHP 4, PHP 5.

544 LE GUIDE COMPLET

Les chanes de caractres

Chapitre 18

Cette fonction retourne la valeur ASCII du premier caractre de la chane de caractres $str :
print(ord("(c) copyright FCB")); // affiche : 169

parse_str()
j j

Signature : parse_str ($str [, $tab]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction cre les variables contenues dans la query string $str et les initialise leur valeur :
$str = "val1=bonjour+monde&val2=coucou"; parse_str($str); echo $val1, " - ", $val2; // affiche : bonjour monde - coucou

Il est aussi possible de passer un tableau en deuxime paramtre :


$str = "val1=bonjour+monde&val2=coucou"; parse_str($str,$tab); print($tab["val2"]); // affiche : coucou

print()
j j

Signature : print ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction affiche la variable :


$v = bonjour; print("$v monde"); // affiche : bonjour monde print "bonjour"; // affiche : bonjour

printf()
j j

Signature : printf ($format [, $param1, $param2]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dafficher une chane de caractres mise en forme .

LE GUIDE COMPLET 545

Chapitre 18

Les fonctions PHP

Le premier paramtre correspond la chane de caractres de mise en forme : le format. Il peut tre suivi dun ou de plusieurs paramtres qui seront les donnes utilises lors de laffichage :
$nom = "Fred"; printf("Bonjour %s",$nom); // affiche : Bonjour Fred

La chane "Bonjour %s" reprsente le format et %s indique quune chane de caractres va tre place cet endroit. Il existe dautres squences de formatage que %s :
j j j j j j j j

%% affiche un %. %c affiche la valeur ASCII dun nombre. %d affiche un entier. %f affiche une valeur dcimale virgule. %o affiche une valeur dcimale en octal. %b affiche une valeur dcimale en binaire. %x affiche une valeur dcimale en hexadcimal (les lettres sont en

minuscules). %X affiche une valeur dcimale en hexadcimal (les lettres sont en majuscules).
$nom = "Bob"; $annee = 2001; $taux = "12.5"; printf("%c %d %d, %s possde %f %% du capital",169,2000,$annee,$nom,$taux); // affiche : R 2000 2001, Bob possde 12.500000 % du capital printf("dcimal[%d] binaire [%b] - octal[%o] hexadcimal[%x]",29,29,29,29); // affiche : dcimal[29] - binaire [11101] octal[35] // hexadcimal[1d]

Les paramtres suivant la chane de formatage ($format) doivent donc tre dans le mme ordre que les squences de formatage. Vous vous apercevez, dans le premier exemple, que la valeur 12.5 est affiche avec cinq zros. Il savre que la squence de formatage %f peut tre modie pour afficher un nombre exactement comme on le souhaite : %.2f va, par exemple, afficher un nombre ottant avec deux chiffres aprs la virgule.
546 LE GUIDE COMPLET

Les chanes de caractres

Chapitre 18

printf("prix en francs : %.2f FF, sold %.2f FF",132.569,112.1); // affiche : prix en francs : 132.57 FF, sold 112.10 FF

Sil y a lieu, les dcimales sont compltes avec des 0. Il est aussi possible de formater un nombre sur une certaine longueur :
printf("rfrence %05d",13); // affiche : rfrence 00013

La fonction sprintf() est similaire printf(), sauf quelle naffiche pas le rsultat, mais retourne la chane formate.
$val = sprintf("%.2f",12.1); echo "prix = $val FF"; // affiche : prix = 12.100 FF

quotemeta()
j j

Signature : quotemeta ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction ajoute des barres obliques inverses devant les caractres suivants : ., \, +, *, ?, [, ^, ], (, $, ).
print(quotemeta("+*(")); // affiche : \+\*\(

sscanf()
j j

Signature : sscanf ($str, $format, [$var1, $var2]). Versions : PHP 4 partir de la 4.0.1, PHP 5.

Cette fonction permet de lire une chane de caractres et den extraire les diffrentes valeurs grce une chane de formatage similaire celle de printf() :
$naissance = "11/03/1977"; $tab = sscanf($naissance,"%d/%d/%d"); print("anne de la naissance : " . $tab[2]); // affiche : 1977 $ligne = "PRIX|2134.3000 REFERENCE|bzr0145"; list ($prix,$ref) = sscanf($ligne,"PRIX|%f REFERENCE|%s"); print("prix du produit [$ref] : $prix FF"); // affiche : prix du produit [bzr0145] : 2134.3 FF

LE GUIDE COMPLET 547

Chapitre 18

Les fonctions PHP

Si les paramtres $var1, $var2, etc., sont transmis, la fonction assigne ces variables et retourne le nombre de variables qui ont t assignes. Ces paramtres optionnels doivent tre passs par rfrence :
$naissance = "11/03/1977"; echo sscanf($naissance,"%d/%d/%d",&$jour,&$mois,&$annee); // affiche 3 echo "anne = $annee"; // affiche : anne = 1977

strcmp()
j j

Signature : strcmp ($str1, $str2). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction compare deux chanes de caractres et retourne :


j j j

une valeur ngative si $str1 est infrieure $str2 ; une valeur positive si $str1 est suprieure $str2 ; 0 si elles sont gales.

Attention, ce ne sont pas les longueurs des chanes qui sont compares, mais les caractres quelles contiennent ! Si vous voulez comparer les chanes "abcxwtr" et "ac", lalgorithme effectue ceci :
j j

Premier caractre : a = a. Deuxime caractre : c > b.

Lalgorithme sarrte alors et dclare que la chane "ac" est suprieure "abcxwtr". Les comparaisons se font donc sur les valeurs (codes) ASCII des caractres. Or, dans la table ASCII, lordre est tabli ainsi : 0 < 9 < A < Z < a < z.
$str1 = "aa"; $str2 = "b"; $n = strcmp($str1,$str2); if ($n < 0) print("str1 < str2"); elseif ($n > 0) print("str1 > str2"); else print("str1 = str2"); // affiche : str1 < str2

548 LE GUIDE COMPLET

Les chanes de caractres

Chapitre 18

Si seule lgalit vous intresse, il est souvent plus simple dutiliser loprateur de comparaison == :
$str1 = "hello"; if ($str1 == "hello") print("OK"); else print("KO"); // affiche : OK

Dans les deux exemples prcdents, les chanes "bonjour" et "BonJour" ne seraient pas identiques, car les comparaisons sont sensibles la diffrence majuscules/minuscules (les comparaisons sont dites case sensitive). La fonction strcasecmp() peut tre utilise si vous ne voulez pas vous soucier de la diffrence majuscules/minuscules :
$str1 = "HELLO"; if (strcasecmp($str1,"hello") == 0) print("OK"); else print("KO"); // affiche : OK

Il est aussi possible de limiter les portions de chanes comparer avec les fonctions strncmp() ou strncasecmp() :
if (strncasecmp("HELIOS","hello",3) == 0) print("OK"); else print("KO"); // affiche : OK

La comparaison sest faite ici sur les trois premiers caractres et de manire insensitive. Avec ces types de fonctions, la chane "image2" est suprieure "image10". Or, il est souvent utile pour classer des images ou des chiers de faire en sorte davoir "image1" < "image2" < "image12" < "image21". Il faut, pour cela, utiliser un algorithme de comparaison dit naturel. Deux fonctions implmentent cet algorithme : strnatcmp() et strnatcasecmp(). Pour classer un tableau en utilisant cet ordre, la fonction natsort() peut tre utilise.

strcspn()
j j

Signature : strcspn ($str1, $str2). Versions : PHP 3 partir de la 3.0.3, PHP 4, PHP 5.

LE GUIDE COMPLET 549

Chapitre 18

Les fonctions PHP

Cette fonction retourne la longueur de la partie initiale de $str1 qui ne contient aucun caractre de $str2 :
print(strcspn ("aeiouy", "bdcdf")); // affiche 6 print(strcspn ("aeiouy", "bdcdfi")); // affiche 2

strip_tags()
j j

Signature : strip_tags($str [, $balises]). Versions : PHP 3 partir de la 3.0.8, PHP 4 partir de la 4.0b2, PHP 5.

Cette fonction retourne une chane prive des balises HTML et PHP :
$data = "Bonjour <b>monde</b><br>hello <font>world</font>"; $str = strip_tags($data); // la variable $str contient alors "Bonjour mondehello world"

Cest trs pratique quand vous voulez empcher un internaute dinclure des balises HTML dans des donnes qui seront stockes dans votre base de donnes. Il est cependant possible dautoriser certaines balises en transmettant un deuxime paramtre la fonction strip_tags(). On peut, par exemple, nautoriser que la mise en gras (<b>) et les sauts de ligne (<br>) :
$data = "Bonjour <b>monde</b><br>hello <font>world</font>"; $str = strip_tags($data,"<b><br>"); // la variable $str contient alors "Bonjour <b>monde</b> // <br>hello world"

stripslashes()
j j

Signature : stripslashes ($str). Versions : PHP 3, PHP 4, PHP 5. fonction ralise lopration inverse de la fonction

Cette

addslashes() ; par exemple, \ devient :


print(stripslashes("l\aventure")); // affiche : laventure

550 LE GUIDE COMPLET

Les chanes de caractres

Chapitre 18

strlen()
j j

Signature : strlen ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la longueur dune chane de caractres :


$password = "jkw6d"; if (strlen($password) < 8) print("le mot de passe doit contenir au moins 8 caractres"); else print("longueur valide"); // affiche : le mot de passe doit contenir au moins 8 caractres

str_pad()
j j

Signature : str_pad ($str, $ln [,$s ,$mode]). Versions : PHP 4 partir de la 4.0.1, PHP 5.

Cette fonction permet de formater une chane de caractres lintrieur dune plus grande chane, en prcisant la longueur, lalignement (gauche, milieu, droit) et les caractres de remplissage (sil y a lieu) :
$str = "bonjour"; print(str_pad($str, 10)); // affiche : "bonjour " print(str_pad($str, 10, "-+", STR_PAD_LEFT)); // affiche : "-+-bonjour" print(str_pad($str, 10, "_", STR_PAD_BOTH)); // affiche : "_bonjour__" print(str_pad($str, 10, ".", STR_PAD_RIGHT)); // affiche : "bonjour..."

STR_PAD_RIGHT est le mode dalignement par dfaut, il est donc souvent inutile de le spcier.

strpbrk()
j j

Signature : strpbrk ($str, $list). Version : PHP 5.

LE GUIDE COMPLET 551

Chapitre 18

Les fonctions PHP

Cette fonction retourne une partie de $str commenant par lun des caractres prsents dans $list.
$str = "Bonjour Jean Dupont"; print(strpbrk($str,"ijq")); // affiche "jour Jean Dupont" car le caractre i nest pas // trouv la diffrence de j print(strpbrk($str,"iJq")); // affiche " Jean Dupont" car cette fonction est sensible // la casse

strpos()
j j

Signature : strpos ($str1, $str2). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la position de la variable $str2 dans la variable


$str2 :
$str1 = "bonjour"; $str2 = "on"; print(strpos($str1,$str2));

// affiche : 1

Si $str2 nest pas prsente dans $str1, la valeur boolenne false est retourne, ce qui peut conduire une erreur assez courante :
$str1 = "bonjour"; $str2 = "bon"; if (strpos($str1,$str2) == false) print("$str2 na pas t trouv dans $str1"); else print("OK"); // ce code affiche "bon na pas t trouv dans bonjour"

Le rsultat de cet exemple est donc erron. Le problme vient du test ==, qui ne fait pas la diffrence entre les valeurs false et 0. Il est donc ncessaire dutiliser loprateur ===, qui compare la fois la valeur et le type. La valeur false tant un boolen et 0 un numrique, le test ne passera pas :
$str1 = "bonjour"; $str2 = "bon"; if (strpos($str1,$str2) === false) print("$str2 na pas t trouv dans $str1"); else print("OK"); // affiche : OK

552 LE GUIDE COMPLET

Les chanes de caractres

Chapitre 18

La fonction strrpos() retourne, quant elle, la dernire position de la variable $str2 dans $str1 :
echo strrpos("bonbon","on"); // affiche : 4

strrchr()
j j

Signature : strrchr($str, $c). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la partie de $str qui commence l o lon trouve pour la dernire fois la premire lettre de la chane de caractres $c. En cas derreur, la valeur false est retourne :
$str = "www.toto.fr"; print("extension : " . strrchr($str,".")); // affiche : extension : .fr

str_repeat()
j j

Signature : str_repeat ($str, $n). Versions : PHP 4 partir de la 4.0b4, PHP 5.

Cette fonction rpte une chane plusieurs fois :


print(str_repeat ("--", 4)); // affiche : --------

strrev()
j j

Signature : strrev ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction inverse une chane de caractres :


print(strrev("abc")); // affiche : "cba"

strrpos()
j j

Signature : strrpos ($str1, $str2). Versions : PHP 3, PHP 4, PHP 5.

LE GUIDE COMPLET 553

Chapitre 18

Les fonctions PHP

Cette fonction retourne la position de la dernire occurrence de la chane $str2 au sein de $str1 :
print(strrpos("hellohello","lo")); // affiche : 8

strspn()
j j

Signature : strspn ($str1, $str2). Versions : PHP 3 partir de la 3.0.3, PHP 4, PHP 5.

Cette fonction retourne la longueur du segment initial de $str1, qui nest compos que de caractres de $str2 :
print(strspn("bonjour","bonsoir")); // affiche : 3 print(strspn("bonjour","on")); // affiche : 0, car "on" nest pas au dbut de "bonjour"

strstr()
j j

Signature : strstr ($str1, $str2). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la partie de $str1 qui commence l o lon trouve pour la premire fois la chane de caractres $str2. En cas derreur, le boolen false est retourn :
$email = "bob@toto.fr"; print("domaine : " . strstr($email,"@")); // affiche : domaine : @toto.fr

La fonction strchr() est un alias de strstr(). La fonction stristr() a le mme comportement que strstr(), sans tre sensible la casse.

strtolower()
j j

Signature : strtolower ($str). Versions : PHP 3, PHP 4, PHP 5.

554 LE GUIDE COMPLET

Les chanes de caractres

Chapitre 18

Cette fonction retourne la chane convertie entirement en minuscules :


$str = "Bonjour MONDE"; print(strtolower($str)); // affiche : "bonjour monde"

Il existe dautres fonctions permettant de jouer sur les minuscules et les majuscules.
j j j

strtoupper() : la chane passe en majuscules. ucfisrst() : le premier caractre de la chane passe en

majuscule.
ucwords() : le premier caractre de chacun des mots passe en

majuscule.
$str = "bonjour monde"; print(strtoupper($str)); // affiche : BONJOUR MONDE print(ucfirst($str)); // affiche : Bonjour monde print(ucwords($str)); // affiche : Bonjour Monde

str_replace()
j j

Signature : str_replace ($str1,$str2,$str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de remplacer la chane de caractres $str1 par la chane de caractres $str2 dans la chane de caractres $str :
print(str_replace("#PRENOM#","Paul","Prnom : #PRENOM#")); // affiche : Prnom : Paul

Il est aussi possible de remplacer $str1 et $str2 par des tableaux :


$s = str_replace(array("#PRENOM#","#NOM#"), array("Paul","Dupont"), "Nom : #NOM#<br>Prnom : #PRENOM#"); print($s); // affiche : // Nom : Dupont // Prnom : Paul

Cette fonction peut tre trs utile pour travailler avec des pages modles (templates).

LE GUIDE COMPLET 555

Chapitre 18

Les fonctions PHP

str_split()
j j

Signature : str_split ($str,$n). Version : PHP 5.

Cette fonction convertit la chane $str en un tableau. Le tableau est compos de parties de chanes de longueur $n.
$tab = str_plit ("bonjour"); // $tab contient "b","o","n","j","o","u","r" $tab = str_plit ("bonjour",4); // $tab contient "bonj","our"

strtr()
j j

Signature : strtr ($str, $chars1, $chars2). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de substituer, dans la chane $str, les caractres de $chars1 par les caractres de $chars2 :
$str = "cet lve est bte"; print(strtr($str, "", "eeee")); // affiche : "cet eleve est bete"

substr()
j j

Signature : substr ($str, $deb [, $long]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dextraire une partie dune chane de caractres. Le premier paramtre est la chane de caractres en question, le deuxime la position partir de laquelle lextraction va tre faite, le troisime (optionnel) indique la longueur de la partie extraire. Si le deuxime paramtre est ngatif, la position est considrer partir de la n de la chane. Si le troisime paramtre est ngatif (n), la partie extraite sarrtera
n caractres avant la n de la chane :
// toute la chane sauf le premier caractre print substr("abcdef", 1); // affiche : "bcdef"

556 LE GUIDE COMPLET

Les chanes de caractres

Chapitre 18

// une chane de 3 caractres partir du deuxime caractre print substr("abcdef", 1, 3); // affiche : "bcd" // les 2 derniers caractres print substr("abcdef", -2);

// affiche : "ef"

// toute la chane sauf les 2 derniers caractres print substr("abcdef", 0, -2); // affiche : "abcd" // toute la chane sauf le premier et le dernier caractre print substr("abcdef", 1, -1); // affiche : "bcde"

substr_compare()
j j

Signature :

substr_compare ($str1,$str2, $long [, $nocase]]).

$deb

[,

Version : PHP 5.

Cette fonction permet de comparer la chane $str1 ( partir de la position $deb) avec $str2, sur une longueur (optionnelle) de $long caractres. Si le paramtre $nocase est prcis et quil est gal true, la fonction devient insensible la casse.
echo echo echo echo substr_compare("abcde", substr_compare("abcde", substr_compare("abcde", substr_compare("abcde", "bc", 1, 2); // 0 "bcg", 1, 2); // 0 "BC", 1, 2, true); // 0 "bc", 1, 3); // 1

substr_count()
j j

Signature : substr_count ($str1,$str2). Versions : PHP 4 partir de la 4.0RC2, PHP 5.

Cette fonction permet de compter le nombre de fois o apparat une chane ($str2) dans une autre ($str1) :
$n = substr_count("bonjour monde","on"); print $n; // affiche : 2

substr_replace()
j

Signature : substr_replace ($str1, $str2, $deb [,


$long] ).

LE GUIDE COMPLET 557

Chapitre 18
j

Les fonctions PHP

Versions : PHP 4 partir de la 4.0b4, PHP 5.

Cette fonction remplace une partie dune chane de caractres $str1 par une autre $str2. Une position de dpart ($deb) et une longueur optionnelle ($long) peuvent tre prcises. Le mode de fonctionnement est alors le mme que pour la fonction substr() :
$str = "bonjour monde"; // remplace $str par "--" print substr_replace ($str, "--", 0); // affiche : "--" // insre "--" au dbut de $str print substr_replace ($str, "--", 0, 0); // affiche : "--bonjour monde" // remplace la deuxime lettre de $str par "--" print substr_replace ($str, "--", 1, 1); // affiche : "b--njour monde" // remplace les 4 premiers caractres de $str par "--" print substr_replace ($str, "--", 0, 4); // affiche : "--our monde" // remplace la dernire de $str lettre par "--" print substr_replace ($str, "--", -1, 1); // affiche : "bonjour mond--" // remplace par "--" tous les caractres de $str // sauf les 2 derniers print substr_replace ($str, "--", 0, -2); // affiche : "--de" // remplace par "-" tous les caractres de $str // sauf le premier et le dernier print substr_replace ($str, "--", 1, -1); // affiche : "b--e"

trim()
j j

Signature : trim ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction supprime les caractres blancs de dbut et de n de chane. Les caractres blancs sont les mmes que pour la fonction chop() : \n, \r, \t, \0.
$str = " bonjour monde "; print("|". $str . "|"); // affiche : | bonjour monde |

558 LE GUIDE COMPLET

Les expressions rgulires

Chapitre 18

print("|". trim($str) . "|"); // affiche : |bonjour monde|

Il existe des variantes trim() :


j j

ltrim() ne supprime que les caractres blancs gauche. rtrim() ne supprime que les caractres blancs droite (comme la fonction chop()).

wordwrap()
j j

Signature : wordwrap ($str, [, $long [, $sep [,


$coup]]]).

Versions : PHP 4 partir de la 4.0.2, PHP 5.

Cette fonction permet de sparer une chane de caractres $str en plusieurs parties de longueur $long, spares par une chane de caractres $sep. Par dfaut, la valeur de $long est 75 et celle de $sep est \n. Par dfaut, wordwrap() garde les mots en entier, sauf si $coup vaut 1 :
$str = "bonjour tous"; print wordwrap($str,4,"<br>"); /* affiche : bonjour tous */ $str = "bonjour tous"; print wordwrap($str,4,"<br>",1); /* affiche : bonj our tous */

18.3. Les expressions rgulires


Dans cette partie, le paramtre $motif correspond la REGEXP.
LE GUIDE COMPLET 559

Chapitre 18

Les fonctions PHP

preg_match()
j j

Signature : preg_match ($motif, $str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de tester si le motif $motif est prsent dans la chane $str. Elle retourne la valeur boolenne true si le motif est trouv, sinon elle renvoie false :
if (preg_match("/important/",$str)) // permet de tester si $str contient le mot "important"

Le motif peut contenir des expressions rgulires :


if (preg_match("/^\d*$/", $str)) // permet de tester si $str ne contient que des chiffres

preg_replace()
j j

Signature : preg_replace ($motif, $modele, $str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction balaie la chane $str pour trouver des zones de correspondance avec le motif $motif et remplace les zones en correspondance avec la chane $modele :
print(preg_replace("/c/","aaa","cqsdc")); // affiche : aaaqsdaaa $str = preg_replace("/\r\n/","\n",$str); // permet de remplacer \r\n par \n dans la chane $str print(preg_replace("/\d/","X","tel : 01 23 45 56 78")); // tous les caractres de type numriques // sont remplacs par X // le script affiche donc : tel : XX XX XX XX XX

split()
j j

Signature : split ($motif, $str [, $limite]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dcouper une chane partir dun motif de sparation. Les lments issus de la dcoupe sont placs dans un tableau :

560 LE GUIDE COMPLET

Les tableaux

Chapitre 18

$tab = split("[ \.]","03.21.52.68.41"); // permet de dcouper un numro de tlphone // le caractre de sparation pouvant tre un espace // ou un point print "indicatif : $tab[0]"; // indicatif : 03

Si le paramtre optionnel $limite est prcis, le tableau contiendra un grand nombre de $limite lments, le dernier lment contenant la chane entire. Si le motif $motif est un simple caractre (ou une simple chane), il est prfrable dutiliser la fonction explode() :
$tab = explode(",",$str);

18.4. Les tableaux


Les fonctions suivantes peuvent galement tre intressantes dans le cadre de lutilisation de tableaux : is_array(), explode(), implode(), split() et unset().

array()
j j

Signature: array(). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de crer un tableau. Il est possible de crer :


j

des tableaux scalaires ;


$tab = array("rouge","jaune","bleu"); print $tab[1]; // affiche : "jaune"

des tableaux associatifs.


$tab = array("nom"=>"dupont","prenom"=>"paul"); print $tab["nom"]; // affiche : "dupont"

Il est aussi possible de crer des tableaux plusieurs dimensions :


$toile = array ( "dimensions" => array ("longueur"=>"160", "largeur"=>"400"), "peintre" => array ("prenom"=>"paul", "nom"=>"cezanne"), ); print $toile["peintre"]["nom"]; // affiche : "cezanne"

LE GUIDE COMPLET 561

Chapitre 18

Les fonctions PHP

array_combine()
j j

Signature: array_combine ($tabindices, $tabvaleurs). Version : PHP 5.

Cette fonction retourne un tableau dont les indices sont les lments de
$tabindices et les valeurs, les lments de $tabvaleurs.

Elle retourne FALSE si le nombre dlments ne correspond pas entre $tabindices et $tabvaleurs.
$tab1 = array ("a", "b", "c"); $tab2 = array ("x","y","z"); $tab = array_combine($tab1, $tab2); // $tab contient : Array ( [a] => x [b] => y [c] => z )

array_count_values()
j j

Signature: array_count_values ($tab). Versions : PHP 4 partir de la 4.0b4, PHP 5.

Cette fonction retourne un tableau dont les indices sont les lments du tableau $tab et dont les valeurs correspondent la frquence dapparition de ces lments dans $tab.
$tab = array ("bonjour","monde","bonjour"); $tab2 = array_count_values ($array); print $tab2["bonjour"]; // affiche : 2 print $tab2["monde"]; // affiche : 1

array_diff()
j j

Signature : array_diff($tab1,$tab2). Versions : PHP 4 partir de la 4.0.1, PHP 5.

Cette fonction retourne un tableau qui contient toutes les valeurs de


$tab1 qui ne sont pas prsentes dans $tab2 (peu importe le type

dindice) :
$tab1 = array ("rouge", "jaune", "aa"=>"bleu"); $tab2 = array ("bb"=>"jaune","bleu"); $tab = array_diff($tab1,$tab2); // $tab contient : Array ( [0] => rouge )

562 LE GUIDE COMPLET

Les tableaux

Chapitre 18

array_ll_keys()
j j

Signature : array_fill_keys($tab_clefs, $valeur). Versions : PHP 5 >= 5.2.0.

Cette fonction retourne un tableau dont les clefs correspondent aux valeurs du tableau $tab_clefs et dont les valeurs correspondent $valeur :
$tab_clefs = array("a", "b", "c"); $tab = array_fill_keys($tab_clefs, 1); // $tab contient : Array ( [a] => 1 [b] => 1 [c] => 1 )

array_lter()
j j

Signature : array_filter($tab, $fct). Versions : PHP 4 partir de la 4.0.6, PHP 5.

Cette fonction retourne un tableau qui ne contient que les lments $tab qui ont t valids par la fonction $fct :
function primaire($val) { if (($val == "rouge") || ($val == "jaune") || ($val == "bleu")) return (1); } $tab = array ("rouge","orange","marron","bleu"); $tab2 = array_filter($tab,"primaire"); // seules les couleurs primaires sont conserves // $tab2 contient : // Array ( [0] => rouge [3] => bleu ) function pair($val) { if (($val % 2)) return (1); } $tab = array (1,2,3,4,5,6,7); $tab2 = array_filter($tab,"pair"); // seuls les nombres impairs sont conservs // $tab2 contient : // Array ( [0] => 1 [2] => 3 [4] => 5 [6] => 7 )

LE GUIDE COMPLET 563

Chapitre 18

Les fonctions PHP

Une fonction interne PHP peut galement tre utilise en tant que callback :
$tab = array ("bonjour",3,3.2,0,false); $tab2 = array_filter($tab,"is_int"); // seuls les entiers sont conservs // $tab2 contient : // Array ( [1] => 3 [3] => 0 )

array_ip()
j j

Signature : array_flip ($tab). Versions : PHP 4 partir de la 4.0b4, PHP 5.

Cette fonction retourne un tableau dont les indices sont devenus les valeurs, et inversement :
$tab = array ("rouge","aa"=>"orange","marron","bleu"); $tab2 = array_flip($tab); print $tab["aa"]; // affiche : "orange" print $tab2["orange"]; // affiche : "aa"

array_intersect()
j j

Signature : array_intersect ($tab1,$tab2). Versions : PHP 4 partir de la 4.0.1, PHP 5.

Cette fonction retourne un tableau contenant les valeurs prsentes la fois dans $tab1 et dans $tab2 :
$tab1 = array ("rouge", "jaune", "aa"=>"bleu"); $tab2 = array ("bb"=>"jaune","bleu"); $tab = array_intersect($tab1,$tab2); // $tab contient : Array ( [1] => jaune [aa] => bleu )

array_keys()
j j

Signature : array_keys ($tab). Versions : PHP 4, PHP 5.

Cette fonction retourne un tableau contenant les indices de $tab :


$tab = array ("rouge","aa"=>"orange","marron","bleu"); $tab2 = array_keys($tab); // $tab2 contient les valeurs 0, "aa", 1, 2

564 LE GUIDE COMPLET

Les tableaux

Chapitre 18

Il est possible de prciser en paramtre la valeur dont on veut rcuprer les indices :
$tab = array ("rouge","aa"=>"orange","marron","bleu", "orange"); $tab2 = array_keys($tab,"orange"); // $tab2 contient les valeurs "aa" et 3

array_map()
j j

Signature : array_map ($fct,$tab [, $tab2]). Versions : PHP 4 partir de la 4.0.6, PHP 5.

Cette fonction permet dappliquer une fonction $fct tous les lments dun tableau $tab :
function double($val) { return $val * $val; } $tab = array ( 1, 2, 3); $tab2 = array_map("double",$tab); // $tab2 contient : 1, 4, 9

Il est aussi possible de transmettre plusieurs tableaux array_map(). La fonction callback $fct doit alors avoir autant de paramtres quil y a de tableaux :
function sup ($x, $y) { if ($x > $y) return $x; return $y; } $tab1 = array (2,18,-10,2,6); $tab2 = array (12, 2, 4, 34, -3); $max = array_map("sup",$tab1,$tab2); // le tableau $max contient les plus grandes valeurs de // $tab1 et de $tab2 : // Array ( [0] => 12 [1] => 18 [2] => 4 [3] => 34 [4] => 6 )

array_merge()
j j

Signature : array_merge ($tab1, $tab2). Versions : PHP 4, PHP 5.

LE GUIDE COMPLET 565

Chapitre 18

Les fonctions PHP

Cette fonction retourne un tableau compos des lments des diffrents tableaux passs en paramtres :
$tab1 = array ("rouge", "jaune", "bleu"); $tab2 = array ("vert", "blanc"); $tab = array_merge($tab1,$tab2); // $tab contient : // Array ( [0] => rouge [1] => jaune [2] => bleu [3] // => vert [4] => blanc )

array_merge_recursive()
j j

Signature : array_merge_recursive ($tab1, $tab2). Versions : PHP 4 partir de la 4.0.1, PHP 5.

Comme array_merge(), cette fonction fusionne des tableaux. Cependant, si lun des tableaux contient dautres tableaux, les lments de ces derniers seront pris en compte dans la fusion :
$tab1 = array ("rouge", "jaune", "aa"=>array("bleu", "violet")); $tab2 = array ("vert", "aa"=>array("cyan"), "blanc"); $tab = array_merge_recursive($tab1,$tab2); // $tab contient : // Array ( [0] => rouge [1] => jaune [aa] => // Array ( [0] => bleu [1] => violet [2] => cyan ) // [2] => vert [3] => blanc )

array_pad()
j j

Signature : array_pad ($tab, $tailler, $val). Versions : PHP 4 partir de la 4.0b4, PHP 5.

Cette fonction permet daugmenter la taille dun tableau en comblant les espaces avec la valeur $val. Si la variable $taille est ngative, linsertion des nouvelles valeurs se fait au dbut :
$tab = array (1, 2 ,3); $tab2 = array_pad($tab,5,9); // $tab2 contient : 1, 2, 3, 9, 9 $tab3 = array_pad($tab,-5,9); // $tab3 contient : 9, 9, 1, 2, 3

566 LE GUIDE COMPLET

Les tableaux

Chapitre 18

array_pop()
j j

Signature : array_pop ($tab). Versions : PHP 4, PHP 5.

Cette fonction retourne la dernire valeur du tableau $tab. Le paramtre


$tab est alors court de cette dernire valeur :
$tab = array ("rouge","jaune","bleu"); $dernier = array_pop($tab); // la variable $dernier vaut "bleu" // et $tab ne contient plus que "rouge", "jaune"

array_push()
j j

Signature : array_push ($tab, $val1, $val2). Versions : PHP 4, PHP 5.

Cette fonction ajoute des lments un tableau :


$tab = array ("rouge", "jaune"); array_push($tab,"bleu","vert"); // $tab contient rouge, jaune, bleu, vert

Il aurait galement t possible dajouter les deux derniers lments de la manire suivante :
$tab = array ("rouge", "jaune"); $tab[] = "bleu"; $tab[] = "vert";

array_rand ()
j j

Signature : array_rand ($tab). Versions : PHP 4, PHP 5.

Cette fonction retourne un indice alatoire du tableau $tab. La fonction srand() doit tre appele pralablement :
srand ((double) microtime() * 10000000); $tab = array ("rouge","jaune","bleu"); $indice = array_rand($tab); print $tab[$indice]; // affiche une des valeurs de $tab

LE GUIDE COMPLET 567

Chapitre 18

Les fonctions PHP

array_reverse()
j j

Signature : array_reverse ($tab). Versions : PHP 4 partir de la 4.0b4, PHP 5.

Cette fonction retourne un tableau contenant les lments de $tab dans lordre inverse :
$tab = array ("rouge","jaune","bleu"); $tab2 = array_reverse($tab); // $tab2 contient bleu, jaune, rouge

array_reduce()
j j

Signature : array_reduce ($tab,$func). Versions : PHP 4 partir de la 4.0.5, PHP 5.

Cette fonction permet de rduire le tableau une seule valeur en appliquant la fonction $func itrativement tous les lments du tableau $tab :
function mult($a,$b) { $a *= $b; return $a; } $tab = array(2,4,6); echo array_reduce($tab,$mult); // affiche 48 : 2 * 4 * 6

array_shift()
j j

Signature : array_shift ($tab). Versions : PHP 4, PHP 5.

Cette fonction permet dextraire le premier lment du tableau $tab et de le retourner :


$tab = array("www","kernix","com"); echo array_shift($tab); // affiche "www", $tab ne contient plus que "kernix" et "com"

568 LE GUIDE COMPLET

Les tableaux

Chapitre 18

array_slice()
j j

Signature : array_slice ($tab,$deb[,$n]). Versions : PHP 4, PHP 5.

Cette fonction permet dextraire un sous-tableau du tableau $tab. Si $deb est positif, $tab2 contient les lments commenant lindice $deb du tableau $tab ; si $deb est ngatif, lindice est considrer partir de la n de $tab. Si $n est positif, le sous-tableau contiendra $n lments. Si $n est ngatif, les $n derniers lments de $tab ne feront pas partie du sous-tableau. Si $n nest pas prcis, tous les lments, partir de lindice $deb, seront retourns.
$tab = array(1,2,3,4,5,6,7,8,9); $tab2 = array_slice($tab,2); // $tab2 contient 3,4,5,6,7,8,9 $tab2 = array_slice($tab,2,2); // $tab2 contient 3,4 $tab2 = array_slice($tab,2,-2); // $tab2 contient 3,4,5,6,7 $tab2 = array_slice($tab,-2,2); // $tab2 contient 8,9

array_splice()
j j

Signature : array_splice ($tab, $remplacement]). Versions : PHP 4, PHP 5.

$offset

[,

$ln,

Cette fonction supprime une partie dun tableau et la remplace par un autre lment. Si $offset est positif, la portion supprimer commence lindex $offset. Si $offset est ngatif lindex est prendre partir de la n du tableau :
$tab = array ("a","b","c","d","e"); $r = array_splice($tab, 3); // $tab contient : Array ( [0] => a [1] => b [2] => c ) // $r contient : Array ( [0] => d [1] => e )

LE GUIDE COMPLET 569

Chapitre 18

Les fonctions PHP

$tab = array ("a","b","c","d","e"); $r = array_splice($tab, -3); // $tab contient : Array ( [0] => a [1] => b ) // $r contient : Array ( [0] => c [1] => d [2] => e )

Si le paramtre $ln est prcis et est positif, seuls $ln lments de $tab seront supprims. Sil est ngatif, la portion supprime sarrte $ln lments avant la n de $tab :
$tab = array ("a", "b", "c", "d", $r = array_splice($tab, 2, 1); // $tab contient : Array ( [0] => // [3] => // $r contient : Array ( [0] => c $tab = array ("a", "b", "c", "d", $r = array_splice($tab, 2, -1); // $tab contient : Array ( [0] => // $r contient : Array ( [0] => c "e", "f"); a [1] => b [2] => d e [4] => f ) ) "e", "f"); a [1] => b [2] => f ) [1] => d [2] => e )

Si le paramtre $remplacement est prcis, les lments retirs de $tab sont remplacs par les lments de $remplacement :
$tab = array ("a", "b", "c", "d", "e", "f"); $remplacement = array (1, 2); $r = array_splice($tab, 2, 1, $remplacement); // $tab contient : Array ( [0] => a [1] => b [2] => 1 [3] => 2 [4] => d [5] => e [6] => f ) // $r contient : Array ( [0] => c )

Si juste un lment de $tab doit tre remplac par un seul lment, $remplacement peut tre une valeur simple. Si les valeurs de $offset et de $ln font quaucun lment ne doit tre remplac dans $tab, $remplacement est alors insr la position $offset :
$tab = array ("a", "b", "c", "d", "e", "f"); $remplacement = array (1, 2); $r = array_splice($tab, 2, -50, $remplacement); // $tab contient : Array ( [0] => a [1] => b [2] => 1 [3] => 2 [4] => c [5] => d [6] => e [7] => f ) // $r est vide

array_sum()
j j

Signature : array_sum ($tab). Versions : PHP 4 partir de la 4.0.4, PHP 5.

570 LE GUIDE COMPLET

Les tableaux

Chapitre 18

Cette fonction additionne les valeurs de $tab :


$tab = array ("1", 2, 3); print array_sum ($tab); // affiche 6

array_unique()
j j

Signature : array_unique ($tab). Versions : PHP 4, PHP 5.

Cette fonction supprime les doublons dun tableau :


$tab = array ("1", 2, "coucou", 1, coucou, 1.0); print_r(array_unique ($tab)); // affiche : Array ( [0] => 1 [1] => 2 [2] => coucou )

array_unshift()
j j

Signature : array_unshift ($tab, $elem1 [, $elem2]). Versions : PHP 4, PHP 5.

Cette fonction permet dajouter des lments au dbut dun tableau :


$tab = array ("a","b"); array_unshift ($tab, "c", array ("d", "e")); /* $tab contient Array ( [0] => c [1] => Array ( [0] => d [1] => e ) [2] => a [3] => b ) */

La fonction retourne le nouveau nombre dlments dans le tableau.

array_values()
j j

Signature : array_values ($tab). Versions : PHP 4, PHP 5.

LE GUIDE COMPLET 571

Chapitre 18

Les fonctions PHP

Cette fonction retourne les valeurs contenues dans $tab :


$tab = array ("a", "b"=>"c", 1); print_r(array_values($tab)); /* affiche : Array ( [0] => a [1] => c [2] => 1 ) */

array_walk()
j j

Signature : array_walk ($tab, $fct). Versions : PHP 3 partir de la 3.0.3, PHP 4, PHP 5.

Cette fonction permet dappliquer la fonction $fct tous les lments de $tab. La fonction $fct reoit en premier paramtre la valeur, et en deuxime la cl (lindex) de llment :
function nbcar ($valeur, $clef) { echo strlen($valeur), "<br>"; } $tab = array ("BonJour", "BONJ"); array_walk($tab,"nbcar"); /* affiche : 7 4 */

Pour modier directement les valeurs de $tab, il est ncessaire que le premier paramtre de $fct soit pass par rfrence :
function minuscule (&$valeur, $clef) { $valeur = strtolower($valeur); } $tab = array ("BonJour", "BONJOUR"); array_walk($tab,"minuscule"); /* $tab contient : Array ( [0] => bonjour [1] => bonjour

572 LE GUIDE COMPLET

Les tableaux
) */

Chapitre 18

asort()
j j

Signature : asort ($tab). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction trie les lments dun tableau (en conservant lassociation indice/valeur) :
$tab = array ("a" => "hello", "bonjour", "b" => "ola"); asort($tab); /* $tab contient : Array ( [0] => bonjour [a] => hello [b] => ola ) */

La fonction arsort() trie, quant elle, les lments en ordre inverse :


$tab = array ("a" => "hello", "bonjour", "b" => "ola"); arsort($tab); /* $tab contient : Array ( [b] => ola [a] => hello [0] => bonjour ) */

compact()
j j

Signature : compact ($var1 [, $var2]). Versions : PHP 4, PHP 5.

Cette fonction permet de crer un tableau associatif partir des noms de variables :
$prenom = "Paul"; $nom = "Dupont"; $tab = compact("nom","prenom"); /* $tab contient :

LE GUIDE COMPLET 573

Chapitre 18

Les fonctions PHP

Array ( [nom] => Dupont [prenom] => Paul ) */

count()
j j

Signature : count ($tab). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le nombre dlments dun tableau :


$tab = array ("a", "b", "c"); echo count($tab); // affiche 3 $tab[1] = "a"; $tab[5] = "b"; $tab[6] = "c"; echo count($tab); // affiche 5

La fonction sizeof() est un alias de count().

current()
j j

Signature : current ($tab). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne llment courant du tableau $tab. Cet lment est celui qui est associ au pointeur interne du tableau. Ce pointeur peut tre modi par les fonctions suivantes :
j j j j

end() place le pointeur interne la n du tableau. next() avance dune position le pointeur interne du tableau. prev() recule dune position le pointeur interne du tableau. reset() place le pointeur interne au dbut du tableau.

Le script suivant permet dafficher tous les lments dun tableau :


$tab = array ("a", "b", "c", "d"); while ($val = current($tab)) { echo "$val - ";

574 LE GUIDE COMPLET

Les tableaux
next ($tab); } // affiche : a - b - c - d -

Chapitre 18

Ce script affiche, quant lui, les valeurs de $tab dans lordre inverse :
$tab = array ("a", "b", "c", "d"); end ($tab); while ($val = current($tab)) { echo "$val - "; prev ($tab); } // affiche : d - c - b - a -

lment vide

Si un des lments du tableau contient les valeurs 0 ou "", la fonction current() retourne alors false.

La fonction pos() est un alias de current().

each()
j j

Signature : each ($tab). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne un tableau contenant lindex et la valeur courante du tableau $tab, puis avance le pointeur dune position :
$tab = array ("prenom" => "Claire", "nom" => "Fulchiron"); next ($tab); print_r(each ($tab)); /* affiche Array ( [1] => Fulchiron [value] => Fulchiron [0] => nom [key] => nom ) */

Cette fonction permet de traverser tout un tableau sans se soucier des valeurs contenues dans ce dernier :

LE GUIDE COMPLET 575

Chapitre 18

Les fonctions PHP

$tab = array ("prenom" => "Paul", "nom" => "Dupont", 0, "annee" => 1977, "Paris"); while (list ($clef, $valeur) = each ($tab)) { echo "$clef > $valeur<br>"; } /* affiche prenom > Paul nom > Dupont 0 > 0 annee > 1977 1 > Paris */

extract()
j j

Signature : extract ($tab [, $mode [, $prefixe]]). Versions : PHP 3 partir de la 3.0.7, PHP 4, PHP 5.

Cette fonction permet de crer et dinitialiser des variables partir des cls et des valeurs des lments dun tableau associatif. Quatre modes sont disponibles
j j j j

EXTR_OVERWRITE : si une variable du mme nom existe, son

contenu est remplac (mode par dfaut). EXTR_SKIP : si une variable de mme nom existe, elle nest pas modie. EXTR_PREFIX_SAME : si une variable de mme nom existe, une nouvelle variable est cre (en utilisant le prxe $prefixe). EXTR_PREFIX_ALL : prxe toutes nouvelles variables avec $prefixe.

La fonction extract() retourne le nombre de variables importes avec succs :


$nom = "Durand"; $tab = array ("prenom" => "Paul", "nom" => "Dupont"); extract($tab); echo $nom; // affiche : Dupont $nom = "Durand"; $tab = array ("prenom" => "Paul", "nom" => "Dupont"); extract($tab,EXTR_SKIP); echo $nom; // affiche : Durand

576 LE GUIDE COMPLET

Les tableaux

Chapitre 18

$nom = "Durand"; $tab = array ("prenom" => "Paul", "nom" => "Dupont"); extract($tab, EXTR_PREFIX_SAME, "var_"); echo $nom; // affiche : Durand echo $var_nom; // affiche : Dupont $nom = "Durand"; $tab = array ("prenom" => "Paul", "nom" => "Dupont"); extract($tab, EXTR_PREFIX_SAME, "var"); echo $nom; // affiche : Durand echo $var_nom; // affiche : Dupont $nom = "Durand"; $tab = array ("prenom" => "Paul", "nom" => "Dupont"); extract($tab, EXTR_PREFIX_ALL, "var"); echo $nom; // affiche : Durand echo $var_nom; // affiche : Dupont echo $var_prenom; // affiche : Paul

in_array()
j j

Signature : in_array ($var, $tab [, $strict]). Versions : PHP 4, PHP 5.

Cette fonction retourne true si la variable $var est prsente dans le tableau $tab :
$tab = array ("prenom" => "Paul", "nom" => "Dupont", "annee" => 1977); if (in_array("1977", $tab)) echo "lment trouv"; else echo "lment absent"; // affiche : "lment trouv"

Si le paramtre $strict (boolen) est prcis, les types doivent aussi correspondre :
$tab = array ("prenom" => "Paul", "nom" => "Dupont", "annee" => 1977); if (in_array("1977", $tab, true)) echo "lment trouv"; else echo "lment absent"; // affiche : "lment absent" car vous avez un numrique et une chane

array_search()
j j

Signature : array_search ($var, $tab [, $strict]). Versions : PHP 4 partir de la 4.0.5, PHP 5.

LE GUIDE COMPLET 577

Chapitre 18

Les fonctions PHP

Cette fonction recherche une valeur ($var) dans un tableau et retourne, en cas de succs, lindice de llment trouv. Si le paramtre boolen $strict est prcis, une comparaison de type est effectue :
$tab = array ("prenom" => "Paul", "nom" => "Dupont", "annee" => 1977); echo array_search ("1977",$tab); // affiche : annee

key()
j j

Signature : key ($tab). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne lindice de la position courante :


$tab = array ("prenom" => "Paul", "nom" => "Dupont", "annee" => 1977); next($tab); echo key($tab); // affiche : nom

ksort()
j j

Signature : ksort ($tab). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de classer un tableau par cls (la corrlation cl/valeur est maintenue) :
$tab = array ("prenom" => "Paul", "nom" => "Dupont", "annee" => 1977); ksort($tab); /* $tab contient : Array ( [annee] => 1977 [nom] => Dupont [prenom] => Paul ) */

La fonction krsort() classe en ordre inverse :


$tab = array ("prenom" => "Paul", "nom" => "Dupont", "annee" => 1977);

578 LE GUIDE COMPLET

Les tableaux
krsort($tab); /* $tab contient : Array ( [prenom] => Paul [nom] => Dupont [annee] => 1977 ) */

Chapitre 18

list()
j

Signature : list ().

Cette fonction permet, en une ligne, dassigner des valeurs plusieurs variables :
$tab = array ("prenom" => "Paul", "nom" => "Dupont", "annee" => 1977); list ($prenom, $nom) = array_values ($tab); echo $nom;

natsort()
j j

Signature : natsort ($tab). Versions : PHP 4, PHP 5.

Cette fonction permet de classer les lments dun tableau en utilisant lordre naturel :
$tab = array ("img21.png","img12.png","img1.png","img2.png"); natsort($tab); /* $tab contient : Array ( [2] => img1.png [3] => img2.png [1] => img12.png [0] => img21.png ) */

LE GUIDE COMPLET 579

Chapitre 18

Les fonctions PHP

$tab = array ("img21.png","img12.png","img1.png", "img2.png"); sort($tab); /* $tab contient : Array ( [0] => img1.png [1] => img12.png [2] => img2.png [3] => img21.png ) */

natcasesort() fonctionne sur le mme modle que natsort(), sans

tre sensible la casse.

range()
j j

Signature : range ($min, $max). Versions : PHP 3 partir de la 3.0.8, PHP 4, PHP 5.

Cette fonction permet de remplir un tableau partir dun intervalle :


$tab = range (12, 16); echo $tab[1]; // affiche 13

Avec une version de PHP suprieure ou gale 4.1.0, il est possible dcrire range (a, z).

shuffle()
j j

Signature : shuffle ($tab). Versions : PHP 3 partir de la 3.0.8, PHP 4, PHP 5.

Cette fonction permet de mlanger les lments dun tableau. Le gnrateur de nombres alatoires doit tre initialis auparavant :
$tab = range (1, 10); srand ((float)microtime()*1000000); shuffle ($tab); while (list ($clef, $valeur) = each ($tab)) print("$valeur - "); // affiche : 4 - 6 - 5 - 10 - 8 - 2 - 3 - 1 - 9 - 7 -

580 LE GUIDE COMPLET

Les tableaux

Chapitre 18

sort()
j j

Signature : sort ($tab [, $mode]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de classer les lments dun tableau. La fonction rsort() classe, quant elle, en ordre inverse. Le paramtre optionnel $mode (ajout aux versions de PHP suprieures ou gales 4) permet de spcier le type de comparaison qui est utilise pour le tri.
j j j

SORT_REGULAR : comparaison normale. SORT_NUMERIC : comparaison numrique. SORT_STRING : comparaison de chanes.


$tab = array (2, "1", 3.0, -12, "12", "-5"); sort($tab, SORT_STRING); /* $tab contient Array ( [0] => -12 [1] => -5 [2] => 1 [3] => 12 [4] => 2 [5] => 3 ) */ $tab = array (2, "1", 3.0, -12, "12", "-5"); sort($tab, SORT_NUMERIC); /* $tab contient Array ( [0] => -12 [1] => -5 [2] => 1 [3] => 2 [4] => 3 [5] => 12 ) */

LE GUIDE COMPLET 581

Chapitre 18

Les fonctions PHP

uasort()
j j

Signature : uasort ($tab, $fct). Versions : PHP 3 partir de la 3.0.4, PHP 4, PHP 5.

Cette fonction permet de trier un tableau en prcisant la fonction de comparaison $fct. Dans lexemple suivant, vous classez les lments du tableau par longueur de chane :
function comp_long($x, $y) { if (strlen($x) > strlen($y)) return 1; return -1; } $tab = ("z" => "11", 9, "b" => "aaaa", "q" => "zzz"); usort($tab, "comp_long"); /* $tab Array ( [0] [1] [2] [3] ) */ contient : => => => =>

9 11 zzz aaaa

La fonction uasort() maintient lassociation cl/valeur :


function comp_long($x, $y) { if (strlen($x) > strlen($y)) return 1; return -1; } $tab = ("z" => "11", 9, "b" => "aaaa", "q" => "zzz"); usort($tab, "comp_long"); /* $tab Array ( [0] [z] [q] [b] ) */ contient : => => => =>

9 11 zzz aaaa

La fonction uksort() trie, quant elle, les cls.


582 LE GUIDE COMPLET

Les fonctions de dates et dheures

Chapitre 18

18.5. Les fonctions de dates et dheures


Il est courant en informatique de faire rfrence un timestamp. Il sagit dun nombre entier qui correspond au nombre de secondes entre le 1er janvier 1970 et une date donne.

checkdate()
j j

Signature : checkdate ($mois, $jour, $annee). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne true si la date est valide, sinon false.


j j j

Lanne doit tre comprise entre 1 et 32767. Le mois doit tre compris entre 1 et 12. Le jour doit tre une valeur autorise pour le mois donn (les annes bissextiles sont prises en compte).

date()
j j

Signature : date ($format [, $timestamp]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dafficher une date (timestamp) suivant un certain format. Si le paramtre $timestamp nest pas prcis, cest la date courante qui est prise en compte.
j

Les caractres de substitution utiliss au sein du format sont lists dans le chapitre consacr aux Dates et Heures
print (date("s")); // affiche le nombre de secondes de la date actuelle echo date("d/m/Y"); // affiche la date la franaise, par exemple 12/03/2001

LE GUIDE COMPLET 583

Chapitre 18

Les fonctions PHP

Il est courant dutiliser la fonction date() avec la fonction mktime() :


$demain = mktime (0, 0, 0, date("m"), date("d") + 1, date("Y")); $moisdernier = mktime (0, 0, 0, date("m")-1, date("d"), date("Y")); $anneeprochaine = mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1); $demain = mktime (0, 0, 0, date("m"), date("d") + 1, date("Y")); echo "demain nous serons le " . date("j",$demain); // si nous sommes le 31, affiche : "demain nous serons le 1"

Pour travailler avec un temps GMT (Greenwich Mean Time), la fonction gmdate() doit tre utilise.

getdate()
j j

Signature : getdate ([$timestamp]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne un tableau associatif contenant des informations sur la date courante (ou sur le timestamp si le paramtre est prcis).
j j j j j j j j j j

"seconds" : secondes. "minutes" : minutes. "hours" : heures. "mday" : jour du mois. "wday" : jour de la semaine, numrique, de 0 (dimanche) 6 (samedi). "mon" : mois, numrique. "year" : anne, numrique. "yday" : jour de lanne, numrique, cest--dire "299". "weekday" : jour de la semaine, texte complet (en anglais), cest--dire "Friday". "month" : mois, texte complet, en anglais, cest--dire "January".

$aujourdhui = getdate(); $mois = $aujourdhui[month]; $mjour = $aujourdhui[mday]; $annee = $aujourdhui[year]; echo "$mjour/$mois/$annee"; // affiche la date la franaise

584 LE GUIDE COMPLET

Les fonctions de dates et dheures

Chapitre 18

microtime()
j j

Signature : microtime (). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le timestamp de la date courante avec les microsecondes. La fonction retourne, en fait, une chane de caractres formate de la faon suivante : "msec sec" o "sec" correspond au timestamp en secondes de la date courante et "msec" correspond aux millisecondes.

mktime()
j j

Signature : mktime ($heure, $minute, $seconde, $mois, $jour, $annee). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de retourner le timestamp dune date :


echo date ("l", mktime (0,0,0,1,1,2000)); // affiche "Saturday" et permet ainsi de savoir que le 1er janvier 2000 tait un samedi

Les paramtres transmis mktime() ne sont pas obligatoirement valides (le mois nest pas obligatoirement compris entre 1 et 12). Tous les exemples suivants affichent "01/Jan/1998" :
echo echo echo echo date date date date ("d/M/Y", ("d/M/Y", ("d/M/Y", ("d/M/Y", mktime mktime mktime mktime (0,0,0,12,32,1997)); (0,0,0,13,1,1997)); (0,0,0,1,1,1998)); (0,0,0,1,1,98));

La fonction gmmktime() permet de travailler avec des dates GMT.

strftime()
j j

Signature : strftime ($format [, $timestamp]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de formater une date selon la langue locale. Les caractres de conversion qui peuvent tre contenus dans le format sont

LE GUIDE COMPLET 585

Chapitre 18
j j j j j j j j j j j j j j j j j j j j j j j j

Les fonctions PHP

%a : nom abrg du jour de la semaine (local). %A : nom complet du jour de la semaine (local). %b : nom abrg du mois (local). %B : nom complet du mois (local). %c : reprsentation prfre pour les dates et les heures, en local. %C : numro de sicle (lanne, divise par 100 et arrondie entre 00 et 99). %d : jour du mois en numrique (intervalle de 01 31). %D : identique %m/%d/%y. %e : numro du jour du mois, les chiffres sont prcds dun espace (de 1 31). %h : identique %b. %H : heure de la journe en numrique et sur 24 heures (intervalle de 00 23). %I : heure de la journe en numrique et sur 12 heures (intervalle de 01 12). %j : jour de lanne, en numrique (intervalle de 001 366). %m : mois en numrique (intervalle de 1 12). %M : minute en numrique. %n : newline character. %p : soit am ou pm, en fonction de lheure absolue ou en

fonction des valeurs enregistres en local. %r : lheure au format AM et PM. %R : lheure au format 24 h. %S : secondes en numrique. %t : tabulation. %T : lheure actuelle (gale %H:%M:%S). %u : le numro du jour dans la semaine de 1 7 (1 reprsente lundi). %U : numro de semaine dans lanne, en considrant le premier dimanche de lanne comme le premier jour de la premire semaine. %V : le numro de semaine comme dni dans la norme ISO 8601 (1988), sous forme dcimale, de 01 53. La semaine 1 est la

586 LE GUIDE COMPLET

Les fonctions de dates et dheures

Chapitre 18

j j j j j j j j

premire semaine qui a plus de quatre jours dans lanne courante et dont lundi est le premier jour. %W : numro de semaine dans lanne, en considrant le premier lundi de lanne comme le premier jour de la premire semaine. %w : jour de la semaine, numrique (0 reprsente dimanche). %x : format prfr de reprsentation de la date sans lheure. %X : format prfr de reprsentation de lheure sans la date. %y : lanne, numrique, sur deux chiffres (de 00 99). %Y : lanne, numrique, sur quatre chiffres. %Z : fuseau horaire, ou nom ou abrviation. %% : un caractre % littral.

Lexemple suivant permet dcrire le jour courant dans trois langues diffrentes :
print (strftime ("Le jour %A se dit en :<br><br>")); setlocale ("LC_TIME", "fi_FI"); print (strftime ("- finlandais : %A<br>")); setlocale ("LC_TIME", "fr_CA"); print (strftime ("- franais : %A<br>")); setlocale ("LC_TIME", "de_DE"); print (strftime ("- allemand : %A<br>")); /* affiche par exemple : Le jour Sunday se dit en : - finlandais : sunnuntai - franais : dimanche - allemand : Sonntag */

La fonction gmstrftime() permet de travailler avec des dates GMT.

time()
j j

Signature : time (). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le timestamp de la date courante.

LE GUIDE COMPLET 587

Chapitre 18

Les fonctions PHP

strtotime()
j j

Signature : strtotime ($str). Versions : PHP 3 partir de la 3.0.12, PHP 4, PHP 5.

Cette fonction essaie de convertir une date exprime en anglais usuel :


echo date ("l", strtotime ("1 January 3000")); // le 1er janvier 3000 sera un jeudi

18.6. Les chiers et les rpertoires


PHP permet de manipuler les chiers, quils soient locaux ou distants (sur dautres serveurs). Dans cette partie, le paramtre $fichier correspond un nom de chier ("toto.txt", "/tmp/toto.txt", "http://www.site .com/toto.txt") et $pfichier correspond, lui, un pointeur sur chier (un identiant de chier). Il en va de mme pour les paramtres $repertoire et $prep.

basename()
j j

Signature : basename ($chemin [, $suffixe]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le nom du chier contenu dans le chemin


$chemin. Si le paramtre $suffixe est prcis, le suffixe du nom de

chier nest pas indiqu.


$chemin = "/sites/monsite/images/titre.gif"; echo basename ($chemin); // affiche : titre.gif echo basename ($chemin, ".gif"); // affiche : titre

Attention, un rpertoire peut tre considr comme un chier, il est donc possible dcrire :
$chemin = "/sites/monsite/images"; echo basename ($chemin); // affiche : images

Les barres obliques inverses ou non peuvent tre utilises sous Windows comme caractres de sparation dans le chemin daccs. Seule

588 LE GUIDE COMPLET

Les fichiers et les rpertoires

Chapitre 18

la barre oblique simple est accepte sur les autres systmes dexploitation.

chdir()
j j

Signature : chdir ($repertoire). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de changer de rpertoire courant. Elle retourne


false en cas derreur, sinon true.

chgrp()
j j

Signature : chgrp ($fichier, $groupe). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de changer le groupe dun chier. Si vous ntes pas super-utilisateur, vous devez la fois tre membre du groupe de dpart (celui du chier) et darrive ($groupe) pour pouvoir le modier. La fonction retourne true en cas de succs, sinon false. La variable $groupe peut contenir lid du groupe. Cette fonction ne fonctionne pas sous Windows.

chmod()
j j

Signature : chmod ($fichier, $droits). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de changer les droits dun chier :


chmod ("/sites/monsite/images/titre.gif", 0644); /* les droits du fichier passent en : - lecture, criture pour le propritaire du fichier [6 : 110] - lecture pour le groupe du propritaire [4 : 100] - lecture pour tout le monde [4 : 100] */

La fonction retourne true en cas de succs, sinon false. Elle ne fonctionne pas sous Windows.

LE GUIDE COMPLET 589

Chapitre 18

Les fonctions PHP

chown()
j j

Signature : chown ($fichier, $utilisateur). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de changer le propritaire du chier. Seul le super-utilisateur peut modier le propritaire dun chier. La fonction retourne true en cas de succs, sinon false. Elle ne fonctionne pas sous Windows.

clearstatcache()
j j

Signature : clearstatcache (). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de vider le cache systme qui a t mis en place lors de laccs un chier. Cette fonction est particulirement utile lorsque vous travaillez sur des chiers susceptibles de changer trs souvent. Les fonctions qui peuvent avoir besoin dtre suivies de
clearstatcache() sont : stat(), lstat(), file_exists(), is_writable(), is_readable(), is_executable(), is_file(), is_dir(), is_link(), filectime(), fileatime(), filemtime(), fileinode(), filegroup(), fileowner(), filesize(), filetype() et fileperms().

closedir()
j j

Signature : closedir ($prep). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de fermer lidentiant de rpertoire $prep.

copy()
j j

Signature : copy ($fichierorig, $fichierdest). Versions : PHP 3, PHP 4, PHP 5.

590 LE GUIDE COMPLET

Les fichiers et les rpertoires

Chapitre 18

Cette fonction permet de copier un chier dun emplacement de dpart vers un emplacement darrive. La fonction retourne true en cas de succs, sinon false.
if (!copy("/sites/monsite/images/titre.gif","/sites/monsite /titre.gif")) { print("la copie a chou"); } else { print("le fichier a t dplac dans le rpertoire /sites/monsite"); }

delete()
Reportez-vous la fonction unlink().

dirname()
j j

Signature : dirname ($chemin). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le rpertoire contenu dans $chemin :


$chemin = "/sites/monsite/images"; echo dirname ($chemin); // affiche : /sites/monsite

unlink()
j j

Signature : unlink ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet deffacer un chier. La fonction delete() est un alias de la fonction unlink(). Cette fonction retourne 0 ou false en cas derreur. Elle nest pas prise en charge sous Windows.

LE GUIDE COMPLET 591

Chapitre 18

Les fonctions PHP

disk_free_space()
j j

Signature : disk_free_space($repertoire). Versions : PHP 4 partir de la 4.0.7RC1, PHP 5.

Cette fonction retourne la place disponible sur la partition o se trouve le rpertoire (en octets). La fonction diskfreespace() est un alias de disk_free_space().

disk_total_space()
j j

Signature : disk_total_space($repertoire). Versions : PHP 4 partir de la 4.0.7RC1, PHP 5.

Cette fonction retourne la taille totale de la partition o se trouve le rpertoire.

fclose()
j j

Signature : fclose ($pfichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de fermer un pointeur sur chier (un identiant de chier). Elle retourne true en cas de succs, sinon false.

feof()
j j

Signature : feof ($pfichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne true si le pointeur du chier $pfichier est la n du chier (le caractre EOF, ou end of file, est rencontr), sinon false.

592 LE GUIDE COMPLET

Les fichiers et les rpertoires

Chapitre 18

fflush()
j j

Signature : fflush ($pfichier). Versions : PHP 4, PHP 5.

Cette fonction force lcriture de toutes les donnes buffrises dans le chier point par $pfichier. Elle retourne true en cas de succs, sinon false.

fgetc()
j j

Signature : fgetc ($pfichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne une chane dun caractre lue dans le chier point par $pfichier. La valeur false est retourne si le caractre de n de chier (EOF) est rencontr.

fgetcsv()
j j

Signature :

fgetcsv ($pfichier, $delimiteur]).

$longueur

[,

Versions : PHP 3 partir de la 3.0.8, PHP 4, PHP 5.

Cette fonction permet de lire des donnes ligne par ligne dans un chier CSV point par $pfichier. Pour chaque ligne, la fonction renvoie un tableau contenant toutes les donnes de la ligne. Si le caractre de sparation nest pas la virgule, il est possible de la spcier avec le paramtre $delimiteur. Supposez que le chier test.csv contienne les donnes suivantes :
paul,dupont,1982 eric,mullier,1981 marc,rissin,1982

Le script suivant permet dafficher toutes les donnes ligne par ligne :
$ligne = 1; $pfichier = fopen ("test.csv","r"); while ($tab = fgetcsv ($pfichier, 64)) { $num = count ($tab);

LE GUIDE COMPLET 593

Chapitre 18

Les fonctions PHP

print "<p> $num champs sur la ligne $row: <br>"; $ligne++; for ($c=0; $c < $num; $c++) { print $tab[$c] . "<br>"; } } fclose ($pfichier);

fgets()
j j

Signature : fgets ($pfichier, $ln). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de lire, ligne par ligne, le chier point par
$pfichier. Le chier est lu par blocs de $ln caractres :
$ligne = 1; $pfichier = fopen ("test.csv","r"); while ($ch = fgets ($pfichier, 64)) { print "ligne [$ligne] -> $ch<br>"; $ligne++; } fclose ($pfichier);

Avec la fonction fgetss(), la ligne reue est vide de toute balise HTML.

le()
j j

Signature : file ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction lit le contenu dun chier et place chaque ligne dans un tableau quelle retourne. Le chier peut tre local ou distant :
$tab = file ("http://www.google.fr"); $tab = file ("/sites/monsite/readme.txt");

le_exists()
j j

Signature : file_exists ($fichier). Versions : PHP 3, PHP 4, PHP 5.

594 LE GUIDE COMPLET

Les fichiers et les rpertoires

Chapitre 18

Cette fonction retourne true si le chier $fichier existe, sinon false. Cette fonction ne peut tre utilise quavec les chiers locaux :
if (file_exists($fichier)) { // actions sur le fichier }

leatime()
j j

Signature : fileatime ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la date laquelle le chier a t ouvert pour la dernire fois. Les fonctions filectime() et filemtime() retournent la date laquelle le chier a t modi pour la dernire fois. Pour filectime(), une modication correspond aussi un changement de permission. Ces fonctions ne peuvent tre utilises quavec des chiers locaux.

legroup()
j j

Signature : filegroup ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le groupe ID du propritaire du chier (ou


false en cas derreur). La valeur retourne est numrique.

Cette fonction naccepte que des chiers locaux et ne fonctionne pas sous Windows.

leinode()
j j

Signature : fileinode ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction renvoie le numro inode dun chier. Elle naccepte que des chiers locaux et ne fonctionne pas sous Windows.

LE GUIDE COMPLET 595

Chapitre 18

Les fonctions PHP

leowner()
j j

Signature : fileowner ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne lID du propritaire du chier (ou false en cas derreur). La valeur retourne est numrique. Cette fonction naccepte que des chiers locaux et ne peut tre utilise sous Windows.

leperms()
j j

Signature : fileperms ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne les permissions dun chier sous forme dun entier. Pour voir si un chier est en lecture publique et pour le groupe, on utilise les oprateurs sur les bits :
$permissions = fileperms("fichier.txt"); if (($permissions & 4) && ($permissions & 32)) ...

Cette fonction naccepte que des chiers locaux et ne peut tre utilise sous Windows.

lesize()
j j

Signature : filesize ($fichier). Versions : PHP 3, PHP 4 partir de la 4.0.0, PHP 5.

Cette fonction retourne la taille dun chier. Elle naccepte que des chiers locaux.

letype()
j j

Signature : filetype ($fichier). Versions : PHP 3, PHP 4, PHP 5.

596 LE GUIDE COMPLET

Les fichiers et les rpertoires

Chapitre 18

Cette fonction retourne le type du chier. Les valeurs possibles sont : fifo, lien, rpertoire, fichier, etc. Cette fonction naccepte que des chiers locaux.

ock()
j j

Signature : flock ($pfichier, $operation). Versions : PHP 3 partir de la 3.0.7, PHP 4, PHP 5.

Cette fonction permet de bloquer un chier point par $pfichier. Les diffrentes valeurs possibles de la fonction $operation sont :
j j j

LOCK_SH pour obtenir un blocage partag (lecture) ; LOCK_EX pour obtenir un blocage exclusif (criture) ; LOCK_UN pour librer les blocages.

La fonction retourne true en cas de succs, sinon false.

fopen()
j j

Signature : fopen ($fichier, $mode). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet douvrir un chier et de crer un pointeur sur chier, qui pourra par la suite tre utilis, par exemple, pour lire ou crire dans le chier. La fonction retourne false si louverture a chou. Il est possible douvrir un chier dans diffrents modes :
j r j j

ouvre le chier en lecture et place le pointeur au dbut du chier. r+ ouvre le chier en lecture et en criture et place le pointeur au dbut du chier. w ouvre le chier en criture et place le pointeur au dbut du chier. Si le chier existe, son contenu est effac ; sil nexiste, pas le chier est cr.

LE GUIDE COMPLET 597

Chapitre 18
j w+

Les fonctions PHP

j j

ouvre le chier en lecture et en criture et place le pointeur au dbut du chier. Si le chier existe, son contenu est effac ; sil nexiste pas, le chier est cr. a ouvre le chier en criture et place le pointeur la n du chier. Si le chier nexiste pas, il est cr. a+ ouvre le chier en lecture et en criture et place le pointeur la n du chier. Si le chier nexiste pas, il est cr.

La fonction fopen() peut ouvrir des chiers locaux et distants :


$pfichier = fopen("http://www.google.fr/index.html","r"); $pfichier = fopen("/sites/monsite/test.txt","w"); // si nous crivons dans le fichier les donnes sont ajoutes au dbut $pfichier = fopen("/sites/monsite/test.txt","w"); // si nous crivons dans le fichier les donnes sont ajoutes la fin

fpassthru()
j j

Signature : fpassthru ($pfichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction lit le chier point par $pfichier et affiche le rsultat. Seules les donnes situes en dessous de lendroit o pointe le chier sont renvoyes. La fonction readfile() est prfrer si vous souhaitez afficher tout un chier.

fputs()
Reportez-vous la fonction fwrite().

fread()
j j

Signature : fread ($pfichier, $ln). Versions : PHP 3, PHP 4, PHP 5.

598 LE GUIDE COMPLET

Les fichiers et les rpertoires

Chapitre 18

Cette fonction permet de lire dans un chier point par $pfichier par blocs de $ln octets. La lecture sarrte quand le caractre de n de chier est rencontr (EOF). Certains systmes comme Windows font une diffrence entre les chiers binaires et les chiers texte. Dans le cas dun chier binaire, le mode b doit tre ajout au mode $mode :
$fichier = "c:\\tmp\\image.gif"; $pfichier = fopen ($fichier, "rb"); $contenu = fread ($pfichier, filesize ($fichier)); fclose ($pfichier);

fscanf()
j j

Signature : fscanf ($pfichier, $format). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de lire dans un chier en utilisant un format, la manire de sscanf(). Si vous avez un chier de personnes .txt prsent de cette manire :
M Paul Dupont [1982] M Eric Mullier [1981] M Marc Rissin [1982]

Il est possible dextraire les donnes ligne par ligne de la manire suivante :
$pfichier = fopen ("personnes.txt","r"); while (list ($prenom, $nom, $annee) = fscanf ($pfichier, "M %s %s [%d]\n")) { print("$nom,$prenom,$annee<br>"); } fclose($pfichier);

fseek()
j j

Signature : fseek ($pfichier, $offset [, $origine]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dplacer le pointeur sur chier. La nouvelle position mesure en octets, par rapport au dbut du chier, est obtenue en ajoutant la valeur $offset la position indique par $origine : Le paramtre $origine peut prendre diffrentes valeurs :
LE GUIDE COMPLET 599

Chapitre 18
j j j

Les fonctions PHP

SEEK_SET : la nouvelle position vaut $offset octets. SEEK_CUR : la nouvelle position vaut la position courante ajoute $offset octets. SEEK_END : la nouvelle position vaut la position de n de chier ajoute $offset octets ($offset a donc intrt tre

ngatif !). Si le paramtre $origine nest pas prcis, la valeur par dfaut est
SEEK_SET.

La fonction retourne 0 en cas de succs, sinon 1.

fstat()
j j

Signature : fstat ($pfichier). Versions : PHP 4, PHP 5.

Cette fonction permet dobtenir des informations sur un chier ouvert. Ces informations sont regroupes dans un tableau. Le tableau contient les valeurs suivantes
j j j j j j j j j j j j j

0 : volume. 1 : inode. 2 : nombre de liens. 3 : nombre de liens. 4 : ID de lutilisateur propritaire. 5 : ID du groupe propritaire. 6 : type du volume de linode. 7 : taille en octets. 8 : date de dernier accs. 9 : date de dernire modication. 10 : date du dernier changement. 11 : taille de bloc du systme pour les entres et sorties. 12 : nombre de blocs allous.

La fonction stat() permet dobtenir les mmes informations en passant un nom de chier plutt quun identiant.

600 LE GUIDE COMPLET

Les fichiers et les rpertoires

Chapitre 18

ftell()
j j

Signature : ftell ($pfichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la position du pointeur $pfichier et retourne


false en cas derreur.

ftruncate()
j j

Signature : ftruncate ($pfichier,$taille). Versions : PHP 4, PHP 5.

Cette fonction prend le pointeur sur chier $pfichier et tronque le chier la taille $taille. La fonction retourne true en cas de succs, sinon false.

fwrite()
j j

Signature : fwrite ($pfichier, $ch [, $ln]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dcrire la chane de caractres $ch dans le chier point par $pfichier. Si le paramtre $ln est transmis, seuls $ln octets seront crits. La fonction retourne le nombre doctets crits en cas de succs, sinon 1.

getcwd()
j j

Signature : getcwd (). Versions : PHP 4, PHP 5.

Cette fonction retourne le rpertoire courant.

is_dir()
j j

Signature : is_dir ($fichier). Versions : PHP 3, PHP 4, PHP 5.


LE GUIDE COMPLET 601

Chapitre 18

Les fonctions PHP

Cette fonction retourne true si le chier $fichier est un rpertoire. Dautres fonctions permettent de tester un chier
j j j j j j

is_executable() : indique quil sagit dun chier excutable. is_file() : indique quil sagit dun chier et non un rpertoire. is_link() : indique un lien symbolique. is_readable() : le chier est accessible en lecture. is_writable(), is_writeable() : le chier est accessible en

criture.
is_uploaded_file() : le chier est envoy via la mthode HTTP POST.

Ces fonctions nacceptent que les chiers locaux.

link()
j j

Signature : link ($cible, $lien). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de crer un lien physique. Elle ne peut pas tre utilise sous Windows.

mkdir()
j j

Signature : mkdir ($repertoire, $mode). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de crer un rpertoire. Le mode doit tre prcis en octal et est modi par la valeur courante du paramtre umask :
mkdir ("/sites/monsite/contact", 0700); // cre le rpertoire contact dans le rpertoire /sites/monsite

Retourne true en cas de succs, sinon false.

move_uploaded_le()
j

Signature : move_uploaded_file ($fichier, $destination).

602 LE GUIDE COMPLET

Les fichiers et les rpertoires


j

Chapitre 18

Versions : PHP 4 partir de la 4.0.3, PHP 5.

Cette fonction permet de dplacer un chier tlcharg en upload.

opendir()
j j

Signature : opendir ($chemin). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet douvrir un identiant de rpertoire, laide duquel il sera possible de lister les chiers contenus dans ce rpertoire. Elle retourne false en cas derreur :
// // if le code ci-dessous permet de lister les fichiers (rpertoires inclus) contenus dans le rpertoire /tmp ($rep = @opendir("/tmp")) { while (($nomfichier = readdir($rep)) !== false) { echo "$nomfichier\n"; } closedir($rep);

Lexemple suivant permet de parcourir de manire rcursive une arborescence de chiers :


<?php function parcours($path) { if ($rep = @opendir($path)) { while (($fichier = readdir($rep))!== false) { if (is_dir($fichier)) { if ($fichier==. || $fichier==..) continue; parcours("$path/$fichier"); print("REP : $path/$fichier<br/>\n"); } else print("FICHIER : $path/$fichier<br/>\n"); } } closedir($rep); } parcours("."); ?>

LE GUIDE COMPLET 603

Chapitre 18

Les fonctions PHP

parse_ini_le()
j j

Signature : parse_ini_file ($fichier [, $section]). Versions : PHP 4, PHP 5.

Cette fonction retourne un tableau contenant les donnes stockes dans un chier .ini. Si $section vaut true, les sections sont prises en compte. Le chier test.ini contient :
[section1] val1 = 1 val2 = 2 [section2] nom = toto $tabini = parse_ini_file("test.ini"); print_r($tabini); /* affiche : Array ( [val1] => 1 [val2] => 2 [nom] => toto ) */ $tabini = parse_ini_file("test.ini", TRUE); print_r($tabini); /* affiche : Array ( [section1] => Array ( [val1] => 1 [val2] => 2 ) [section2] => Array ( [nom] => toto ) ) */

604 LE GUIDE COMPLET

Les fichiers et les rpertoires

Chapitre 18

pathinfo()
j j

Signature : pathinfo ($chemin). Versions : PHP 4 partir de la 4.0.3, PHP 5.

Cette fonction retourne un tableau associatif contenant des informations sur le chemin : dirname, basename et extension.
$tab echo echo echo = pathinfo("/sites/monsite/index.html"); $tab["dirname"] . "\n"; // affiche : /sites/monsite $tab["basename"] . "\n"; // affiche : index.html $tab["extension"] . "\n"; // affiche : html

popen()
j j

Signature : popen ($commande, $mode). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de crer un processus ls correspondant lexcution de la commande $commande (les plus rudits peuvent faire lanalogie avec le fork() du langage C).
$pfichier = popen ("/bin/ls", "r");

La fonction retourne un pointeur sur chier identique ceux qui ont t crs avec fopen(), la diffrence quil est unidirectionnel (il est possible soit dy crire, soit dy lire) et quil doit tre ferm avec la fonction pclose(). Les fonctions fgets(), fwrite(), etc., peuvent tre utilises avec un tel pointeur. La fonction retourne false en cas derreur.

readdir()
j j

Signature : readdir ($prep). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le nom du chier selon le contenu dans le rpertoire identi par $prep :

LE GUIDE COMPLET 605

Chapitre 18

Les fonctions PHP

// liste les fichiers contenus dans le rpertoire courant //(les rpertoires . et .. sont exclus) $prep = opendir(.); while (false !== ($nomfichier = readdir($prep))) { if ($nomfichier != "." && $file != "..") { echo "$nomfichier\n"; } } closedir($prep);

readle()
j j

Signature : readfile ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dafficher le contenu dun chier. Elle peut tre utilise avec des chiers distants :
readfile("ftp://ftp.monserver.com/readme.txt"); // le serveur ftp doit supporter le mode passif !

readlink()
j j

Signature : readlink ($lien). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la cible dun lien symbolique.

rename()
j j

Signature : rename ($vieuxnom, $nouveaunom). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de renommer un chier.


rename ("fichiers/toto.txt","fichiers/titi.txt"); // renomme toto.txt en titi.txt rename ("rep1/toto.txt","rep2/toto.txt"); // dplace toto.txt du rpertoire rep1 vers celui rep2

Retourne true en cas de succs, sinon false.

606 LE GUIDE COMPLET

Les fichiers et les rpertoires

Chapitre 18

rewind()
j j

Signature : rewind ($pfichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de faire pointer $pfichier sur le dbut du chier.

rewinddir()
j j

Signature : rewinddir ($prep). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de rinitialiser lidentiant de rpertoire et de le faire pointer sur le premier chier.

rmdir()
j j

Signature : rmdir ($repertoire). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet deffacer un rpertoire si celui-ci est vide. Pour pouvoir effacer un rpertoire non vide, il est ncessaire dcrire une petite fonction, qui se chargera daller effacer le contenu du rpertoire avant dappeler la fonction rmdir() sur ce mme rpertoire :
function supprim_rep($rep, $flag=0) { $tab_rep = array(); $tab_fichiers = array(); $prep = opendir ($rep); if (!$prep) { return null; } while ($fichier = readdir ($prep)) { if ($fichier == . || $fichier == ..) continue; if (is_dir ("$rep/$fichier")) { $tab_rep[] = $fichier; }

LE GUIDE COMPLET 607

Chapitre 18

Les fonctions PHP

else { $tab_fichiers[] = $fichier; } } $i = 0; while ($tab_rep[$i]) { supprim_rep ("$rep/$tab_rep[$i]",1); rmdir ("$rep/" . $tab_rep[$i]); $i++; } $i = 0; while ($tab_fichiers[$i]) { unlink ("$rep/$tab_fichiers[$i]"); $i++; } if ($flag == 0) rmdir ($rep); closedir($prep); return 1; }

La fonction sappelle de la manire suivante :


supprim_rep($nom_repertoire)

Le deuxime paramtre nest utilis quen interne au sein de la fonction.

set_le_buffer()
j j

Signature : set_file_buffer ($pfichier, $buffer). Versions : PHP 3 partir de la 3.0.8, PHP 4, PHP 5.

Cette fonction permet de modier la taille des buffers qui sont utiliss pour crire dans le chier point par $pfichier. La taille par dfaut est de 8 ko. En transmettant 0 comme valeur pour $buffer, lcriture nest plus buffrise . Lavantage est que lon est sr que les donnes sont bien crites ; linconvnient est que lon rduit considrablement les performances du systme.

608 LE GUIDE COMPLET

Les fichiers et les rpertoires

Chapitre 18

stat()
j j

Signature : stat ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction donne des informations sur un chier, comme fstat().


j j j j j j j j j j j j j

0 : volume. 1 : inode. 2 : mode de protection de linode. 3 : nombre de liens. 4 : ID de lutilisateur propritaire. 5 : ID du groupe propritaire. 6 : type du volume de linode. 7 : taille en octets. 8 : date du dernier accs. 9 : date de la dernire modication. 10 : date du dernier changement. 11 : taille de bloc du systme pour les entres et sorties. 12 : nombre de blocs allous.

lstat()
j j

Signature : lstat ($fichier). Versions : PHP 3 partir de la 3.0.4, PHP 4, PHP 5.

Cette fonction est identique stat(), sauf si le chier est un lien symbolique. Dans ce cas, cest le statut de ce lien qui est retourn.

realpath()
j j

Signature : realpath ($chemin). Versions : PHP 4, PHP 5.

Cette fonction retourne le vritable chemin, dtermin partir du paramtre $chemin. Les liens symboliques et les composantes (., ..) disparaissent.

LE GUIDE COMPLET 609

Chapitre 18

Les fonctions PHP

symlink()
j j

Signature : symlink ($cible, $lien). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction cre un lien symbolique.

tempnam()
j j

Signature : tempnam ($repertoire, $prefixe). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction cre un chier avec un nom unique dans le rpertoire


$repertoire. Le nom du chier est prx avec $prefixe. Le nom

du chier est retourn.

tmple()
j j

Signature : tmpfile (). Versions : PHP 3 partir de la 3.0.13, PHP 4, PHP 5.

Cette fonction cre un chier temporaire et retourne un pointeur sur ce chier :


$temp = tmpfile(); fwrite($temp, "ce fichier est temporaire"); fclose($temp);

touch()
j j

Signature : touch ($fichier [, $date]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de changer la date de modication du chier


$fichier. Si la date nest pas prcise, cest la date actuelle qui est

utilise. Si le chier nexiste pas, il est cr. La fonction retourne true en cas de succs, sinon false.

610 LE GUIDE COMPLET

Linterface avec MySQL

Chapitre 18

umask()
j j

Signature : umask ($masque). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de modier le paramtre umask courant.

unlink()
j j

Signature : unlink ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de supprimer un chier.

18.7. Linterface avec MySQL


Dans cette partie, vous utiliserez la norme suivante
j j j j j

$serverbdd : adresse du serveur de base de donnes. $utilisateur, $motdepasse : les identiants permettant de

sidentier auprs du serveur. $bdd : nom dune base. $liendb : identiant de connexion. $resultat : identiant de rsultat.

mysql_affected_rows()
j j

Signature : mysql_affected_rows ([$liendb]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le nombre de lignes qui ont t modies la suite de la dernire requte contenant une commande INSERT, UPDATE ou DELETE. Si $liendb nest pas prcis, la dernire connexion ouverte est utilise :
$liendb = mysql_connect(localhost, root, ); mysql_select_db (test); $sql = "UPDATE produit SET prix = prix + 1"; mysql_query ($sql); $n = mysql_affected_rows ($liendb);

LE GUIDE COMPLET 611

Chapitre 18

Les fonctions PHP

// $n = mysql_affected_rows(); fonctionnerait aussi echo "$n produits ont t mis jour"; mysql_close($liendb);

Fonction mysql_affected_rows() et UPDATE

Avec une requte UPDATE, MySQL ne met pas jour les colonnes o lancienne valeur est la mme que la nouvelle. De ce fait, la fonction mysql_affected_rows() ne retourne pas le nombre de lignes qui concident avec la requte.

Si la dernire requte a chou, la fonction retourne 1.

mysql_change_user()
j j

Signature : mysql_change_user ($utilisateur, $motdepasse[, $bdd , $liendb]]). Versions : PHP 3 partir de la 3.0.13, PHP 4, PHP 5.

Cette fonction permet de changer lutilisateur de la connexion courante (ou de la connexion spcie par $liendb). Si la base $bdd est prcise, elle deviendra la nouvelle base courante de la connexion. Si lauthentication choue, la connexion courante reste active.

mysql_close()
j j

Signature : mysql_close ([$liendb]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de fermer la connexion courante (ou la connexion identie par $liendb si le paramtre est prcis). Lutilisation de mysql_close() nest pas indispensable, dans la mesure o toutes les connexions non persistantes sont automatiquement fermes avec la terminaison du script. La fonction retourne true en cas de succs, sinon false.

612 LE GUIDE COMPLET

Linterface avec MySQL

Chapitre 18

mysql_connect()
j j

Signature : mysql_connect ([$serverbdd, $utilisateur, $motdepasse]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet douvrir une connexion avec une base de donnes. Si les paramtres ne sont pas prciss, les valeurs suivantes sont prises par dfaut : $serverbdd =localhost:3306. $utilisateur est le mme utilisateur que le propritaire du processus et $motdepasse est vide.
$liendb = mysql_connect ("localhost", "root", "") or die ("la connexion la base a chou"); print ("connexion russie"); mysql_close ($liendb);

Le paramtre $serverbdd peut contenir un numro de port (127.0.0.1:3306) ou un chemin vers le socket utilis pour la connexion (/var/lib/mysql/mysql.sock). Un nouvel appel cette fonction, avec les mmes paramtres, nouvre pas de nouvelle connexion, mais retourne le lien de connexion prcdemment ouvert. La fonction mysql_pconnect() ne diffre de mysql_connect() que par le fait que les connexions avec la base sont persistantes. De cette faon, la connexion avec la base nest pas ferme lorsque le script se termine, et peut ainsi tre rutilise par la suite.

mysql_create_db()
j j

Signature : mysql_create_db ($bdd [, $liendb]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de crer une base de donnes $bdd :


$liendb = mysql_connect(localhost, root, ); if (mysql_create_db ("boutique2")) { echo "base cre"; } else { printf("erreur lors de la cration de la base : %s",mysql_error()); }

LE GUIDE COMPLET 613

Chapitre 18

Les fonctions PHP

La fonction retourne true en cas de succs, sinon false.

mysql_data_seek()
j j

Signature : mysql_data_seek ($resultat, $ligne). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dplacer le pointeur contenu dans lidentiant de rsultat vers la ligne $ligne :
$liendb = mysql_connect(localhost, root, ); mysql_select_db (test); $sql = "SELECT nom FROM produit"; $resultat = mysql_query ($sql); while ($obj = mysql_fetch_object ($resultat)) echo "$obj->nom - "; // affiche : tee-shirt - sweat - casquette mysql_data_seek ($resultat, 1); // nous replaons au niveau de la ligne 1 print("<br>"); while ($obj = mysql_fetch_object ($resultat)) echo "$obj->nom - "; // affiche : sweat - casquette mysql_close($liendb);

La fonction retourne true en cas de succs, sinon false.

mysql_db_name()
j j

Signature : mysql_db_name ($bdds, $ligne). Versions : PHP 3 partir de la 3.0.6, PHP 4, PHP 5.

Cette fonction permet dobtenir le nom des bases. Le paramtre $bdds est le rsultat de lappel la fonction mysql_list_dbs() :
mysql_connect(localhost, root, ); $db_list = mysql_list_dbs(); $i = 0; $nbdd = mysql_num_rows($db_list); while ($i < $nbdd) { echo mysql_db_name($db_list, $i) . "\n"; $i++; }

614 LE GUIDE COMPLET

Linterface avec MySQL

Chapitre 18

mysql_db_query()
j j

Signature :
$liendb]).

mysql_db_query ($bdd,

$requete

[,

Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de slectionner une base de donnes et dexcuter, dans la foule, une requte sur cette base. La connexion courante est utilise si lidentiant de connexion $liendb nest pas prcis. partir de la version 4.0.6 de PHP, cette fonction ne peut plus tre utilise. Il est ncessaire de passer par mysql_select_db(), puis par mysql_query(). La fonction retourne un identiant de rsultat en cas de succs, sinon
false.

mysql_drop_db()
j j

Signature : mysql_drop_db ($bdd [, $liendb]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de supprimer une base. Elle retourne true en cas de succs, sinon false.

mysql_errno()
j j

Signature : mysql_errno ([$liendb]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le numro de lerreur de la dernire fonction MySQL utilise. La valeur 0 est utilise si aucune erreur na eu lieu.

mysql_error()
j j

Signature : mysql_error ([$leindb]). Versions : PHP 3, PHP 4, PHP 5.

LE GUIDE COMPLET 615

Chapitre 18

Les fonctions PHP

Cette fonction retourne le texte derreur de la dernire fonction MySQL utilise. La chane vide est transmise si aucune erreur na eu lieu.

mysql_escape_string()
j j

Signature : mysql_escape_string ($str). Versions : PHP 4 partir de la 4.0.3.

Cette fonction retourne la chane $str, dans laquelle les caractres NUL, (\x00), \n, \r, \, , " et \x1a sont prcds dun antislash \. La fonction addslashes() se contente de prcder dun \ les caractres NUL, , " et \.

mysql_fetch_array()
j j

Signature : mysql_fetch_array ($resultat [, $type]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne un tableau des donnes lues dans lidentiant de rsultat $resultat. En cas derreur, la fonction retourne false. Le paramtre optionnel $type peut prendre diffrentes valeurs.
j j j

MYSQL_ASSOC : les donnes sont accessibles par leur nom. Le comportement est alors le mme que mysql_fetch_assoc(). MYSQL_NUM : les donnes sont accessibles par index. Le comportement est alors le mme que mysql_fetch_rox(). MYSQL_BOTH : combine les mthodes nom et index. Cest la valeur par dfaut.
$liendb = mysql_connect(localhost, root, ); mysql_select_db (test); $sql = "SELECT reference, nom FROM produit"; $resultat = mysql_query ($sql); while ($tab = mysql_fetch_array ($resultat,MYSQL_ASSOC)) { echo $tab[nom]; } mysql_close($liendb);

616 LE GUIDE COMPLET

Linterface avec MySQL

Chapitre 18

$liendb = mysql_connect(localhost, root, ); mysql_select_db (test); $sql = "SELECT reference, nom FROM produit"; $resultat = mysql_query ($sql); while ($tab = mysql_fetch_array ($resultat,MYSQL_NUM)) { echo $tab[1]; } mysql_close($liendb);

mysql_fetch_eld()
j j

Signature : mysql_fetch_field ($resultat [,$offset]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne un objet contenant des informations sur une colonne.
j j j j j j j j j j j j

name : nom de la colonne. table : nom de la table. max_length : taille maximale de la colonne. not_null : 1 si la colonne ne peut pas tre NULL (attribut NOT NULL). primary_key : 1 si la colonne est une cl primaire (attribut PRIMARY KEY). unique_key : 1 si la colonne est une cl unique (attribut UNIQUE). multiple_key : 1 si la colonne est une cl non unique. numeric : 1 si la colonne est numrique. blob : 1 si la colonne est BLOB. type : le type de la colonne. unsigned : 1 si la colonne est non signe. zerofill : 1 si la colonne est complte par des zros.
$liendb = mysql_connect(localhost, root, ); mysql_select_db (test); $sql = "SELECT idproduit FROM produit"; $resultat = mysql_query ($sql); $meta = mysql_fetch_field ($resultat); echo "<PRE> blob: $meta->blob max_length: $meta->max_length

LE GUIDE COMPLET 617

Chapitre 18

Les fonctions PHP

multiple_key: $meta->multiple_key name: $meta->name not_null: $meta->not_null numeric: $meta->numeric primary_key: $meta->primary_key table: $meta->table type: $meta->type unique_key: $meta->unique_key unsigned: $meta->unsigned zerofill: $meta->zerofill </PRE>"; mysql_close($liendb);

mysql_fetch_object()
j j

Signature : mysql_fetch_object ($resultat [, $type]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne un objet dont les attributs sont les donnes lues dans lidentiant de rsultat $resultat. La valeur false est retourne en cas derreur.
$liendb = mysql_connect(localhost, root, ); mysql_select_db (test); $sql = "SELECT reference, nom FROM produit"; $resultat = mysql_query ($sql); while ($obj = mysql_fetch_object ($resultat)) { echo $obj->nom; } mysql_close($liendb);

Comme pour mysql_fetch_array(), le paramtre $type peut tre utilis.

mysql_free_result()
j j

Signature : mysql_free_result ($resultat). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction libre toute la mmoire associe lidentiant de rsultat


$resultat.

Cette fonction peut tre intressante quand, en plein milieu dun script, vous procdez une requte importante sur la base.

618 LE GUIDE COMPLET

Linterface avec MySQL

Chapitre 18

La fonction retourne true en cas de succs, sinon false.

mysql_insert_id()
j j

Signature : mysql_insert_id ([$liendb]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne lid gnr dans la colonne en AUTO INCREMENT par la dernire requte INSERT.
$liendb = mysql_connect(localhost, root, ); mysql_select_db (test); $sql = "INSERT INTO produit (reference) VALUES (PROD004)"; mysql_query ($sql); echo "le produit a bien t ajout la table, son id est : " . mysql_insert_id(); mysql_close($liendb);

La fonction retourne 0 si la prcdente requte na pas gnr une valeur auto-incrmente.

mysql_list_dbs()
j j

Signature : mysql_list_dbs ([$liendb]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne un identiant de rsultat contenant la liste des bases prsentes sur le serveur :
$liendb = mysql_connect(localhost, root, ); $list = mysql_list_dbs($liendb); while ($obj = mysql_fetch_object($list)) { echo $obj->Database . "\n"; }

mysql_list_elds()
j j

Signature : mysql_list_fields ($bdd, $table [, $liendb]). Versions : PHP 3, PHP 4, PHP 5.

LE GUIDE COMPLET 619

Chapitre 18

Les fonctions PHP

Cette fonction retourne les colonnes prsentes dans une table :


$liendb = mysql_connect(localhost, root, ); $colonnes = mysql_list_fields("test", "eleve", $liendb); $nbcol = mysql_num_fields($colonnes); for ($i = 0; $i < $nbcol; $i++) { echo mysql_field_name($colonnes, $i) . "\n"; }

mysql_list_tables()
j j

Signature : mysql_list_tables ($bdd, [$liendb]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dobtenir la liste des tables prsentes dans la base $bdd :
$liendb = mysql_connect(localhost, root, monpasword); mysql_select_db("test"); $tables = mysql_list_tables("test"); while ( list ($table) = mysql_fetch_array($tables)) { echo $table; }

mysql_num_elds()
j j

Signature : mysql_num_fields ($resultat). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le nombre de colonnes contenues dans lidentiant de rsultat.

mysql_num_rows()
j j

Signature : mysql_num_rows ($resultat). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le nombre de lignes contenues dans lidentiant de rsultat :


$liendb = mysql_connect(localhost, root, ); mysql_select_db (test); $sql = "SELECT idproduit FROM produit WHERE prix 20 ";

620 LE GUIDE COMPLET

Linterface avec MySQL

Chapitre 18

$resultat = mysql_query ($sql); echo "cette table contient " . mysql_num_rows($resultat) . " produits ayant un prix 20"; mysql_close($liendb);

mysql_query()
j j

Signature : mysql_query ($requete [, $liendb]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de transmettre une requte la base. Seule la commande SELECT permet dobtenir un identiant de rsultat. La fonction retourne false en cas dchec. Il est dsormais impossible denvoyer deux requtes en mme temps la base. Cela vite de nombreux problmes de scurit :
mysql_query ("SELECT * FROM produit; DROP test"); // impossible

mysql_result()
j j

Signature :
$colonne]).

mysql_result ($resultat,

$ligne

[,

Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de rcuprer le contenu dune donne se trouvant dans lidentiant de rsultat. Le paramtre $colonne peut, la fois, tre un index ou un nom de colonne.

mysql_select_db()
j j

Signature : mysql_select_db ($bdd [, $liendb]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dinitialiser la base courante. Elle retourne true en cas de succs, sinon false. Toutes les requtes effectues sur le serveur avec la fonction mysql_query() sont faites sur la base courante.

LE GUIDE COMPLET 621

Chapitre 18

Les fonctions PHP

mysql_get_client_info()
j j

Signature : mysql_get_client_info(). Versions : PHP 4 partir de la 4.0.5, PHP 5.

Cette fonction retourne la version de la librairie MySQL cliente :


echo mysql_get_client_info(); // affiche par exemple : 3.23.39

mysql_get_host_info()
j j

Signature : mysql_get_host_info ([$liendb]). Versions : PHP 4 partir de la 4.0.5, PHP 5.

Cette fonction retourne le type de connexion :


echo mysql_get_host_info(); //affiche par exemple : Localhost via UNIX socket

mysql_get_proto_info()
j j

Signature : mysql_get_proto_info ([$liendb]). Versions : PHP 4 partir de la 4.0.5, PHP 5.

Cette fonction retourne la version du protocole :


echo mysql_get_proto_info(); // affiche par exemple : 10

mysql_get_server_info()
j j

Signature : mysql_get_server_info(). Versions : PHP 4 partir de la 4.0.5, PHP 5.

Cette fonction retourne la version du serveur :


echo mysql_get_server_info(); // affiche par exemple : 3.23.41

18.8. Les images


Pour toutes les fonctions qui suivent, lorigine de limage (0, 0) est situe dans langle suprieur gauche de limage.
622 LE GUIDE COMPLET

Les images

Chapitre 18

$img correspond un identiant dimage, cr par exemple avec ImageCreate().

getimagesize()
j j

Signature : getimagesize ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne un tableau contenant les dimensions dune image. Le chier peut tre local ou distant :
$tab = GetImageSize ("http://www.php.net/gifs/logo.gif"); echo "largeur : " . $tab[0]; // affiche 130 echo "longueur : " . $tab[1]; // affiche 67

Deux autres lments sont prsents dans le tableau :


j j

le type de limage (1 reprsente le format GIF, 2 JPEG, 3 PNG, 4 SWF, 5 PSD, 6 BMP) ; une chane du type height=xxx width=xxx, qui peut tre utilise directement dans une balise <IMG>.

Image2WBMP()
j j

Signature : Image2WBMP ($img [, $fichier]). Versions : PHP 4 partir de la 4.0.5, PHP 5.

Cette fonction permet de convertir une image au format WBMP (format dimage pour le Wap, par exemple). Si le paramtre $fichier nest pas transmis, le contenu est affich directement lcran.

ImageAlphaBlending()
j j

Signature : ImageAlphaBlending($img, $mode). Versions : PHP 4 partir de la 4.0.6, PHP 5.

Cette fonction permet de passer en mode alpha pour les fonctions daffichage. Cela signie que les couleurs disposeront dune dimension en

LE GUIDE COMPLET 623

Chapitre 18

Les fonctions PHP

plus : la transparence. Le paramtre $mode doit prendre la valeur true pour passer en mode de transparence. Cette fonction doit tre utilise avec des images cres en mode True Color. La fonction ImageCreate Truecolor($dimX,$dimY) permet de crer une telle image.
Listing 18-1 : Transparence dans les images <? $imOrigine = @imagecreatefrompng ("logo.png"); $im = ImageCreateTrueColor(276,110); // copie de limage dans une image en True Color ImageCopy($im,$imOrigine,0,0,0,0,276,110); ImageFilledRectangle($im,0,0,92,110,0x00ff1111); // passage en mode transparence ImageAlphaBlending($im,true); ImageFilledRectangle($im,92,0,184,110,0x20ff1111); ImageFilledRectangle($im,184,0,276,110,0x60ff1111); Header(Content-Type: image/png); ImagePNG($im); ?>

Figure 18.2 : Exemple de lutilisation des transparences

ImageArc()
j j

Signature : ImageArc ($img, $cx, $cy, $larg, $haut, $deb, $fin, $coul). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dessiner une ellipse partielle, centre sur le point de coordonnes ($cx, $cy) dans limage identie par $img. Lellipse a pour largeur $larg et pour hauteur $haut. Les points de dpart et darrive sont spcis par $deb et $fin, et sont indiqus en degrs (dans le sens des aiguilles dune montre).
624 LE GUIDE COMPLET

Les images $coul est un identiant de couleur.


<?php Header ("Content-type: image/png"); $img = ImageCreate (250, 250);

Chapitre 18

$blanc = ImageColorAllocate ($img, 255, 255, 255); $noir = ImageColorAllocate ($img, 0, 0, 0); ImageArc ($img, 125, 125, 120, 90, 0, 230, $noir); // lellipse partielle ImageArc ($img, 125, 125, 50, 50, 0, 360, $noir); // le cercle central ImagePng ($img); ImageDestroy ($img); ?>

Figure 18.3 : Une ellipse incomplte et un cercle

ImageChar()
j j

Signature : ImageChar ($img, $coul). Versions : PHP 3, PHP 4, PHP 5.

$font,

$x,

$y,

$c,

Cette fonction dessine dans limage identie par $img le premier caractre de la chane $c. Le point ($x,$y) correspond langle suprieur gauche du caractre. Si la valeur de $font est 1, 2, 3, 4 ou 5, une des polices par dfaut sera utilise. La fonction ImageCharUp() verticalement. permet dafficher le caractre

LE GUIDE COMPLET 625

Chapitre 18

Les fonctions PHP

ImageColorAllocate()
j j

Signature : ImageColorAllocate ($img, $rouge, $ver, $bleu). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de crer un nouvel identiant de couleur, qui pourra tre utilis dans limage $img. Les paramtres $rouge, $vert, $bleu sont compris entre 0 et 255 :
$blanc = ImageColorAllocate ($img, 255, 255, 255); $noir = ImageColorAllocate ($img, 0, 0, 0);

En multipliant le nombre de couleurs alloues, vous obtiendrez facilement un dgrad :


Listing 18-2 : Dgrad <? $im = ImageCreate(300,256); for($r=0; $r<256; $r++) { $col = ImageColorAllocate($im,$r,0,0); ImageLine($im, 0,$r, 100, $r, $col); } for($g=0; $g<256; $g++) { $col = ImageColorAllocate($im,0,$g,0); ImageLine($im, 100,255-$g, 200, 255-$g, $col); } for($b=0; $b<256; $b++) { $col = ImageColorAllocate($im,0,0,$b); ImageLine($im, 200,$b, 300, $b, $col); } Header(Content-Type: image/png); ImagePNG($im); ?>

Figure 18.4 : Affichage du dgrad

626 LE GUIDE COMPLET

Les images

Chapitre 18

ImageColorDeAllocate()
j j

Signature : ImageColorDeAllocate ($img, $coul). Versions : PHP 3 partir de la 3.0.6, PHP 4, PHP 5.

Cette fonction permet de dsattribuer une couleur dune image.

ImageColorAt()
j j

Signature : ImageColorAt ($img, $x, $y). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de rcuprer lidentiant de couleur du pixel de coordonnes ($x, $y).

ImageColorClosest()
j j

Signature : ImageColorClosest ($img, $rouge, $vert, $bleu). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne lidentiant de couleur de la palette de limage


$img, qui est la plus proche de la couleur dnie par les composantes ($rouge, $vert, $bleu).

ImageColorExact()
j j

Signature : ImageColorExact ($img, $bleu). Versions : PHP 3, PHP 4, PHP 5.

$rouge,

$vert,

Cette fonction retourne lidentiant de couleur spci par les composantes ($rouge, $vert, $bleu). La valeur 1 est retourne si la couleur nest pas prsente dans la palette.

ImageGammaCorrect()
j j

Signature : ImageGammaCorrect ($img, $outgamma).

$inputgamma,

Versions : PHP 3 partir de la 3.0.13, PHP 4, PHP 5.

LE GUIDE COMPLET 627

Chapitre 18

Les fonctions PHP

Cette fonction applique une correction gamma limage identie par $img.

ImageColorsTotal()
j j

Signature : ImageColorsTotal ($img). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le nombre de couleurs prsentes dans la palette de limage.

ImageColorTransparent()
j j

Signature : ImageColorTransparent ($img, $coul). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dnir quel est lidentiant de couleur qui correspond au transparent dans limage.

ImageCopy()
j

Signature : ImageCopy ($dest_img, $orig_img, $dest_x, $dest_y, $orig_x, $orig_y, $orig_larg, $orig_haut). Versions : PHP 3 partir de la 3.0.6, PHP 4, PHP 5.

Cette fonction copie une partie dune image dorigine ($orig_img) vers une image de destination ($dest_img). Pour limage de dpart, les coordonnes de langle suprieur gauche de la partie extraire sont prcises, ainsi que la largeur et la hauteur de cette mme partie. Pour limage de destination, seules les coordonnes de lendroit o va tre copie la zone sont prcises.

ImageCreate()
j j

Signature : ImageCreate ($larg, $haut). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction cre une image de largeur $larg et de longueur $long. Un identiant dimage est retourn.

628 LE GUIDE COMPLET

Les images

Chapitre 18

ImageCreateFromGIF()
j j

Signature : ImageCreateFromGIF ($fichier). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de crer un identiant dimage partir dune image GIF (prsente localement ou distance). Dautres fonctions permettent de faire exactement la mme chose pour dautres formats : ImageCreateFromJPEG(), ImageCreate FromPNG(), ImageCreateFromWBMP(), ImageCreate FromString() (limage est cre partir dune chane de caractres), ImageCreateFromXBM(), ImageCreateFromXPM().

ImageDestroy()
j j

Signature : ImageDestroy ($img). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dtruire toute la mmoire associe lidentiant dimage $img.

ImageFill()
j j

Signature : ImageFill ($img, $x, $y, $coul). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de remplir une rgion de limage avec la couleur reconnue par lidentiant de couleur $coul. Langle suprieur gauche de la rgion a pour coordonnes ($x, $y).

ImageFilledPolygon()
j j

Signature : ImageFilledPolygon ($img, $nbpoints, $coul). Versions : PHP 3, PHP 4, PHP 5.

$tabpoints,

Cette fonction permet de dessiner dans $img un polygone plein, de couleur $coul. Le tableau doit tre conu de la manire suivante : $tabpoints[0] correspond x0, $tabpoints[1] y0,
LE GUIDE COMPLET 629

Chapitre 18

Les fonctions PHP

$tabpoints[2] x1, $tabpoints[3] y1, etc. Le paramtre $nbpoints contient le nombre de sommets du polygone.

ImageFilledRectangle()
j j

Signature :

ImageFilledRectangle ($img, $x2, $y2, $coul).

$x1,

$y1,

Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dessiner un rectangle plein.

ImageFillToBorder()
j j

Signature : ImageFillToBorder ($img, $x, $y, $coulbord, $coul). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction remplit avec la couleur $coul toute la rgion limite par la couleur $coulbord. Le point de dpart est ($x,$y) :
<?php Header ("Content-type: image/png"); $img = ImageCreate (250, 250); $gris = ImageColorAllocate ($img, 204, 204, 204); $bleu = ImageColorAllocate ($img, 0, 0, 255); $bleugris = ImageColorAllocate ($img, 173, 173, 205); ImageLine ($img, 0, 150, 150, 0, $bleu); imagefilltoborder ($img, 10, 10, $bleu, $bleugris); ImagePng ($img); ImageDestroy ($img); ?>

Figure 18.5 : Remplissage depuis le point (10, 10)

630 LE GUIDE COMPLET

Les images

Chapitre 18

Si vous choisissez, maintenant, le point de coordonnes (200, 200), cest lautre zone qui est remplie avec la couleur gris-bleu.

Figure 18.6 : Remplissage depuis le point (200, 200)

ImageFontHeight()
j j

Signature : ImageFontHeight ($font). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la hauteur (en pixels) dun caractre de la fonte


$font.

ImageFontWidth()
j j

Signature : ImageFontWidth ($font). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la largeur (en pixels) dun caractre de la fonte


$font.

ImageGIF()
j j

Signature : ImageGIF ($img [, $fichierimage]). Versions : PHP 3, PHP 4, PHP 5.

LE GUIDE COMPLET 631

Chapitre 18

Les fonctions PHP

Cette fonction permet de gnrer le contenu de limage identie par $img au format GIF. Si le paramtre $fichierimage nest pas prcis, le contenu est affich directement lcran. Cette fonction nest plus disponible avec les versions de la libGD suprieures ou gales 1.6. Dautres formats peuvent tre gnrs avec les fonctions suivantes
j j j

ImagePNG() : gnration au format PNG. ImageJPEG() : gnration au format JPEG. ImageWBMP() : gnration au format WBM.
Header ("Content-type: image/png"); $img = ImageCreate (180, 125); $bleu = ImageColorAllocate ($img, 0, 0, 255); $blanc = ImageColorAllocate ($img, 255, 255, 255); // gnration dun carr blanc dans un rectangle blanc ImageFilledRectangle ($img, 50, 50, 105, 105, $blanc); ImagePng ($img);

Figure 18.7 : Exemple dune image PNG gnre la vole

ImageInterlace()
j j

Signature : ImageInterlace ($img [, $interlace]). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dactiver ou de dsactiver le bit dentrelacement. Si le paramtre $interlace vaut 1, limage sera interlace ; sil vaut 0, elle ne le sera pas.

632 LE GUIDE COMPLET

Les images

Chapitre 18

Si le bit dentrelacement est activ et que le format de limage soit JPEG, limage sera cre en tant que JPEG progressif.

ImageLine()
j j

Signature : ImageLine ($img, $x1, $y1, $x2, $y2,


$coul).

Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de tracer une ligne de couleur $coul entre un point dorigine ($x1,$y1) et un point nal ($x2,$y2).

ImageLoadFont()
j j

Signature : ImageLoadFont ($fichierfont). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de charger un chier de police de caractres. La fonction retourne un identiant de fonte.

ImagePaletteCopy()
j j

Signature : ImagePaletteCopy ($imgsrc, $imgdest). Versions : PHP 4, PHP 5.

Cette fonction permet de copier la palette dune image $imgsrc vers une image $imgdest.

ImagePolygon()
j j

Signature : ImagePolygon ($img, $tabpoints, $nbpoints, $coul). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dessiner dans $img un polygone de couleur $coul. Le tableau doit tre conu de la manire suivante : $tabpoints[0] correspond x0, $tabpoints[1] y0, $tabpoints[2] x1, $tabpoints[3] y1, etc. Le paramtre $nbpoints contient le nombre de sommets du polygone :

LE GUIDE COMPLET 633

Chapitre 18

Les fonctions PHP

<?php Header ("Content-type: image/png"); $img = ImageCreate (250, 250); // couleur du fond de limage $gris = ImageColorAllocate ($img, 204, 204, 204); $bleu = ImageColorAllocate ($img, 0, 0, 255); // dfinition des sommets $tab_sommets = array ( "20", // abscisse point 1 "100", // ordonne point 1 "80", // abscisse point 2 "20", // ordonne point 2 "180", // abscisse point 3 "20", // ordonne point 3 "230", // abscisse point 4 "100", // ordonne point 4 "150", // abscisse point 5 "220", // ordonne point 5 ); ImagePolygon ($img, $tab_sommets, 5, $bleu); ImagePng ($img); ImageDestroy ($img); ?>

Figure 18.8 : Fonction ImagePolygon()

ImageRectangle()
j j

Signature : ImageRectangle ($img, $x1, $y1, $x2, $y2,


$coul).

Versions : PHP 3, PHP 4, PHP 5.

634 LE GUIDE COMPLET

Les images

Chapitre 18

Cette fonction permet de dessiner un rectangle.

ImageSetPixel()
j j

Signature : ImageSetPixel ($img, $x, $y, $coul). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de changer la couleur dun pixel.

ImageString()
j j

Signature : ImageString ($img, $font, $x, $y, $str, $coul). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dessiner la chane de caractres $str dans limage $img. Si $font vaut 1, 2, 3, 4 ou 5, une police par dfaut est utilise.
ImageStringUp() permet de dessiner la chane en vertical.

ImageSX()
j j

Signature : ImageSX ($img). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la largeur dune image reprsente par lidentiant dimage $img.
ImageSY() retourne la hauteur.

FonctionImageTTFBBox()
j j

Signature : ImageTTFBBox ($taille, $fichierfont, $str). Versions : PHP 3 partir de la 3.0.1, PHP 4, PHP 5.

$angle,

Cette fonction retourne un tableau contenant les coordonnes de la rgion qui entoure la zone de texte dessine avec les paramtres suivants
LE GUIDE COMPLET 635

Chapitre 18
j j j j

Les fonctions PHP

$taille : taille de la fonte. $angle : angle, en degrs, fait par le texte par rapport

lhorizontal.
$fichierfont : chemin daccs la fonte. $str : texte dessiner.

Les lments du tableau sont les suivants


j j j j j j j j

0 : abscisse de langle infrieur gauche. 1 : ordonne de langle infrieur gauche. 2 : abscisse de langle infrieur droit. 3 : ordonne de langle infrieur droit. 4 : abscisse de langle suprieur droit. 5 : ordonne de langle suprieur droit. 6 : abscisse de langle suprieur gauche. 7 : ordonne de langle suprieur gauche.

ImageTTFText()
j j

Signature : ImageTTFText ($img, $taille, $angle, $x, $y, $coul, $fichierfont, $str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dessiner la chane de caractres $str dans limage $img. Le point de coordonnes ($x, $y) correspond langle infrieur gauche. Le nom, la couleur et la taille de la fonte peuvent tre prciss avec les paramtres $taille, $coul, et $fichierfont. Langle (en degrs) que fait le texte avec lhorizontal est prcis par $angle (la valeur 90 permet dafficher le texte verticalement) :
Header ("Content-type: image/png"); $img = ImageCreate (180, 125); $blue = ImageColorAllocate ($img, 0, 0, 255); $white = ImageColorAllocate ($img, 255, 255, 255); ImageTTFText ($img, 8, 0, 10, 20, $white, "./verdana.ttf", "test"); ImagePng ($img);

636 LE GUIDE COMPLET

Les images

Chapitre 18

Figure 18.9 : Image contenant du texte gnre la vole

La fonction retourne les coordonnes de la rgion entourant le texte. Reportez-vous la fonction ImageTTFBBox().

ImageTypes()
j j

Signature : ImageTypes(). Versions : PHP 3 CVS seulement, PHP 4 partir de la 4.0.2, PHP 5.

Cette fonction permet de savoir quels formats dimage sont pris en charge. Cette fonction renvoie un champ de bits. Les diffrents paramtres de format possibles sont : IMG_GIF,
IMG_JPG, IMG_PNG, IMG_WBMP.
if (ImageTypes() & IMG_PNG) echo "le format PNG est support";

JPEG2WBMP()
j j

Signature : JPEG2WBMP ($fichierjpeg, $haut, $larg). Versions : PHP 4 partir de la 4.0.5, PHP 5.

$fichierwbm,

Cette fonction permet de convertir une image JPEG en une image WBM de largeur $larg et de hauteur $haut.
PNG2WBMP() fonctionne sur le mme modle.

LE GUIDE COMPLET 637

Chapitre 18

Les fonctions PHP

18.9. Les variables


empty ()
j j

Signature : empty ($var). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne FALSE si la variable $var est dnie ou bien si sa valeur est diffrente de 0.

gettype ()
j j

Signature : gettype ($var). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le type de la variable $var. Les diffrents types sont : boolean, integer, double, string, array, object, resource, NULL. Les fonctions de test du type sont les suivantes
j j j j j j j j j j j j

is_array ($var) : permet de tester si la variable $var est un

tableau.
is_bool ($var) : teste si $var est un boolen. is_double() : alias de la fonction is_float(). is_float ($var) : teste si $var est un nombre virgule

(ottant).
is_int ($var) : teste si $var est un entier. is_integer() : alias de la fonction is_int(). is_long() : alias de la fonction is_int(). is_null ($var) : teste si $var a une valeur gale NULL. is_numeric ($var) : teste si $var est un nombre ou une

chane de caractres contenant un nombre. is_object ($var) : teste si $var est un objet. is_real() : alias de la fonction is_float(). is_resource ($var) : teste si $var est de type ressource (pointeur sur chier, identiant de connexion, etc.).

638 LE GUIDE COMPLET

Les variables
j

Chapitre 18

is_scalar ($var) : teste si $var est un scalaire (cest--dire

un entier, un nombre ottant, un boolen ou une chane de caractres). is_string ($var) : teste si $var est une chane de caractres.
<?php $x = 1; if if if if if if (is_string($x)) echo "string"; // affiche string (is_numeric($x)) echo "numeric"; // affiche numeric (is_bool($x)) echo "boolen"; (is_double($x)) echo "double"; (is_float($x)) echo "float"; (is_int($x)) echo "int";

$x = 1 + 0; if if if if if if ?> (is_string($x)) echo "string"; (is_numeric($x)) echo "numeric"; // affiche numeric (is_bool($x)) echo "boolen"; (is_double($x)) echo "double"; (is_float($x)) echo "float"; (is_int($x)) echo "int"; // affiche int

isset()
j j

Signature : isset ($var). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction renvoie true si la variable $var est dnie.

print_r()
j j

Signature : print_r($tab). Versions : PHP 4, PHP 5.

Cette fonction permet dafficher le contenu dun tableau. Il est intressant dentourer la fonction des balises <pre> et </pre> pour rendre laffichage du tableau plus lisible :

LE GUIDE COMPLET 639

Chapitre 18

Les fonctions PHP

$tab = array ("a" => array ("b","c"), "d" => 1, "e" => array (2,3)); echo "<pre>"; print_r($tab); echo "</pre>"; /* affiche : Array ( [a] => Array ( [0] => b [1] => c ) [d] => 1 [e] => Array ( [0] => 2 [1] => 3 ) ) */

settype()
j j

Signature : settype ($var, $type). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de forcer le type dune variable :


$var1 = "5toto"; // string $var2 = true; // boolean settype($var1, "integer"); // $var1 vaut maintenant 5

(integer)

settype($var2, "string"); // $var2 vaut maintenant "1" (string)

unset()
j j

Signature : unset ($var). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de supprimer une variable. Elle peut tre utilise pour effacer un lment dun tableau :

640 LE GUIDE COMPLET

Les variables

Chapitre 18

$tab = array ("a" => array ("b","c"), "d" => 1, "e" => 2); unset($tab[d]); echo "<pre>"; print_r($tab); echo "</pre>"; /* affiche : Array ( [a] => Array ( [0] => b [1] => c ) [e] => 2 ) */

Si le tableau est de type scalaire, prenez garde ne pas utiliser une boucle pour parcourir tout le tableau :
$tab = array (a,b,c,d); unset($tab[2]); $i = 0; while ($tab[$i]) { echo "$tab[$i] - "; $i++; } // affiche a - b // en effet llment 2 nexiste plus, $tab[2] est // quivalent false echo "<pre>"; print_r($tab); echo "</pre>"; /* affiche Array ( [0] => a [1] => b [3] => d ) */

var_dump()
j j

Signature : var_dump ($var1 [,$var2]). Versions : PHP 3 partir de la 3.0.5, PHP 4, PHP 5.

LE GUIDE COMPLET 641

Chapitre 18

Les fonctions PHP

Cette fonction permet dafficher des informations sur une ou plusieurs variables :
$var1 = 10.5; $var2 = true; var_dump($var1,$var2); /* affiche : float(10.5) bool(true) */

18.10. La conguration PHP


dl()
j j

Signature : dl ($extension). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de charger une extension :


dl("xml.so"); // pour charger lextension XML sous UNIX dl("xml.dll"); // pour charger lextension XML sous windows

getenv()
j j

Signature : getenv ($var). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de rcuprer le contenu dune variable denvironnement :


echo getenv ("HOSTTYPE"); // affiche par exemple : i386

get_cfg_var()
j j

Signature : get_cfg_var ($var). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de rcuprer le contenu dune variable de conguration PHP :

642 LE GUIDE COMPLET

La configuration PHP
echo get_cfg_var ("file_uploads"); // affiche par exemple : 1 , il est donc possible // duploader des fichiers

Chapitre 18

get_current_user()
j j

Signature : get_current_user(). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne le nom du propritaire du script en cours dexcution :


echo get_current_user(); // affiche par exemple : nobody

Avec la fonction getmyuid(), cest le USER ID du propritaire qui est retourn :


echo getmyuid(); // affiche par exemple : 99

get_dened_constants()
j j

Signature : get_defined_constants(). Versions : PHP 4 partir de la 4.0.7RC1, PHP 5.

Cette fonction retourne un tableau contenant toutes les constantes dnies (y compris celles qui sont dnies par les extensions).

get_extension_funcs()
j j

Signature : get_extension_funcs ($module). Versions : PHP 4, PHP 5.

Cette fonction retourne la liste des fonctions prsentes dans le module


$module :
print_r (get_extension_funcs ("gd"));

getmygid()
j j

Signature : getmygid(). Versions : PHP 4 partir de la 4.0.7RC1, PHP 5.

Cette fonction retourne le GROUP ID du propritaire du script courant.


LE GUIDE COMPLET 643

Chapitre 18

Les fonctions PHP

get_loaded_extensions()
j j

Signature : get_loaded_extensions(). Versions : PHP 4, PHP 5.

Cette fonction retourne un tableau contenant le nom de toutes les extensions charges.

get_magic_quotes_gpc()
j j

Signature : get_magic_quotes_gpc(). Versions : PHP 3 partir de la 3.0.6, PHP 4, PHP 5.

Cette fonction permet de savoir si les magic quotes fonctionnent. Labrviation gpc (get/post/cookie) signie que les variables provenant dun formulaire ou dun cookie sont chappes.
if (get_magic_quotes_gpc()) echo "le systme utilise les magic quotes"; else echo "le systme nutilise pas le systme des magic quotes";

ini_alter()
j j

Signature : ini_alter ($var, $val). Versions : PHP 4, PHP 5.

Cette fonction permet de modier le contenu dune variable de conguration.

ini_get()
j j

Signature : ini_get ($var). Versions : PHP 4, PHP 5.

Cette fonction retourne le contenu dune variable de conguration :


echo ini_get ("file_uploads")

644 LE GUIDE COMPLET

Fonctions diverses

Chapitre 18

ini_restore()
j j

Signature : ini_restore ($var). Versions : PHP 4, PHP 5.

Cette fonction permet de remettre une variable de conguration sa valeur initiale.

ini_set()
Reportez-vous la fonction init_alter().

phpversion()
j j

Signature : phpversion(). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne la version de PHP.

putenv()
j j

Signature : putenv ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dinitialiser une variable denvironnement :


putenv ("UNIQID=$uniqid");

18.11. Fonctions diverses


constant()
j j

Signature : constant($cst). Versions : PHP 4 partir de la 4.0.4, PHP 5.

Cette fonction retourne la valeur de la constante $cst :


define("MAXINFO",200); echo MAXINFO; echo constant("MAXINFO"); // mme rsultat que prcdemment

LE GUIDE COMPLET 645

Chapitre 18

Les fonctions PHP

dene()
j j

Signature : define ($cst, $val). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de dnir une constante.

dened()
j j

Signature : defined ($cst). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction retourne true si la constante $cst existe.

die()
Reportez-vous la fonction exit().

eval()
j j

Signature : eval ($str). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet dvaluer une expression :


eval eval echo echo ("\$n = 1;"); ("\$ch = \"hello\";"); $n; // affiche : 1 $ch; // affiche : hello

exit()
j j

Signature : exit ($status). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction affiche la variable $status et arrte lexcution du script :


if ($n != 2) exit("valeur non conforme"); $pfichier = fopen ($fichier, r) or exit("le fichier ne peut tre ouvert");

646 LE GUIDE COMPLET

Fonctions diverses

Chapitre 18

highlight_le()
j j

Signature : highlight_file ($fichier). Versions : PHP 4, PHP 5.

Cette fonction permet dafficher le contenu dun script en mettant le code en couleur :
echo "voici le contenu du script : graph.php<hr/>"; highlight_file("graph.php");

Figure 18.10 : Affichage coloris du contenu du script graph.php

La fonction highlight_string() ne colorise que la chane transmise en paramtre :


highlight_string ("<?php \$str = \"toto\"; ?>");

LE GUIDE COMPLET 647

Chapitre 18

Les fonctions PHP

sleep()
j j

Signature : sleep ($n). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet darrter lexcution dun script pendant $n secondes. La fonction usleep() prend en argument un nombre de millisecondes.

uniqid()
j j

Signature : uniqid ($refixe). Versions : PHP 3, PHP 4, PHP 5.

Cette fonction permet de gnrer une valeur unique. Si le paramtre


$prefixe est transmis la valeur est prcde de $prefixe :
echo uniqid(""); // affiche par exemple : 3c05f028546e6 echo uniqid("CODE"); // affiche par exemple : CODE3c05f028594cb

648 LE GUIDE COMPLET

Annexes

Webographie ....................................................................................................................... 650 PHP ....................................................................................................................................... 654 MySQL .................................................................................................................................. 673 Les caractres HTML spciaux ...................................................................................... 679 Les feuilles de styles : CSS ............................................................................................. 683

Chapitre 19

19.1. Webographie
Larrive du Web a radicalement modi la vie du dveloppeur. Rarissimes sont dsormais les situations o vous ne pouvez trouver une rponse un problme sur le Web. Bien souvent, le code rpondant votre question pourra mme tre tlcharg gratuitement. Ce chapitre rpertorie quelques-uns des sites phares autour de PHP et, plus gnralement, des applications en ligne.

PHP
Les sites officiels
j

www.php.net : site officiel du langage PHP. Lespace de tlchargement de PHP fournit des sources ou des binaires pour diffrentes plateformes. Un espace est consacr la documentation la plus jour. Possibilit de la tlcharger dans diffrents formats : HTML, PDF, HLP (chiers daide Windows). http://snaps.php.net : permet de rcuprer les versions les plus rcentes de PHP (gnralement compiles pendant la nuit). Ce sont des versions de dveloppement par dnition instables. www.zend.com : site de la socit Zend. Zone de tlchargement : la librairie Zend Optimizer et une version de dmonstration de loutil de dveloppement Zend IDE. Toutes les semaines, deux articles prsentant les dernires avances au sein de PHP et du Zend Engine sont mis en ligne. Beaucoup darticles, de codes et de documentation, toujours particulirement bien mis en pages. oss.backendmedia.com/PhP60 : un tat davancement du futur PHP6.

Les sites franais


j j j j

www.nexen.net : la documentation de PHP en franais. www.phpindex.com, www.phpinfo.net, www.phpfrance.com : documentation, FAQ, exemples, liens. www.commentcamarche.net : site de vulgarisation informatique dune richesse rare. www.ofphp.com : lobservatoire franais du PHP.

650 LE GUIDE COMPLET

Webographie

Chapitre 19

Les documentations et articles


j j j

www.phpbuilder.com : beaucoup darticles de qualit. Forums trs actifs. www.devshed.com/c/b/PHP : articles et exemples. www.alt-php-faq.org, www.faqts.com/knowledge_base/index.phtml/fid/ 51 : des sites qui permettent de trouver des rponses des problmes plus ou moins courants (ce sont, en fait, des FAQ). www.linuxdoc.org : site central pour toute la documentation de lopen source. On y trouve quelques HOWTO consacrs PHP et Apache. http://marc.theaimsgroup.com : site proposant une archive gigantesque de listes consacres des outils de lopen source.

Les bibliothques de scripts


j j j j

http://px.sklar.com : PX, PHP Code Exchange, la rfrence en la matire. www.hotscripts.com/PHP/Scripts_and_Programs/index.html : Hot Scripts. http://php.resourceindex.com : index de ressources PHP. http://freshmeat.net : le site de rfrence permettant de trouver tous les logiciels open source possibles et imaginables. Les logiciels sont organiss par catgories (Communication, Database, Environnement, Langage de programmation, etc.).

Les modules
j j j j

www.opaque.net/ming : gnration de Flash en PHP. www.pdflib.com : librairie qui permet de gnrer des chiers PDF. www.boutell.com/gd : librairie qui permet de gnrer des images. http://mcrypt.sourceforge.net : librairie qui permet daccder tous les principaux algorithmes de cryptage.

PHP et Windows
j

www.wampserver.com : tlchargement de Wamp, ainsi que des rubriques forum et FAQ.


LE GUIDE COMPLET 651

Chapitre 19
j

www.easyphp.org : site proposant le fantastique logiciel EasyPHP, qui permet de faire fonctionner Apache, PHP, MySQL, phpMyAdmin sous Windows.

Les diteurs
j j

j j

http://notepad-plus.sourceforge.net/fr/site.htm : excellent diteur de code fonctionnant sous Windows. www.gnu.org/software/emacs/emacs.html, www.gnu.org/software/emacs/ windows/ntemacs.html : lditeur par excellence pour Unix/Linux, et qui peut galement fonctionner sous Windows. www.emacswiki.org/cgi-bin/emacs-fr, www.linux-france.org/article/appli/ emacs/index.html : des sites en franais consacrs Emacs. www.dotemacs.de : une formidable source dinformations pour personnaliser votre Emacs.

La scurit
j j j

http://phpsec.org/projects/vulnerabilities/securityfocus.html : failles de scurits de logiciels crits en PHP. http://blog.php-security.org : blog consacr la scurit autour de PHP. www.hardened-php.net : projet visant inclure des extensions de scurit au sein du projet PHP.

MySQL
j

www.mysql.com : site officiel du SGBD MySQL. Tlchargement des sources ou des binaires. Documentation rcente et tlchargeable dans diffrents formats. http://phpmyadmin.sourceforge.net : site dsormais officiel du logiciel phpMyAdmin. Possibilit de tlcharger la version stable et la version bta. www.mysqlperformanceblog.com : blog extrmement pointu consacr aux optimisations MySQL.

Apache
j

www.apache.org, http://httpd.apache.org/docs/2.0/mod/ : site officiel. Tlchargement, documentation, FAQ.

652 LE GUIDE COMPLET

Webographie
j

Chapitre 19

www.apacheweek.com : news et articles rguliers sur Apache et les modules environnants (notamment PHP).

Internet et le Web
Gnralits
j j

http://fr.wikipedia.org/wiki/Internet : une histoire dInternet. http://sunsite.dk/RFC : un moteur de recherche de RFC (Request for Comments). Laccs une RFC peut tre ralis par numros ou par mots-cls. Quelques RFC importantes : HTTP (2616 2617), MAIL (1521 2821 2822). www.w3.org : le site du World Wide Web Consortium, rfrence pour tout ce qui touche au monde du Web. Prsence de documentations trs prcises et techniques sur les diffrentes technologies du Web daujourdhui et de demain.

Les navigateurs
j j j

www.mozilla.org : Mozilla est un excellent navigateur gratuit fonctionnant sur une multitude de plateformes. www.mozillazine.org : site de news concernant Mozilla et les projets environnants. www.mozdev.org : site consacr des applicatifs fonds sur le framework Mozilla.

HTML, CSS et Javascript


j j j j j

www.htmlhelp.com : tout ce quil faut savoir sur le HTML et les CSS (trs bonnes documentations tlcharger). www.htmldog.com/reference/cssproperties : beaucoup dinformations sur les CSS. http://javascript.internet.com : de trs nombreux exemples. www.w3schools.com/html/html_colors.asp : site qui permet de voir, en un coup dil, les codes couleurs HTML. http://developer.mozilla.org/en/docs/Main_Page : le site Mozilla consacr aux dveloppeurs. Un must !

LE GUIDE COMPLET 653

Chapitre 19

Et les blogs
j j j j j

www.planet-php.net : blogs consacrs PHP. www.planetmysql.org : blogs consacrs MySQL. www.planetapache.org : blogs consacrs Apache. http://planet.mozilla.org : blogs consacrs au navigateur Firefox. http://andigutmans.blogspot.com, www.suraski.net/blog, http://blog.360 .yahoo.com/rlerdorf : les blogs des crateurs de PHP.

Divers
j

www.ucc.ie/cgi-bin/acronym : un moteur de recherche consacr aux abrviations. Un bon moyen pour savoir ce que veulent dire HTTP, FTP, etc. www.dafont.com, www.fontfreak.com, www.1001freefonts.com : sites proposant des fontes gratuites.

19.2. PHP
Les oprateurs
Les oprateurs arithmtiques
Tableau 19.1 : Oprateurs arithmtiques

Oprateur

Nom Addition Soustraction Multiplication Division Modulo

Rsultat Somme de $x et $y Diffrence de $x et $y Multiplication de $x et $y Division de $x et $y Modulo de $x et $y

+ * / %

654 LE GUIDE COMPLET

PHP

Chapitre 19

Les oprateurs sur les bits


Tableau 19.2 : Oprateurs sur les bits

Oprateur

Nom ET (AND) OU (OR) Xor NON (Not) Dcalage gauche

Rsultat Les bits dnis 1 dans $x ET dans $y sont placs 1 Les bits dnis 1 dans $x OU dans $y sont placs 1 Les bits dnis 1 dans $x OU dans $y sont placs 1 Les bits qui sont dnis 1 dans $x sont placs 0, et vice-versa Dcale les bits de $x dans $y par la gauche (chaque dcalage quivaut une multiplication par 2) Dcalage des bits de $x dans $y par la droite (chaque dcalage quivaut une division par 2)

$x & $y $x | $y $x ^ $y ~ $x $x << $y

$x >> $y

Dcalage droite

Oprateurs de comparaison
Tableau 19.3 : Oprateurs de comparaison

Oprateur

Rsultat Vrai si la valeur $x est gale $y Vrai si la valeur $x est gale $y et si elles sont de mme type Vrai si $x est diffrente de $y Vrai si $x est diffrente de $y Vrai si $x est diffrente de $y et si elles sont de type diffrent Vrai si $x est suprieure $y Vrai si $x est infrieure $y Vrai si $x est suprieure ou gale $y Vrai si $x est infrieure ou gale $y

$x == $y $x === $y $x != $y $x <> $y $x !== $y $x > $y $x < $y $x >= $y $x <= $y

LE GUIDE COMPLET 655

Chapitre 19

Oprateurs arithmtiques
Tableau 19.4 : Oprateurs arithmtiques

Oprateur

Rsultat Vrai si $x ET $y sont vraies Vrai si $x ET $y sont vraies (identique and) Vrai si $x OU $y sont vraies Vrai si $x OU $y sont vraies (identique or) Vrai si $x OU $y sont vraies, mais pas les deux Vrai si $x est fausse

$x and $y $x && $y $x or $y $x || $y $x xor $y ! $x

Priorit des oprateurs


Ce tableau est conu dans lordre croissant de priorit. Dans lexemple suivant, loprateur == est en dessous de loprateur or ; il est donc prioritaire :
if ($a == b$ or $c)

Lexpression est donc quivalente :


if (($a == $b) or $c)
Tableau 19.5 : Associativit des oprateurs

Associativit Gauche Gauche Gauche Gauche Droite Gauche Gauche Gauche Gauche

Oprateurs

, or xor and print = += = *= /= .= %= &= |= ^= ~= <<=>>= ? : || &&

656 LE GUIDE COMPLET

PHP
Tableau 19.5 : Associativit des oprateurs

Chapitre 19

Associativit Gauche Gauche Gauche Non associatif Non associatif Gauche Gauche Gauche Droite Droite Non associatif

Oprateurs

| ^ & == != === < <= > >= << >> + . * / % ! ~ ++ (int) (double) (string) (array) (object) @ [ new

Les variables prdnies


Un script PHP peut accder tout moment un certain nombre de variables prdnies. Nous allons lister dans cette partie deux types de variables :
j j

les variables Apache, qui ne sont disponibles que si vos scripts tournent sur un serveur web Apache ; les variables PHP, qui, elles, sont toujours accessibles.

La fonction phpinfo() peut tre utilise pour obtenir un aperu rapide de toutes ces variables. Elle vous permettra aussi de savoir si votre serveur web est Apache.

LE GUIDE COMPLET 657

Chapitre 19

Figure 19.1 : Liste de variables proposes par Apache

Les variables Apache


En fonctionnant avec le serveur web Apache, vous tes sr de pouvoir accder ces variables. Dautres serveurs web peuvent aussi vous y donner accs. Vous navez cependant aucune garantie du pourcentage de variables qui seront disponibles. Il se peut galement que certaines dentre elles portent un nom diffrent. Quoi quil en soit, Apache est, aujourdhui et de loin, le serveur web le plus utilis pour faire fonctionner des scripts PHP, et il y a fort parier que votre hbergeur ait fait ce choix.

$_SERVER[GATEWAY_INTERFACE]
Cette variable contient la version de la spcication CGI utilise par le serveur web. Par exemple : CGI/1.1.

$_SERVER[SERVER_NAME]
Cette variable contient le nom du serveur web sur lequel le script est excut. Sil sagit dune machine qui fonctionne en virtual host

658 LE GUIDE COMPLET

PHP

Chapitre 19

(plusieurs domaines sur la mme machine), cest le nom du virtual


host qui est retourn. Par exemple : localhost.

$_SERVER[SERVER_SOFTWARE]
Cette variable contient une identication technique du serveur web sur lequel est excut le script. Par exemple : Apache/1.3.14 (Unix) (RedHat/Linux) mod_perl/1.23. Grce cette identication, on devine que le serveur web est Apache, que sa version est 1.3.14 et que le systme dexploitation sur lequel il fonctionne est un Linux (distribution Red Hat).

$_SERVER[SERVER_PROTOCOL]
Cette variable contient le nom et la version du protocole qui a t utilis pour rcuprer la page. Par exemple : HTTP/1.1.

$_SERVER[REQUEST_METHOD]
Cette variable contient le nom de la mthode qui a t utilise pour accder la page. Les diffrentes valeurs possibles sont : GET, HEAD, POST, PUT.

$_SERVER[QUERY_STRING]
Cette variable contient la query string qui a t transmise au script. Si lURL dappel est http://localhost/test.PHP 3?var1 =2&var2=3, la variable $_SERVER[QUERY_STRING] contiendra var1=2&var2=3.

$_SERVER[DOCUMENT_ROOT]
Cette variable contient le rpertoire racine de votre compte. Cette variable est dnie dans le chier de conguration dApache. Il y a de fortes chances pour que cette valeur ne vous serve rien. Par exemple : c:/wamp/www.

$_SERVER[HTTP_ACCEPT]
Cette variable contient la partie Accept: de len-tte HTTP de la requte courante (si elle existe). Par exemple : text/xml, application/xml, application/xhtml+xml, text/html;

LE GUIDE COMPLET 659

Chapitre 19 q=0.9, image/png, image/jpeg, text/plain;q=0.8, text/css, */*;q=0.1. image/gif;q=0.2,

Certains navigateurs acceptent plus ou moins de formats de chiers. Lexemple prcdent correspond Netscape. Pour Internet Explorer, la variable contient : image/gif, image/xxbitmap, image/jpeg, image/pjpeg, application/vnd.mspowerpoint, application /vnd.msexcel, application/msword, */*. Vous voyez donc quInternet Explorer est capable de lire directement des chiers PowerPoint, Excel ou Word. Cette variable est rarement complte. On sait en effet quInternet Explorer accepte le format PNG.

$_SERVER[HTTP_ACCEPT_CHARSET]
Cette variable contient la partie AcceptCharset: de len-tte HTTP de la requte courante (si elle existe). Par exemple : ISO88591, utf8;q=0.66, *;q=0.66.

$_SERVER[HTTP_ACCEPT_ENCODING]
Cette variable contient la partie AcceptEncoding: de len-tte HTTP de la requte courante (si elle existe). Par exemple : gzip,deflate,compress,identity. Cette variable est utilise par le serveur web pour savoir comment il peut rpondre au navigateur. Une fonctionnalit des navigateurs souvent inconnue est de pouvoir recevoir des donnes compresses et les dcompresser la vole. Le fait quil y ait moins de donnes transmettre quivaut bien videmment une acclration du chargement de la page. Lexemple suivant envoie de manire compresse une page contenant un pome :
Listing 19-1 : envoi dun contenu compress <?php if (strpos($_SERVER[HTTP_ACCEPT_ENCODING], "gzip") === false) die("votre navigateur naccepte pas les pages compresses"); ob_start();

660 LE GUIDE COMPLET

PHP
?> <html> <head> <title>Le Corbeau et le Renard</title> </head> <body>

Chapitre 19

<pre> Matre Corbeau, sur un arbre perch, Tenait en son bec un fromage. Matre Renard, par lodeur allch, Lui tint peu prs ce langage : "H ! bonjour, Monsieur du Corbeau. Que vous tes joli ! que vous me semblez beau ! Sans mentir, si votre ramage Se rapporte votre plumage, Vous tes le Phnix des htes de ces bois. " A ces mots le Corbeau ne se sent pas de joie ; Et pour montrer sa belle voix, Il ouvre un large bec, laisse tomber sa proie. Le Renard sen saisit, et dit : "Mon bon Monsieur, Apprenez que tout flatteur Vit aux dpens de celui qui lcoute : Cette leon vaut bien un fromage, sans doute. " Le Corbeau, honteux et confus, Jura, mais un peu tard, quon ne ly prendrait plus. </pre> </body> </html> <?php $contenu = ob_get_contents(); $gzdata = "\x1f\x8b\x08\x00\x00\x00\x00\x00"; $taille = strlen($contenu); $crc = crc32($contenu); $gzdata .= gzcompress($contenu, 5); $gzdata = substr($gzdata, 0, strlen($gzdata) - 4); $gzdata .= pack("V",$crc) . pack("V", $taille); ob_end_clean(); Header(Content-Encoding: gzip); Header(Vary: Accept-Encoding); Header(Content-Length: . strlen($gzdata));

LE GUIDE COMPLET 661

Chapitre 19
echo $gzdata; ?>

Si vous commentez la ligne Header(ContentEncoding: gzip) (directive HTTP qui indique au navigateur que le contenu est compress), vous obtenez le rsultat suivant :

Figure 19.2 : Sans la fonction header(), le navigateur a limpression de recevoir du texte brut

$_SERVER[HTTP_ACCEPT_LANGUAGE]
Cette variable contient la partie AcceptLanguage: de len-tte HTTP de la requte courante (si elle existe). Par exemple : enus.

$_SERVER[HTTP_CONNECTION]
Cette variable contient la partie Connection: de len-tte HTTP de la requte courante (si elle existe). Par exemple : KeepAlive.

$_SERVER[HTTP_HOST]
Cette variable contient la partie Host: de len-tte HTTP de la requte courante (si elle existe). Par exemple : localhost.

$_SERVER[HTTP_REFERER]
Cette variable contient ladresse de la page qui a men la page actuelle. Cette