Sie sind auf Seite 1von 471

PHPetMySQL

Matrisez le dveloppement d'un site Web dynamique et interactif

OlivierHEURTEL

Rsum
Ce livre sur PHP et MySQL sadresse aux concepteurs et dveloppeurs qui souhaitent utiliser PHP et MySQL pour dvelopper un site Web dynamique et interactif. Dans la premire partie du livre, lauteur prsente la mise en oeuvre dune base de donnes MySQL : langage SQL (Structured Query Language), utilisation des fonctions MySQL, construction dune base de donnes (tables, index, vues), sans oublier les techniques avances comme la recherche en texte intgral ou le dveloppement de programmes stocks. Dans la deuxime partie du livre, aprs une prsentation des fonctionnalits de base du langage PHP, lauteur se focalise sur les besoins spcifiques du dveloppement de sites dynamiques et interactifs en sattachant apporter des rponses prcises et compltes aux problmatiques habituelles : gestion des formulaires, gestion des sessions, envoi de courriers lectroniques et bien sr accs une base de donnes MySQL. Abondamment illustr dexemples comments, ce livre (crit sur les versions 5 de PHP et de MySQL) est la fois complet et synthtique et vous permet daller droit au but. Les exemples cits dans le livre sont en tlchargement sur cette page.

L'auteur
Aprs plus de huit ans passs en socit de service, o il a successivement occup les postes de dveloppeur, chef de projet puis directeur de projet, Olivier Heurtel a dmarr une activit de consultant/formateur indpendant spcialis sur les bases de donnes (Oracle), le dveloppement Web (PHP) et les systmes dcisionnels. Il est certifi Oracle Certified Professional.
Ce livre numrique a t conu et est diffus dans le respect des droits dauteur. Toutes les marques cites ont t dposes par leur diteur respectif. La loi du 11 Mars 1957 nautorisant aux termes des alinas 2 et 3 de larticle 41, dune part, que les copies ou reproductions strictement rserves lusage priv du copiste et non destines une utilisation collective, et, dautre part, que les analyses et les courtes citations dans un but dexemple et dillustration, toute reprsentation ou reproduction intgrale, ou partielle, faite sans le consentement de lauteur ou de ses ayants droit ou ayant cause, est illicite (alina 1er de larticle 40). Cette reprsentation ou reproduction, par quelque procd que ce soit, constituerait donc une contrefaon sanctionne par les articles 425 et suivants du Code Pnal. Copyright Editions ENI

ENI Editions - All rigths reserved

- 1-

Objectifsdelouvrage
LobjectifdecetouvrageestdapprendredvelopperunsiteWebdynamiqueetinteractiflaidedePHPetMySQL. Pourrpondrecetobjectif,celivretudieendtaillesfonctionnalitsncessairesaudveloppementdun site Web dynamiqueetinteractif :
q

utilisation du langage SQL (Structered Query Language langage standard daccs aux bases de donnes relationnelles)pourinterrogeretmodifierlesdonnesdunebasededonnesMySQL crationdunebasededonnesMySQL utilisationdesfonctionnalitsdebasedulangagePHP accsunebasededonnesMySQLpartirdePHP gestiondesformulaires gestiondessessions(authentification,gestionduncontexte,utilisationdescookies) envoiduncourrierlectronique(dontlescourriersauformatHTMLetceuxavecpicejointe) gestiondesfichiers,dontletransfertdefichiersdupostedelutilisateurversleserveur("fileupload").

Cet ouvrage sadresse des chefs de projet, concepteurs ou dveloppeurs ayant une connaissance de base de la programmationWebenHTML. Celivreabordelesversions5dePHPetdeMySQL.

ENI Editions - All rigths reserved

- 1-

BrefhistoriquedePHPetMySQL
1.PHP
LelangagePHP(historiquementPersonalHomePage,officiellementacronymercursifdePHP :HypertextPreprocessor)a t conu en 1994 par Rasmus Lerdorf pour ces besoins personnels, avant dtre rendu public au dbut de lanne 1995. Courant1995,unenouvelleversion,compltementrcrite,estpubliesouslenomPHP/FIversion2.Cetteversion, capabledegrerlesformulairesetdaccderlabasemSQL,permetaulangagedesedvelopperrapidement. En1997,ledveloppementdulangageestprisenchargeparunequipeformeautourdeRasmusLerdorfetaboutit lasortiedelaversion3. En 2000, lanalyseur PHP est migr sur le moteur danalyse Zend afin doffrir de meilleures performances et de supporterunplusgrandnombredextension :cestlaversion4dePHP. En 2004, la version 5 voit le jour. Cette nouvelle version, base sur la version 2 du moteur Zend, apporte plusieurs nouveauts,laplupartconcernantledveloppementorientobjet. cejour,lesanalystesestimentquePHPestutilisparplusde20millionsdesitesWebdanslemonde(ennombrede domaines).

2.MySQL
MySQL est le Systme de Gestion de Base de Donnes Relationnelle (SGBDR) Open Source le plus rpandu dans le monde.IlestdveloppparMySQLAB,uneentreprisesudoise. La premire version de MySQL est apparue en 1995. Cette premire version est cre pour un usage personnel partirdemSQL. En2000,laversion3.23estpasseenlicenceGPL(GeneralPublicLicense). En 2003, la version 4, apparue en 2001, est dclare stable. Cette version apporte de nombreuses nouvelles fonctionnalits et amliorations : oprateur UNION, DELETE multitables, nouvelles options pour la gestion des droits, amliorationdesperformances,sousrequtes(4.1),etc. En 2005, la version 5, apparue en 2003, est dclare stable. Cette version majeure introduit de nombreuses fonctionnalitsmanquantesdansMySQL :programmesstocks,triggers,vues. Fin2007,laversion5.1estdistribueenReleaseCandidateetdevraitsortirenversionfinaledbut2008. MySQLestdisponibleselondeuxlicencesdiffrentes :
q

LalicenceGPL Unelicencecommerciale.

SivousutilisezMySQLdansunproduitlibre,vouspouvezutiliserMySQLlibrement(versionMySQLCommunityServer). SivousutilisezMySQLdansunproduitcommercial,ousivoussouhaitezavoirunsupportpourlelogiciel,vousdevez acqurirunelicencecommerciale(versionMySQLEnterprise).

ENI Editions - All rigths reserved

- 1-

OseprocurerPHPetMySQL
De nombreux sites Web sont consacrs au langage PHP et MySQL. Ils permettent de tlcharger les produits, de consulterdesexemplesdescriptsoudedialoguersurdesforums : Adresse Contenu SiteofficieldePHPquiproposeletlchargementde PHPetunmanuelderfrenceenlignetrspratique. Vouspouveznotammentsaisir www.php.net/nom_fonctionpouraccderdirectement laideenlignedunefonctionPHP. SiteofficieldeMySQLquiproposeletlchargementde MySQL,uneaideenligne,desarticles,unforum,etc. SiteenfranaisconsacrPHPquiproposedesnews, desexemplesainsiquunforumdediscussion.Bref,un sitetrscompletmettredanssesfavoris. AutresitefrancophoneconsacrPHPproposantdes rubriquessimilaires. SiteofficieldumoteurdescriptZendquiproposelui aussilesrubriquesclassiquesdetlchargement, dexemples,deforum, Sitefrancophonequiproposegratuitementunproduit installable(EasyPHP)surplateformeWindows.Ce produitcomprend :unserveurApache,PHPetMySQL. Voustlchargezleproduitetdoublecliquezsur lexcutablequiinstallelesdiffrentslments.Cinq minutesaprs,votreenvironnementPHPMySQLest oprationnel.Cesiteestindispensablepourceuxqui souhaitentmonterrapidementuneconfiguration oprationnellecompltesurWindows.Lesversions utilisesparEasyPHPprsententtoujoursunlger retardparrapportauxderniresversionsofficielles. Autresitequiproposeunproduitinstallable(XAMPP) surdiffrentesplatesformes(Linux,Windows,Solaris, MacOSX).Ceproduitcomprendluiaussi,entreautres, unserveurApache,PHPetMySQL.Lencore linstallationesttrssimpleettrsrapide.Lesversions utilisesparXAMPPsonttoujourstrsrcentespar rapportauxderniresversionsofficielles. PagedusitedesditionsENIsurlaquellelesexemples traitsdanscetouvragepeuventtretlchargs.

www.php.net

wwwfr.mysql.com

www.phpindex.com

www.phpfrance.com

www.zend.com/fr

www.easyphp.org

www.apachefriends.org/fr/xampp.html

www.editionseni.com/exemples/

Cette liste est videmment non exhaustive mais tous les sites prsents proposent de nombreux liens vers dautres sites.Nhsitezpassurfer ! TouslesexemplesdecetouvrageontttestsavecXAMPPLinux1.6.4(soitMySQL5.0.45etPHP5.2.4).

ENI Editions - All rigths reserved

- 1-

Conventionsdcriture
1.PHP
LasyntaxedesfonctionsPHPestdcritedelamaniresuivantedanscetouvrage : type_retour nom_fonction( type_paramtre nom_paramtre) type_retour Typederetourdelafonction. nom_fonction Nomdelafonction. type_paramtre Typeduparamtreacceptparlafonction. nom_paramtre Nomdonnauparamtre. Les types de donnes possibles seront prsents dans le chapitre Introduction PHP. Dans le cas o la fonction accepte un paramtre de nimporte quel type et/ou retourne une valeur de nimporte quel type, le terme mixte est utilis. Silafonctionneretournepasdevaleur,linformationtype_retourestomise. Exemple nom_fonction( type_paramtre nom_paramtre) Silafonctionneprendaucunparamtre,lesinformationstype_paramtreetnom_paramtresontomises. Exemple type_retour nom_fonction() Lesparamtresoptionnelssontindiqusentrecrochets( []). Exemple type_retour nom_fonction( [ type_paramtre nom_paramtre ] ) Si la fonction accepte plusieurs paramtres, ces derniers sont indiqus, spars par une virgule, selon la mme convention. Exemple type_retour nom_fonction( type_paramtre_1 nom_paramtre_1, type_paramtre_2 nom_paramtre_2) Siunparamtrepeuttrerptunnombrequelconquedefois,ilestsimplementsuividelasquence[,]. Exemple type_retour nom_fonction( type_paramtre nom_paramtre [ , . . . ] )

2.MySQL
LasyntaxedesordresSQLestdcritedelamaniresuivantedanscetouvrage : MOT EN MAJUSCULES

ENI Editions - All rigths reserved

- 1-

Motsclsdelacommande(CREATE TABLEparexemple). Danslapratique,ilspeuventtresaisisindiffremmentenmajusculesouenminuscules. mot en minucules Valeurssaisirrelativeslabasededonnesoulapplication(nomdetable,nomdecolonne,etc). Selonlecas,cesvaleurssontsensibleslacasseoupas(cf.IntroductionMySQLphpMyAdmin). [] Clauseoptionnelle. [,] Laclauseprcdentepeuttrerpteplusieursfois. | Indiqueunchoixentreplusieursoptions. {} Dlimiteunelistedoptions. mot soulign Valeurpardfaut. mot en italique Clausedelacommandedontlasyntaxeestdtaillepart.

- 2-

ENI Editions - All rigths reserved

Introductionauxbasesdedonnesrelationnelles
1.Concepts
Unebasededonnesestunensemblededonnesstructurescorrespondantgnralementundomainefonctionnel (facturation, ressources humaines, etc.). Physiquement, une base de donnes se matrialise par un ensemble de fichiersstockssurunpriphriquedestockage. LesdonnesdunebasededonnessontgresparunlogicielappelSystmedeGestiondeBasedeDonnes(SGBD). Ce logiciel offre plusieurs fonctionnalits : accs aux donnes, gestion des mises jour, renforcement de lintgrit, contrledelascuritdaccs,etc. Une base de donnes relationnelle supporte une organisation des donnes bases sur le modle relationnel, dveloppen1970parEdgarFrankCodd.Cestlastructurelaplusrpandueaujourdhui. Dans une base de donnes relationnelle, les donnes sont organises en tables logiquement lies entre elles. Une table comporte un certain nombre de colonnes (ou champs) qui dcrivent une ligne (ou enregistrement). La mise en relationdestablesseffectueparlintermdiairedunecolonne. Exemple livre +----+--------------------------------+---------------+ | id | titre | id_collection | +----+--------------------------------+---------------+ | 1 | PHP 5.2 - Dveloppement Web | 1 | | 2 | Oracle 10g - Administration | 1 | | 3 | Oracle 10g - Recovery Manager | 2 | | 4 | BusinessObjects 6 | 1 | | 5 | MySQL 5 - Mise en oeuvre | 1 | | 6 | PHP et MySQL (versions 4 et 5) | 3 | | 7 | MySQL 5 et PHP 5 | 4 | +----+--------------------------------+---------------+ collection +----+--------------------------+ | id | nom | +----+--------------------------+ | 1 | Ressources Informatiques | | 2 | TechNote | | 3 | Les TP Informatiques | | 4 | Coffret Technique | +----+--------------------------+ Surcetexemple,lestableslivreet collectionsontliesparlescolonnesid_collectiondelatable livreetiddela tablecollection. LinteractionavecunebasededonnesrelationnelleseffectuegrceaulangageSQL( StructuredQueryLangage).Ce langage permet la lecture et la mise jour des donnes, mais aussi la dfinition de lorganisation des donnes, la gestiondelascurit,lerenforcementdelintgrit,etc.LelangageSQLestunlangagenormalis,maislesdiffrents diteursdebasededonnesnerespectentpaslintgralitdustandard.

2.Principesdeconceptiondunebasededonnes
Laconceptiondunebasededonnesestunsujetcomplexedontnousnabordonsiciquelesprincipesdebase,dans uneapprochepluspratiquequethorique. Dans une base de donnes relationnelle, lobjectif est de stocker dans des tables diffrentes les informations correspondantdesentits(objets)diffrentsdudomainefonctionnel.Lebutestdviterlesredondancesetfaireen sorte quune information donne ne soit stocke quune fois. Sur notre exemple prcdent, les informations sur lauteurdunlivrenesontpasstockesdanslatablelivre lauteurdunlivreestuneentitfonctionnellepartentire quieststockedansunetablespare. Ceprocessusdesparationdesdonnesdansplusieurstablesestappel normalisation . nenormalisationpousselextrmepeutnuireauxperformancesdesrequtesdinterrogationquidoiventlire U un grand nombre de tables. Pour amliorer les performances des lectures, il est alors envisageable de
ENI Editions - All rigths reserved - 1-

dnormaliser lemodle,enregroupantdestables,quitteavoirdesdonnesredondantesdanslesdiffrentes lignes. Les bases de donnes des systmes dcisionnels, qui effectuent principalement des interrogations gnralement complexes, sont trs souvent dnormalises. linverse, les bases de donnes des systmes transactionnels, qui effectuent principalement des petites interrogations simples et beaucoup de mises jour, respectentbienleprincipedenormalisation. Dansunebasededonnesrelationnelle,chaquetablestockelesinformationsrelativesunobjetmtierconcretou abstraitquidoittreidentifi. Danslatable,chaquecolonnestockeuneinformationunitaire(attribut,proprit)quicaractriseunelignedelatable. Chaquecolonnepossdeuntypededonnes(entier,chanedecaractres,date,etc)etpeuttreobligatoireounon. Une colonne ou combinaison de colonnes qui identifie de manire unique une ligne dune table est appele cl candidate. La valeur dune cl candidate est diffrente pour toutes les lignes de la table (pas de doublon autoris). Uneclcandidatepeuttreconstitueparunecolonnearbitraireutilisespcifiquementpourcela. Laclprimairedunetableestunedesclscandidatesdelatable,choisieplusoumoinsarbitrairement,sicenestque lescolonnesdelaclprimairedoiventaussitreobligatoires ilyauneseuleclprimairepartable.Lesautrescls candidatesdelatablesontalorsappelesclsuniques. Unecolonneoucombinaisondecolonnesdunetablequirfrenceuneclcandidateduneautretable(engnralla clprimaire)estappelecltrangre.Unetablepeutavoirplusieursclstrangres. Exemple

Leschmacidessusprsentelemodledelabasededonnesutilisedanscetouvrage.Cemodleestunmodle simplifidegestiondeslivresdunditeur. Cemodlecomportelestablessuivantes : auteur

- 2-

ENI Editions - All rigths reserved

Auteursdeslivres. rubrique Rubriquespermettantleclassementdeslivresdansdiffrentescatgories(basededonnes,langagede dveloppement,etc.).Lesrubriquessontorganisessurdeuxniveaux:rubriqueprincipaleetsousrubrique.Une sousrubriqueestrattacheunerubriqueparentparlintermdiairedelacolonneid_parent.Pourunerubrique parent,lacolonneid_parentestvide. collection Collectionsdelditeurdanslesquellesleslivressontpublis. promotion Promotionssurleslivres. livre Livrespublisparlditeur. auteur_livre Relationentrelesauteursetleslivres:unauteurpeutcrireplusieurslivresetunlivrepeutavoirplusieursauteurs. rubrique_livre Relationentrelesrubriquesetleslivres:unerubriquepeutcontenirplusieurslivresetunlivrepeutappartenir plusieursrubriques. Dans toutes les tables, lexception de auteur_livre et rubrique_livre, la cl primaire est la colonne id. Pour les tables auteur_livre et rubrique_livre, la cl primaire est la combinaison des deux colonnes, respectivement (id_auteur,id_livre)et(id_rubrique,id_livre). Dansltatactueldumodle,ilyaunecluniquesurlacolonnenomdelatablecollection.DanslechapitreConstruire unebasededonnesdansMySQL,nousajouteronsdesclsuniquessurdautrestables. Latablelivrecomportedeuxclstrangres:id_collection(verslatablecollection)et id_promotion(verslatable promotion). La table auteur_livre comporte deux cls trangres : id_auteur (vers la table auteur) et id_livre (vers la table livre). La table rubrique_livre comporte deux cls trangres : id_rubrique (vers la table rubrique) et id_livre (vers la tablelivre). Latablerubriquecomporteunecltrangre:id_parent(verslatablerubrique).

ENI Editions - All rigths reserved

- 3-

TravailleravecMySQL
1.AdministrationduserveurMySQL
AprsavoirinstallMySQL,nouspouvonsadministrerleserveurMySQLaveclecomptesuperutilisateur root (rien voiraveclecompterootsousUnixouLinux). Initialement,lecompte rootnapasdemotdepasseetildisposedetouslesdroitssurtouteslesbasesdedonnes duserveurMySQL.Parcontre,ilnepeutseconnecterquelocalement(partirduserveurluimme). Dans le chapitre Construire une base de donnes dans MySQL, nous verrons comment crer dautres utilisateurs et leuraffecterdesdroits.

2.Interfacelignedecommande
Lapplicationcliente mysqlestunprogrammeinteractifquipermetdeseconnecterunserveurMySQLetdexcuter desrequtessurceserveur.CetteapplicationsetrouvedanslerpertoirebindevotreinstallationMySQL. Syntaxe mysql [-h hte] [-u utilisateur ] [-p[ mot_de_passe ]] [ nom_base ] -h hte Hteauquelilfautseconnecter(machinelocalepardfaut). -u utilisateur Nomdutilisateurpourlaconnexion(nomdelutilisateurcourantdusystmedexploitationpardfaut). -p[mot_de_passe] Motdepassepourlaconnexion(aucunmotdepassepardfaut).Silnestpasdonnsurlalignedecommande,ilsera demanddemanireinteractive,ensaisiemasque.Silemotdepasseestspcifidanslalignedecommande(cequi nestpasconseillpourlascurit),ilnedoitpasyavoirdespaceaprsloption-p. nom_base Baseslectionneaudpart(aucunepardfaut). Exemple [root@xampp ~]# m y s q l - u r o o t Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 32 Server version: 5.0.45 Source distribution Type help; or \h for help. Type \c to clear the buffer. mysql> Surcetexemple,laconnexionseffectuelocalement,sansmotdepasse,entantquutilisateurroot.Commelutilisateur courant est root au niveau du systme dexploitation, le mme rsultat peut tre obtenu en tapant simplement la commandemysql : [root@xampp ~]# m y s q l Welcome to the MySQL monitor. ...

Commands end with ; or \g.

Siunmotdepasseestrequisetquevousnesouhaitezpaslesaisirsurlalignedecommande,vouspouvezutiliserla commandesuivantepourvousconnecter : [root@xampp ~]# m y s q l - u r o o t - p

ENI Editions - All rigths reserved

- 1-

Enter password: * * * * Welcome to the MySQL monitor. ...

Commands end with ; or \g.

Siunmotdepasseestrequisetquevoustentezdevousconnectersansmotdepasse,vousobtenezuneerreur : ERROR 1045 (28000): Access denied for user root@localhost (using password: NO) Demme,sivoustentezdevousconnecterpartirdunemachinequinestpasautorise,vousobtenezuneerreur similaire. Danslinterfacelignedecommande,vouspouvezsaisirsoitdescommandesduclientmysqlsoitdesrequtesSQL. Lescommandesduclient mysqlsontinterprtesdirectementparleclient mysql.Unetellecommandedoittrecrite suruneseuleligneetlutilisationdupointvirguleenfindecommandeestsuperflue.Lescommandesduclientmysqlne sontpassensibleslacasseetpeuventtresaisiesindiffremmentenminusculesouenmajuscules. Les requtes SQL sont envoyes au serveur pour tre excutes. Une requte SQL peut tre crite sur plusieurs lignes et doit se terminer par un point virgule. Les mots cls du langage SQL ne sont pas sensibles la casse et peuventtresaisisindiffremmentenminusculesouenmajuscules. Lescommandesduclientmysqllesplussouventutilisessontlessuivantes : exitouquit Quittelapplication. usenom_base Utiliseuneautrebasededonnes. sourcefichier_script ExcuteunscriptSQL. delimitercaractres ModifieledlimiteurutilispourterminerunerequteSQL. Exemple [root@xampp ~]# m y s q l - u r o o t Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 37 Server version: 5.0.45 Source distribution Type help; or \h for help. Type \c to clear the buffer. mysql> u s e i n f o r m a t i o n _ s c h e m a Database changed mysql> S E L E C T s c h e m a _ n a m e F R O M s c h e m a t a ; +--------------------+ | schema_name | +--------------------+ | information_schema | | cdcol | | mysql | | phpmyadmin | | test | +--------------------+ 5 rows in set (0.01 sec) mysql> e x i t Bye [root@xampp ~]# Dans la suite de cet ouvrage, nous prsenterons la syntaxe de lordre SQL SELECT, ainsi que la base de donnes

- 2-

ENI Editions - All rigths reserved

information_schema. IlexisteaussiunordreSQLUSEquivalentlacommandeuse.

3.MySQLQueryBrowser
MySQL Query Browser est une application graphique dveloppe par la socit MySQL AB qui permet dditer et dexcuterdesrequtesSQLdansunebasededonnesMySQL. VouspouvezvousprocurerMySQLQueryBrowserladressesuivante :http://dev.mysql.com/downloads/.Leproduit estdisponiblesurlesplatesformesWindows,LinuxetMacOS. Lorsque vous lancez lapplication, une fentre de dialogue saffiche afin de saisir les paramtres de connexion au serveurMySQL :

Danscettefentrededialogue,vousdevezindiquerlesinformationssuivantes : ServerHost Hteauquelilfautseconnecter(obligatoire). Username Nomdutilisateurpourlaconnexion(nomdelutilisateurcourantdusystmedexploitationpardfaut). Password Motdepassepourlaconnexion(aucunmotdepassepardfaut). DefaultSchema Base(ouschma)slectionneaudpart(aucunepardfaut). Unefoisconnect,lafentresuivantesaffiche :

ENI Editions - All rigths reserved

- 3-

Dans le cadre de droite, loutil liste les bases de donnes auxquelles lutilisateur a accs. En cliquant sur les petits triangles,vouspouveztrsfacilementafficherlalistedestablesstockesdansunebasededonnes,puislastructure dunetable :

Sivousdoublecliquezsurlenomdunebasededonnes,cellecidevientlabasededonnescourante :sonnomest alorsaffichengras. Dans le cadre suprieur, vous pouvez saisir le texte dune requte SQL puis cliquer sur le bouton Execute pour lexcuter lersultatdelarequtesaffichedanslongletResultset :

- 4-

ENI Editions - All rigths reserved

Si vous double cliquez sur le nom dune table dans le cadre de droite, une requte permettant dafficher tout le contenudelatableestautomatiquementrenseignedanslecadresuprieur. Si vous effectuez un clic droit sur un objet dans le cadre de droite, un menu contextuel saffiche. Ce dernier vous propose diffrents articles qui vous permettent de crer, modifier ou supprimer les objets (table, vue, programme stock) :

Danslensemble,cetoutilesttrsconvivialetsonapprentissageestais.

4.phpMyAdmin
phpMyAdminestuneapplicationWebdveloppeenPHPquipermetdadministrerunserveurMySQL(sousrservede disposerduncompteutilisateurMySQLayantlesdroitssuffisants). phpMyAdminpermetde :
q

grerlesbasesdedonnesduserveurMySQL grerlesutilisateursetlesdroits grerlesdiffrentsobjetsdunebasededonnes(tables,colonnes,index,vues,programmesstocks,etc.) diteretexcuterdesrequtesSQL

ENI Editions - All rigths reserved

- 5-

chargerdesfichierstextesdansdestables exporterouimporterdestables exporterlesdonnesdestablesdansdiffrentsformats(CSV,XML,PDF,etc) Etc.

VouspouvezvousprocurerphpMyAdminladressesuivante :http://www.phpmyadmin.net/ phpMyAdminpeuttreconfigurlaidedufichierconfig.inc.php. Cefichierdeconfigurationpermetnotammentdespcifierlamthodedauthentification. SivousnesouhaitezpassaisirunnometunmotdepasselorsdelutilisationdephpMyAdmin,vouspouvezutiliserla mthodedauthentificationconfig aveccettemthode,lenomdelutilisateuretlemotdepassesontstocksdansle fichierdeconfiguration.Cedernierdoitcontenirlestroislignessuivantes : $cfg[Servers][$i][auth_type] = config; $cfg[Servers][$i][user] = root; // nom de lutilisateur $cfg[Servers][$i][password] = xhz12A8q0; // mot de passe Si vous souhaitez scuriser lutilisation de phpMyAdmin, vous pouvez utiliser la mthode dauthentification cookie aveccettemthode,lenomdutilisateuretlemotdepassesontdemandsparphpMyAdmin.Lefichierdeconfiguration doitcontenirlesdeuxlignessuivantes : $cfg[blowfish_secret] = abZ123aXiu65; ... $cfg[Servers][$i][auth_type] = cookie; Ladirectiveblowfish_secretpermetdedfinirunephrasequiserautilisepourchiffrerlemotdepassedelutilisateur. uelquesoitlemodedauthentificationchoisi,lenomdutilisateuretlemotdepasseutilisspourlaconnexion Q phpMyAdmin doivent tre ceux dun compte MySQL valide. Consultez la documentation de phpMyAdmin pour obtenirplusdinformationssurlefichierdeconfigurationetlesdiffrentsmodesdauthentification.

Pagedaccueil LapagedaccueildephpMyAdminaffichequelquesinformationsgnralessurleserveur :

- 6-

ENI Editions - All rigths reserved

Entreautresactions,cettepagedaccueilpermetdecrerunenouvellebasededonnes(formulaireCrerunebase dedonnes). Danslapartiegauchedelafentre,phpMyAdminaffichelalistedesbasesdedonnesgresparleserveurMySQL. Surlapagedaccueil,vouspouvezcliquersurleliencorrespondantunebasededonnesafindaccderlapage dadministrationdecettebasededonnes. Pagedadministrationdunebasededonnes

ENI Editions - All rigths reserved

- 7-

Lapagedadministrationdunebasededonnesproposeplusieursonglets : Structure Cetongletaffichelalistedestablesetlalistedesprogrammesstocksetproposeplusieurslienseticnespourgrer cesdiffrentsobjets.Pourditerunobjet,ilsuffitdecliquersurlicneStructure( )associe. SQL CetongletpermetdcriredesrequtesSQLsurlabasededonnesactuellementslectionne. Rechercher Cetongletpermetderechercherdesdonnesdansuneouplusieurstables. Requte CetongletproposeunditeurquipermetdeconstruiredesrequtesSQLsansconnatrelelangageSQL. Exporter Cetongletpermetdexportertoutoupartiedunebasededonnessousdiffrentesformes. Importer Cetongletpermetdexcuterlesrequtescontenuesdansunfichier. Oprations Cetongletpermetdeffectuerdiversesoprationssurlabasededonnes. Privilges Cetongletaffichelesdroitsdesutilisateursquiontaccslabasededonnescourante. Supprimer Cetongletpermetdesupprimerlabasededonnescourante.
- 8 ENI Editions - All rigths reserved

Danslapartiegauchedelafentre,phpMyAdminaffichelalistedestablesdelabasededonnes.Vouspouvezcliquer surleliencorrespondantunetableafindelditer. Pagedditiondunetable

Lapagedditiondunetableproposeplusieursonglets : Afficher Cetongletaffichelesdonnesdelatableetpermetdelesmodifier. Structure Cetongletaffichelastructuredelatableetproposeplusieurslienseticnespourmodifiercettestructure(ajouterou supprimerdescolonnes,desindex,etc.).Pourditerunobjet,ilsuffitdecliquersurlicneModifier( )associe. SQL CetongletpermetdcriredesrequtesSQLsurlatable. Rechercher Cetongletpermetderechercherdesdonnesdanslatable. Insrer Cetongletproposeunformulairequipermetdinsrerdesnouvelleslignesdanslatable. Exporter Cetongletpermetdexporterlatablesousdiffrentesformes. Importer Cetongletpermetdimporterdesdonnesdanslatable.

ENI Editions - All rigths reserved

- 9-

Oprations Cetongletpermetdeffectuerdiversesoprationssurlatable. Vider Cetongletpermetdeviderlatabledesoncontenusanslasupprimer(ordreSQLTRUNCATE). Supprimer Cetongletpermetdesupprimerlatable.

5.Fichierdeconfiguration
LesdiffrentsprogrammesMySQL,dontleserveur mysqld,peuventtreconfigursparplusieursoptionspassesen lignedecommandeouspcifiesdansunfichierdeconfiguration. Sur une plateforme Linux, le fichier de configuration sappelle my.cnf et se trouve gnralement dans le rpertoire /etc.SuruneplateformeWindows,lefichierdeconfigurationsappelle my.inietsetrouvegnralement danslerpertoireWindows( c:\windowsparexemple). Lefichierdeconfigurationcomporteplusieurssectionsdlimitespardesmotsentrecrochets. Lasection[client]permetdedfinirdesoptionspourlesprogrammesclientscommemysql :port,motdepasse,etc. Lasection[mysqld]permetdespcifierdesoptionspourleserveur.

- 10 -

ENI Editions - All rigths reserved

Installernotrebasededonnesdedmonstration
Danslasuitedecechapitre,nousallonstravailleravecunebasededonnesnommeeni. CettebasededonnesENIpeuttrecrelaideduscriptcreer-base-eni.sqlsuivant : -- Cration de la base de donnes. DROP DATABASE IF EXISTS eni ; CREATE DATABASE eni; USE eni; -- Cration de la table RUBRIQUE. CREATE TABLE rubrique ( id INT PRIMARY KEY AUTO_INCREMENT, titre VARCHAR(20) NOT NULL, id_parent INT ); INSERT INTO rubrique (id,titre,id_parent) VALUES (1,Base de donnes,NULL), (2,Dveloppement,NULL), (3,Internet,NULL), (4,Open Source,NULL) ; INSERT INTO rubrique (titre,id_parent) VALUES (MySQL,1), (Oracle,1), (Langages,2), (Mthode,2), (HTML - XML,3), (Conception Web,3), (Scurit,3), (Systme,4), (Langages,4), (Base de donnes,4) ; -- Cration de la table COLLECTION. CREATE TABLE collection ( id INT PRIMARY KEY AUTO_INCREMENT, nom VARCHAR(25) NOT NULL UNIQUE, prix_ht DECIMAL(5,2) DEFAULT 20, frais_ht DECIMAL(5,2) ); INSERT INTO collection (nom,prix_ht,frais_ht) VALUES (Ressources Informatiques,24.44,1.5), (TechNote,9.48,NULL), (Les TP Informatiques,25.59,1.5), (Coffret Technique,46.45,2) ; -- Cration de la table AUTEUR. CREATE TABLE auteur ( id INT PRIMARY KEY AUTO_INCREMENT, nom VARCHAR(40) NOT NULL, prenom VARCHAR(40) NOT NULL, mail VARCHAR(200), tel_bureau VARCHAR(10), tel_portable VARCHAR(10),

ENI Editions - All rigths reserved

- 1-

tel_domicile VARCHAR(10), mot_de_passe BLOB, profil BLOB, UNIQUE (nom,prenom) ); INSERT INTO auteur (nom,prenom,mail,tel_bureau,tel_portable,tel_domicile) VALUES (HEURTEL,Olivier,NULL,NULL,0687731346,0102030405), (THIBAUD,Cyril,NULL,0203040506,NULL,NULL), (GUERIN,Brice-Arnaud,NULL,NULL,NULL,0304050607) ; -- Cration de la table PROMOTION. CREATE TABLE promotion ( id INT PRIMARY KEY AUTO_INCREMENT, intitule VARCHAR(40) NOT NULL, date_debut DATE, date_fin DATE, est_active BOOLEAN ); INSERT INTO promotion (intitule,date_debut,date_fin,est_active) VALUES (-5% sur cet ouvrage,CURDATE(),ADDDATE(CURDATE(),10),TRUE), (Frais de port offerts sur cet ouvrage,NULL,NULL,FALSE), (Un superbe marque page en cadeau,NULL,NULL,FALSE) ; -- Cration de la table LIVRE. CREATE TABLE livre ( id INT PRIMARY KEY AUTO_INCREMENT, isbn VARCHAR(20), titre VARCHAR(100) NOT NULL, sous_titre VARCHAR(100), nombre_pages INT, annee_parution YEAR(4), niveau ENUM(Dbutant,Initi,Confirm,Expert), id_collection INT, id_promotion INT, description TEXT, couverture BLOB, date_maj TIMESTAMP ); INSERT INTO livre (isbn,titre,sous_titre,nombre_pages,annee_parution,niveau,id_collection, id_promotion,description,couverture) VALUES (2-7460-1451-3,PHP 4, Dvelopper un site Web dynamique et interactif, 447,2001,Initi,1,1,NULL,NULL), (978-2-7460-3992-6,PHP 5.2, Dvelopper un site Web dynamique et interactif, 518,2007,Initi,1,1,NULL,NULL), (2-7460-3104-3,PHP 5, L\accs aux donnes (MySQL, Oracle, SQL Server, SQLite...), 211,2006,Expert,2,1,NULL,NULL), (2-7460-2778-X,Oracle 10g, Administration, 489,2005,Initi,1,NULL,NULL,NULL), (2-7460-2834-4,Oracle 10g, Installation du serveur sous Windows/Linux - Oracle Net, 161,2005,Expert,2,NULL,NULL,NULL), (2-7460-2833-6,Oracle 10g, Sauvegarde et restauration de la base de donnes avec RMAN, 174,2005,Expert,2,NULL,NULL,NULL), (2-7460-2281-8,BusinessObjects 6,

- 2-

ENI Editions - All rigths reserved

NULL, 470,2004,Initi,1,NULL,NULL,NULL), (2-7460-3004-7,MySQL 5, Installation, mise en uvre, administration et programmation, 468,2006,Initi,1,NULL,NULL,NULL), (2-7460-2340-7,PHP et MySQL (versions 4 et 5), Entranez-vous crer des applications professionnelles, 272,2004,Initi,3,NULL,NULL,NULL), (2-7460-3377-1,MySQL 5 et PHP 5, Matrisez les sites web dynamiques, 972,2006,Initi,4,2,NULL,NULL) ; -- Cration de la table AUTEUR_LIVRE. CREATE TABLE auteur_livre ( id_auteur INT, id_livre INT, PRIMARY KEY (id_auteur,id_livre) ); INSERT INTO auteur_livre (id_auteur,id_livre) VALUES (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (1,7), (2,8), (3,9), (1,10), (2,10) ; -- Cration de la table RUBRIQUE_LIVRE. CREATE TABLE rubrique_livre ( id_rubrique INT, id_livre INT, PRIMARY KEY (id_rubrique,id_livre) ); INSERT INTO rubrique_livre SELECT rub.id,liv.id FROM livre liv,rubrique rub WHERE liv.titre like %PHP% AND rub.titre IN (Langages,Conception Web) AND rub.id_parent IS NOT NULL; INSERT INTO rubrique_livre SELECT rub.id,liv.id FROM livre liv,rubrique rub WHERE liv.titre like %MySQL% AND rub.titre IN (MySQL,Base de donnes) AND rub.id_parent IS NOT NULL; INSERT INTO rubrique_livre SELECT rub.id,liv.id FROM livre liv,rubrique rub WHERE liv.titre like %Oracle% AND rub.titre IN (Oracle) AND rub.id_parent IS NOT NULL; -- Cration de la table CATALOGUE. CREATE TABLE catalogue ( code VARCHAR(10) NOT NULL UNIQUE,

ENI Editions - All rigths reserved

- 3-

titre VARCHAR(100) NOT NULL UNIQUE, prix_ttc DECIMAL(5,2) NOT NULL ); -- Cration de trois programmes stocks delimiter // CREATE PROCEDURE ps_creer_collection ( -- Nom de la nouvelle collection. IN p_nom VARCHAR(25), -- Prix HT de la nouvelle collection. IN p_prix_ht DECIMAL(5,2), -- Identifiant de la nouvelle collection. OUT p_id INT ) BEGIN /* ** Insrer la nouvelle collection et ** rcuprer lidentifiant affect. */ INSERT INTO collection (nom,prix_ht) VALUES (p_nom,p_prix_ht); SET p_id = LAST_INSERT_ID(); END; // CREATE PROCEDURE ps_lire_sous_rubriques ( -- Identifiant dune rubrique (parent). IN p_id_parent INT ) BEGIN /* ** Slectionner les sous-rubriques dune ** rubrique dont lidentifiant est pass ** en paramtre. */ SELECT titre FROM rubrique WHERE id_parent = p_id_parent; END; // CREATE FUNCTION fs_nombre_sous_rubriques ( -- Identifiant dune rubrique (parent). p_id_parent INT ) RETURNS INT BEGIN /* ** Compter le nombre de sous-rubriques dune ** rubrique dont lidentifiant est pass ** en paramtre. */ DECLARE v_resultat INT; SELECT COUNT(*) INTO v_resultat FROM rubrique WHERE id_parent = p_id_parent; RETURN v_resultat; END; // delimiter ;

- 4-

ENI Editions - All rigths reserved

-- Cration dun utilisateur eniweb. DROP USER eniweb@localhost; CREATE USER eniweb@localhost IDENTIFIED BY web; GRANT SELECT,INSERT,UPDATE,DELETE,EXECUTE ON eni.* TO eniweb@localhost; -- Affichage des tables. SHOW TABLES; Cescriptpeuttrercuprsurlesitedelditeur(www.enilivres.com). Pourcrerlabasededonnesenilaideduscriptprcdent,vouspouvezprocderdelamaniresuivante :
q

Lancezlapplicationclientemysqletconnectezvousauserveurentantquutilisateurroot :

[root@xampp ~]# m y s q l - u r o o t Welcome to the MySQL monitor. Commands end with ; or \g. ...
q

Excutezlescriptlaidedelacommandesource :

mysql> source creer-base-eni.sql Query OK, 0 rows affected, 1 warning (0.00 sec) Query OK, 1 row affected (0.00 sec) Database changed ... ... +----------------+ | Tables_in_eni | +----------------+ | auteur | | auteur_livre | | catalogue | | collection | | livre | | promotion | | rubrique | | rubrique_livre | +----------------+ 8 rows in set (0.00 sec)

Silescriptnestpasstockdanslerpertoirecourant,indiquezunchemincompletdanslacommandesource.

ENI Editions - All rigths reserved

- 5-

ApprendrelesbasesdulangageSQL
1.Typesdedonnes
MySQLproposeplusieurstypesdedonnespourladfinitiondescolonnesdestables.DanslechapitreConstruireune base de donnes dans MySQL, nous verrons comment utiliser ces types de donnes dans les ordres de cration de table.

a.Typeschanedecaractres
MySQLproposelesprincipauxtypessuivantspourleschanesdecaractres : CHAR[(n)] [BINARY] Chanedelongueurfixe,dencaractres(ncomprisentre0et255,1pardfaut).Lorsdustockage,lachaneest compltedroitepardesespacesjusqulalongueurdemande cesespacessontautomatiquementsupprims lorsquelachaneestlue. VARCHAR(n) [BINARY] Chanedelongueurvariable,dencaractresmaximum(ncomprisentre0et65535,1pardfaut).Lorsdustockage, aucunespacenestajout.Ilfautnoterquesilachanecontientdesespacesdroite,ceuxcinesontpassupprims lorsquelachaneestlue. TINYTEXT [BINARY] Chanedelongueurvariablejusqu255caractres.quivalentVARCHAR(255). TEXT [BINARY] Chanedelongueurvariablejusqu216-1caractres. MEDIUMTEXT [BINARY] Chanedelongueurvariablejusqu224-1caractres. LONGTEXT [BINARY] Chanedelongueurvariablejusqu232-1caractres. ENUM(valeur[,...]) numration.Chanedontlavaleurdoitappartenirunelistedevaleurs(outreNULL).Unenumrationpeut contenir65535valeursdistinctesaumaximum. SET(valeur[,...]) Ensemble.Chanequipeutcontenirzro,uneouplusieursvaleursparmiunelistedevaleurs.Unensemblepeut contenir64valeursdistinctesaumaximum. Pardfaut,leschanesdecaractresnesontparsensibleslacasse( Aestgala).Lemotcl BINARY,dansla dfinitiondutype,permetdavoirunechane binaire sensiblelacasse. LestypesdedonnesENUMetSETnesontpassensibleslacasse. omptetenudelasuppressiondesespaceslorsdelalecture,ab (espaceenfindechane)stockdansune C colonnedetypeVARCHARnestpasgalab stockdansunecolonnedetypeCHAR.

b.Typesnumriques
MySQLproposelesprincipauxtypesnumriquessuivants :

ENI Editions - All rigths reserved

- 1-

TINYINT[(m)] Entiersignsur8bits(-128+127). SMALLINT[(m)] Entiersignsur16bits(-32768+32767). SMALLINT[(m)] UNSIGNED Entiernonsignsur16bits(065535). MEDIUMINT[(m)] Entiersignsur24bits(-223+223-1). MEDIUMINT[(m)] UNSIGNED Entiernonsignsur24bits(0+224-1). INT[(m)] Entiersignsur32bits(-231+231-1). INT[(m)] UNSIGNED Entiernonsignsur32bits(0+232-1). BIGINT[(m)] Entiersignsur64bits(-263+263-1). BIGINT[(m)] UNSIGNED Entiernonsignsur64bits(0+264-1). FLOAT[(n,d)] [UNSIGNED] Nombrevirguleflottanteensimpleprcision.nspcifielenombredechiffressignificatifsetdlenombredechiffres aprslavirgule sinetdsontomis,MySQLutiliselesvaleursmaximalespermisesparlamachine.Silemotcl UNSIGNEDestspcifi,lesnombresngatifssontinterdits. DOUBLE[(n,d)] [UNSIGNED] Nombrevirguleflottanteendoubleprcision. nspcifielenombredechiffressignificatifset dlenombredechiffres aprs la virgule si n et d sont omis, MySQL utilise les valeurs maximales permises par la machine. Si le mot cl UNSIGNEDestspcifi,lesnombresngatifssontinterdits. FLOAT(p) [UNSIGNED] Nombrevirguleflottante.Pspcifielaprcisionenbits.CetteprcisionestutiliseparMySQLpourdterminerle typeutilis :FLOATentre0et24etDOUBLEentre25et53. DECIMAL[(n[,d])] [UNSIGNED] Nombrevirgulefixe.nspcifielenombredechiffressignificatifs(10pardfaut,65aumaximum)etdlenombrede chiffresaprslavirgule(0pardfaut,30aumaximum).SilemotclUNSIGNEDestspcifi,lesnombresngatifssont interdits. Pour les diffrents types entiers, le nombre optionnel m permet de dfinir une longueur daffichage (pas une contraintesurlaplagedevaleursautorises) lesvaleursentiresdontlalongueurestinfrieurecettelimitesont affichescompltesgauchepardesespaces.Pourcompltergauchepardeszros,ilestpossibledajouterle motclZEROFILLlafindeladfinitiondutype. INTEGERestunsynonymedeINT.

- 2-

ENI Editions - All rigths reserved

DEC,NUMERICetFIXEDsontdessynonymesdeDECIMAL.

c.Typeboolen
BOOL,BOOLEAN SynonymesdeTINYINT(1)utilisspourreprsenterunevaleurboolenne( 0estconsidrcommefaux touteautre valeurestconsidrecommevraie).

d.Typesdateetheure
MySQLproposelesprincipauxtypessuivantspourlesdatesetheures : DATE Datecompriseentrele01/01/1000et 31/12/9999.Formatpardfaut :YYYY-MM-DD. DATETIME Dateetheurecompriseentrele01/01/1000 00:00:00et31/12/9999 23:59:59.Formatpardfaut :YYYY-MM-DD HH:MM:SS. TIMESTAMP Dateetheurecompriseentrele01/01/1970 00:00:01et19/01/2038 04:14:08.Formatpardfaut :YYYY-MM-DD HH:MM:SS. TIME Heurecompriseentre-838:59:59et838:59:59.Formatpardfaut :HH:MM:SS. YEAR[(2|4)] Annesur2ou4chiffres(4pardfaut),compriseentre70(pour1970)et69(pour2069)pourlannesur2chiffreset entre1901et2155pourlannesur4chiffres.Formatpardfaut :YYYY.

L etypededonnesTIMESTAMPachangentrelaversion4etlaversion5.

e.Typespourlesdonnesbinaires
MySQLproposelesprincipauxtypessuivantspourlesdonnesbinaires(image,son,etc.) : TINYBLOB Donnebinairejusqu255octets. BLOB Donnebinairejusqu216-1octets. MEDIUMBLOB Donnebinairejusqu224-1octets. LONGBLOB Donnebinairejusqu232-1octets. Sicestypessontutilisspourstockerdeschanesdecaractres,cesderniressontsensibleslacasse.

ENI Editions - All rigths reserved

- 3-

2.Nomdesobjets
Unnomdebasededonnes,detable,decolonneoudindexestlimit64octets. Pourvoussimplifierlatche,nousvousconseillonsdenutiliserquedescaractresnonaccentus,deschiffresetles caractres$et_(soulign)pourvosnomsdobjets.Lutilisationdetoutautrecaractreimposeeneffetdedlimiterle nomsoitpardesapostrophesobliques( `)soitpardesguillemets(")silaconfigurationduserveurlepermet. Avec MySQL, les bases de donnes et les tables correspondent des dossiers et des fichiers. En consquence, les nomsdebasesdedonnesetdetablessontsensibleslacassesilesnomsdefichierslesontauniveaudusystme dexploitation.Celasignifiequelesnomsdebasesdedonnesetdetablessontsensibleslacassesurlesplates formesUnixetLinuxetnonsensibleslacassesurlesplatesformesWindows. Lesnomsdecolonnesnesontpassensibleslacasse. Lessyntaxespermettantderfrencerunnomdetableetunnomdecolonnesontlessuivantes : [nom_base.]nom_table [[nom_base.]nom_table.]nom_colonne Unnomdetablepeuttrerfrencdirectementsilatableeststockedanslabasededonnescourante.Silatable appartient une autre base de donnes, il est ncessaire de prfixer le nom de la table par le nom de la base de donnespouryfairerfrence. De mme, un nom de colonne peut tre prfix par un nom de table (luimme prfix par un nom de base de donnes). Dans la suite de cet ouvrage, dans les descriptions de syntaxe, les termes nom_table et nom_colonne dsignent respectivementunnomdunetableetunnomdecolonne,aveclesdiffrentespossibilitsdesyntaxeprsentesci dessus.

3.Valeurslittrales
a.Chane
Unechanelittraleestdlimitepardesapostrophes :ceci est une chane. Si la configuration du serveur MySQL le permet, il est aussi possible de dlimiter une chane littrale par des guillemets.CettepossibilitestdconseillecarellenerespectepaslanormeANSI. lintrieurdunechane,certainessquencesdecaractresprcdesparlecaractredchappementantislash(\) ontunesignificationspciale : \ Apostrophe \" Guillemet \n Nouvelleligne \r Retourchariot \t Tabulation \\ Antislash Pour intgrer une apostrophe lintrieur dune chane littrale dlimite par des apostrophes, il existe deux

- 4-

ENI Editions - All rigths reserved

possibilits :
q

doublerlapostrophe :larticle faireprcderlapostropheparlecaractredchappementantislash :l\article.

Pardfaut,leschanesdecaractresnesontpassensibleslacasse,saufsiellessontdfiniessouslaformedune chanebinaire,cequipeuttrefaitenfaisantprcderlavaleurdeloprateurBINARY.Ainsi,pardfautaestgal A,maisBINARYa estdiffrentdeA,

b.Nombre
Un nombre peut tre crit directement, sans dlimiteur. Le sparateur dcimal est le point (.). La notation exponentielleestautorise. Exemples 123 -10 1.23 1.2e3

c.Date,heure,date/heure
Unedatepeuttrecritesoitsouslaformedunechaneauformat YYYY-MM-DD,soitsouslaformedunnombreau formatYYYYMMDD. Uneheurepeuttrecritesoitsouslaformedunechaneauformat HH:MM:SS,soitsouslaformedunnombreau formatHHMMSS. Unedate/heurepeuttrecritesoitsouslaformedunechaneauformatYYYY-MM-DD HH:MM:SS,soitsouslaforme dunnombreauformatYYYYMMDDHHMMSS.Lheureestcompriseentre0et23. Exemples 2001-12-19 20031213 2001-12-19 23:15:00 20031213031500

d.Boolen
Les deux valeurs boolennes vrai et faux peuvent tre reprsentes par les constantes TRUE (valeur 1) et FALSE(valeur0).Lenomdecesconstantesnestpassensiblelacasse.

4.Expression
Uneexpressionpeututiliserdesvaleurslittrales,desnomsdecolonnes,desvariables,lesoprateursarithmtiques habituels(+,-,*,/),desparenthsesetdesfonctions(cf.chapitreUtiliserlesfonctionsMySQL). Exemples prix_ht * ( 1 + taux_tva/100 ) UPPER(titre)

5.ValeurNULL
LavaleurNULLsignifielabsencedevaleur.NULLestdiffrentde0,etdiffrentdunechanevide. UneexpressionquicontientunevaleurNULLdonnetoujoursunrsultatNULL(parexemple,10 + NULLestgalNULL). Lesvaleurs NULLsontsouventsourcedeproblme danslasuitedecetouvrage,nousverronscommentviterces

ENI Editions - All rigths reserved

- 5-

problmes.

6.Variables
a.Variablesutilisateurs
MySQLpermetdutiliserdesvariablesutilisateursspcifiqueslaconnexionaveclasyntaxe @nom_variable.Unnom devariablepeutcontenirdescaractresalphanumriques,ainsiquelescaractres_ ,$ et.. Lesvariablesnontpasbesoindtreinitialisesavantdtreutilises pardfaut,ellescontiennentlavaleur NULL. Unevariableutilisateurpeutcontenirunnombre(entierourel)ouunechanedecaractres. Lesvariablespeuventtreutilisesdansdesexpressions. Pouraffecterunevaleurunevariable,vouspouvezutiliserlacommandeSET. Syntaxe SET @nom_variable = expression [,...] Pourafficherlavaleurdunevariable,vouspouvezutiliserunesyntaxesimplifiedelordreSELECT. Syntaxe SELECT @nom_variable [,...] Exemple mysql> SET @taux_tva=19.6; Query OK, 0 rows affected (0.00 sec) mysql> SELECT ROUND(100 * ( 1 + @taux_tva/100 ),2); +--------------------------------------+ | ROUND(100 * ( 1 + @taux_tva/100 ),2) | +--------------------------------------+ | 119.60 | +--------------------------------------+ 1 row in set (0.00 sec)

b.Variablessystmes
MySQL fournit un grand nombre de variables qui permettent dobtenir des informations sur le fonctionnement du serveur. Dans la plupart des cas, la valeur de ces variables peut tre modifie pour changer le fonctionnement du serveur. Ilexistedeuxtypesdevariables :
q

Les variables globales qui affectent lensemble du serveur. Ces variables globales sont initialises au dmarrageduserveur,partirdufichierdeconfigurationetdesargumentspasssenlignedecommandeau serveurMySQL. Lesvariablesdesessionquiaffectentlesconnexions.Cesvariablesdesessionsontinitialisesaumoment delaconnexionpartirdesvaleursdesvariablesglobalescorrespondantes.

LacommandeSETpermetdemodifierlavaleurdunevariableglobaleoudesession. Syntaxes SET SET SET SET GLOBAL nom_variable = valeur @@global.nom_variable = valeur [SESSION] nom_variable = valeur [@@[session.]]nom_variable = valeur

Les deux premires syntaxes permettent de modifier une variable globale et les deux dernires une variable de session( SESSIONetsessionsontoptionnels).LOCALestsynonymedeSESSION.

- 6-

ENI Editions - All rigths reserved

Lamodificationdunevariableglobalenaffectepaslessessionsdjconnectes(pasmmelasessionquieffectuela modification). Pour afficher la valeur dune variable globale ou de session, vous pouvez utiliser une syntaxe simplifie de lordre SELECT. Syntaxes SELECT @@global.nom_variable SELECT @@[session.]nom_variable Exemple mysql> SELECT @@lc_time_names; +-----------------+ | @@lc_time_names | +-----------------+ | en_US | +-----------------+ 1 row in set (0.00 sec) mysql> SET @@lc_time_names=fr_FR; Query OK, 0 rows affected (0.00 sec)

7.Commentaires
MySQLsupportetroistypesdecommentaires :
q

depuislecaractre#(dise)jusqulafindelaligne depuislasquence-- (deuxtiretssuivisdunespace)jusqulafindelaligne entrelessquences/*et*/,cesdeuxsquencespouvanttresurdeslignesdiffrentes.

Exemple /* Exemple de commentaire crit sur plusieurs lignes */ SELECT * FROM collection ORDER BY rand(); -- tri alatoire ! (commentaire mono-ligne)

ENI Editions - All rigths reserved

- 7-

ExcuterdesrequtesSQLsimples
1.LemodeSQLduserveur
Le serveur MySQL peut fonctionner selon diffrents modes SQL. Le mode SQL dfinit quelle syntaxe SQL peut tre utiliseetquellesvrificationsleserveurdoitfaire,notammentlorsdesmisesjour. LemodeSQLutilisaudmarrageestdfiniparlavaleurdeloption sql-mode(surlalignedecommandedudmon MySQLoudanslefichierdeconfiguration). Depuislaversion4.1,vouspouvezmodifierlemodeSQLaprsledmarragegrcelavariablesystmesql_mode.Le modeSQLpeuttremodifiauniveauglobalouauniveausession(chaqueconnexionpeututiliserunmodediffrent adaptcesbesoins). LemodeSQLestdfiniparunelistedemotsclssparspardesvirgules.Lavaleurpardfautestvide(pasdemode configur). Avec le mode par dfaut (pas de mode), le serveur MySQL vite de gnrer des erreurs lors des mises jour et nhsitepasmodifierdesvaleurspourpermettreleuraffectationunecolonne unesimplealerteestmise. Pourmodifiercecomportement,lesmodes STRICT_TRANS_TABLES ou STRICT_ALL_TABLESpeuventtreutiliss :cestle mode SQL "strict". Dans ce mode, les valeurs invalides sont rejetes et une erreur est gnre. Le mode STRICT_ALL_TABLES sapplique tous les moteurs de stockage le mode STRICT_TRANS_TABLES sappliqueuniquement auxmoteursdestockagetransactionnel. Nousreviendronsplusendtailsurcesujetdanslasuitedecechapitre. anotiondemoteurdestockageestprsentedanslechapitreConstruireunebasededonnesdansMySQL L Grerlestables. ExempledaffichageetdemodificationdumodeSQL mysql> SELECT @@sql_mode; +------------+ | @@sql_mode | +------------+ | | +------------+ 1 row in set (0.00 sec) mysql> SET @@sql_mode=STRICT_ALL_TABLES; Query OK, 0 rows affected (0.00 sec) mysql> SELECT @@sql_mode; +-------------------+ | @@sql_mode | +-------------------+ | STRICT_ALL_TABLES | +-------------------+ 1 row in set (0.00 sec)

IlexistedautresmodesSQL( ANSI,TRADITIONAL,etc.).Pourensavoirplus,consultezladocumentation.

2.Obtenirdesinformations
Linstruction SQL SHOW offre diffrentes formes qui permettent dobtenir des informations sur le serveur MySQL, les basesdedonnesquilgreetlecontenudecesbasesdedonnes(lestables,lescolonnes,etc.). Dans cette section, nous prsentons les formes les plus utilises de la commande SHOW permettant dafficher des informations sur les bases de donnes gres par le serveur, les tables stockes dans une base de donnes et la structuredunetable : SHOW DATABASES

ENI Editions - All rigths reserved

- 1-

SHOW SCHEMAS ListedesbasesdedonnesgresparleserveurmySQL. SHOW TABLES Listedestablesstockesdanslabasededonnescourante. SHOW COLUMNS FROM nom_table { DESCRIBE | DESC } nom_table Listedescolonnesdunetable. Exemple mysql> S H O W D A T A B A S E S ; +--------------------+ | Database | +--------------------+ | information_schema | | cdcol | | eni | | mysql | | phpmyadmin | | test | +--------------------+ 6 rows in set (0.00 sec) mysql> U S E e n i ; Database changed mysql> S H O W T A B L E S ; +----------------+ | Tables_in_eni | +----------------+ | auteur | | auteur_livre | | catalogue | | collection | | livre | | promotion | | rubrique | | rubrique_livre | +----------------+ 6 rows in set (0.00 sec) mysql> D E S C c o l l e c t i o n ; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | nom | varchar(25) | NO | UNI | | | | prix_ht | decimal(5,2) | YES | | 20.00 | | | frais_ht | decimal(5,2) | YES | | NULL | | +----------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) mysql> DanslechapitreConstruireunebasededonnesdansMySQL,nousverronsdautresvariantesdelacommande SHOW quipermettentdercuprerdesinformationssurlesvues,lesprocduresetlestriggers.

3.Afficherleserreursetlesalertes
La commande SHOW WARNINGS permet dafficher les alertes ou les erreurs gnres par la dernire commande. La

- 2-

ENI Editions - All rigths reserved

commandeSHOW ERRORSpermetdafficheruniquementleserreursgnresparladernirecommande. Danslapplicationcliente mysql,leserreursgnresparladernirecommandesontautomatiquementaffiches.Par contre, pour les alertes, lapplication indique uniquement le nombre dalertes gnres mais ne les affiche pas la commandeSHOW WARNINGSestalorstrsutile. Exemple mysql> INSERT INTO rubrique(titre) -> VALUES(Messagerie et travail de groupe); Query OK, 1 row affected, 1 w a r n i n g (0.00 sec) mysql> S H O W W A R N I N G S ; +---------+------+--------------------------------------------+ | Level | Code | Message | +---------+------+--------------------------------------------+ | Warning | 1265 | Data truncated for column titre at row 1 | +---------+------+--------------------------------------------+ 1 row in set (0.00 sec)

4.Lirelesdonnes
a.SyntaxedebasedelordreSELECT
LordreSQLSELECTpermetdelirelesdonnes. LasyntaxelaplussimplepourlordreSELECTestlasuivante : SELECT [DISTINCT] expression[,...] | * FROM nom_table La clause FROM indique dans quelle table lire les donnes. Nous verrons plus loin comment lire les donnes dans plusieurstables. La clause SELECT contient une liste dexpressions spares par une virgule. Une expression peut tre une colonne dunetable,unevaleurlittraleouuneexpressioncalculeutilisantventuellementuneouplusieurscolonnesdune table.laplacedunelistedexpressions,ilestpossibledutiliserunastrisquepourindiquerquetouteslescolonnes sontslectionnes. Aveclasyntaxesuivante,toutesleslignesdelatablesontretournes.Nousverronsplusloincommentrestreindrele rsultatdunerequte. Exemples mysql> SELECT * FROM collection; +----+--------------------------+---------+----------+ | id | nom | prix_ht | frais_ht | +----+--------------------------+---------+----------+ | 1 | Ressources Informatiques | 24.44 | 1.50 | | 2 | TechNote | 9.48 | NULL | | 3 | Les TP Informatiques | 25.59 | 1.50 | | 4 | Coffret Technique | 46.45 | 2.00 | +----+--------------------------+---------+----------+ 4 rows in set (0.00 sec) mysql> SELECT id,nom FROM collection; +----+--------------------------+ | id | nom | +----+--------------------------+ | 1 | Ressources Informatiques | | 2 | TechNote | | 3 | Les TP Informatiques | | 4 | Coffret Technique | +----+--------------------------+ 4 rows in set (0.00 sec) mysql> SELECT nom,prix_ht+ROUND(prix_ht*5.5/100,2) FROM collection; +--------------------------+----------------------------------+

ENI Editions - All rigths reserved

- 3-

| nom | prix_ht+ROUND(prix_ht*5.5/100,2) | +--------------------------+----------------------------------+ | Ressources Informatiques | 25.78 | | TechNote | 10.00 | | Les TP Informatiques | 27.00 | | Coffret Technique | 49.00 | +--------------------------+----------------------------------+ 4 rows in set (0.00 sec) Surledernierexemple,ROUND(prix_ht*(1+5.5/100),2)estuneexpressioncalculesurlacolonneprix_ht. LemotclDISTINCTpermetdobteniruneseuleoccurrencedechaqueensembledelignesdupliques. Exemple mysql> SELECT annee_parution FROM livre; +----------------+ | annee_parution | +----------------+ | 2001 | | 2007 | | 2006 | | 2005 | | 2005 | | 2005 | | 2004 | | 2006 | | 2004 | | 2006 | +----------------+ 10 rows in set (0.00 sec) mysql> SELECT DISTINCT annee_parution FROM livre; +----------------+ | annee_parution | +----------------+ | 2001 | | 2007 | | 2006 | | 2005 | | 2004 | +----------------+ 5 rows in set (0.00 sec) mysql> SELECT annee_parution,niveau FROM livre; +----------------+--------+ | annee_parution | niveau | +----------------+--------+ | 2001 | Initi | | 2007 | Initi | | 2006 | Expert | | 2005 | Initi | | 2005 | Expert | | 2005 | Expert | | 2004 | Initi | | 2006 | Initi | | 2004 | Initi | | 2006 | Initi | +----------------+--------+ 10 rows in set (0.00 sec) mysql> SELECT DISTINCT annee_parution,niveau FROM livre; +----------------+--------+ | annee_parution | niveau | +----------------+--------+ | 2001 | Initi | | 2007 | Initi | | 2006 | Expert | | 2005 | Initi | | 2005 | Expert |
- 4 ENI Editions - All rigths reserved

| 2004 | Initi | | 2006 | Initi | +----------------+--------+ 7 rows in set (0.00 sec) Lordre SELECT peut aussi tre utilis pour lire des expressions calcules, ou des variables, sans rfrence une table.Danscecas,laclauseFROMestabsente. Exemple mysql> SELECT 1+2+3; +-------+ | 1+2+3 | +-------+ | 6 | +-------+ 1 row in set (0.00 sec) Depuislaversion4.1,vouspouvezspcifier dualcommenomdetabledanslaclause FROM,danslecasoaucune table nest rfrence. Cette possibilit permet dtre compatible avec les serveurs de base de donnes qui ne supportentpasleSELECTsansclauseFROM. Exemple mysql> SELECT 1+2+3 FROM dual; +-------+ | 1+2+3 | +-------+ | 6 | +-------+ 1 row in set (0.00 sec) DanslaclauseSELECTuneexpressionpeuttresuiviedunaliasquipermetdenommerlexpression. Syntaxe expression [AS] alias LemotclASestoptionnel. Exemple mysql> SELECT nom,prix_ht+ROUND(prix_ht*5.5/100,2) p r i x _ t t c -> FROM collection; +--------------------------+----------+ | nom | prix_ttc | +--------------------------+----------+ | Ressources Informatiques | 25.78 | | TechNote | 10.00 | | Les TP Informatiques | 27.00 | | Coffret Technique | 49.00 | +--------------------------+----------+ 4 rows in set (0.00 sec) Un alias peut tre appliqu une simple colonne, ce qui a pour effet de renommer la colonne dans linterrogation uniquement(pasdanslatable). Silaliascomportedesespacesoutoutautrecaractrespcial,ildoittresaisientreguillemets. De mme, dans la clause FROM, un nom de table peut tre suivi dun alias qui permet de renommer la table dans linterrogationuniquement(pasdanslabasededonnes). Syntaxe nom_table [AS] alias LemotclASestoptionnel.

ENI Editions - All rigths reserved

- 5-

Unaliasdetablepeuttreutilislaplacedunomdelatablepourprfixerunecolonne. Exemple mysql> SELECT col.nom FROM collection col; +--------------------------+ | nom | +--------------------------+ | Ressources Informatiques | | TechNote | | Les TP Informatiques | | Coffret Technique | +--------------------------+ 4 rows in set (0.00 sec) Cettepossibilitestparticulirementintressantedanslesinterrogationsportantsurplusieurstables. Eneffet,danscegenredinterrogation,ilestconseilldeprfixerlenomdescolonnesparlenomdelatable(oupar unaliasdetable)pourfaciliterlalecturedelarequte(onvoittoutedesuitequelletableappartientlacolonne).Le prfixe est par ailleurs obligatoire lorsque deux tables ont une colonne portant le mme nom et que ce nom est prsentdanslarequte sansprfixelarequteestambiguetprovoqueuneerreur. Exemple mysql> SELECT id FROM livre,collection; ERROR 1052 (23000): Column id in field list is ambiguous Utiliserunaliasdetablelaplacedunomdelatablepourprfixerlescolonnesestintressantlorsquelestables portent des noms "longs" des alias de 3 ou 4 caractres bien choisis (suffisamment significatifs) peuvent avantageusementlesremplacer. ourvoussimplifierlatche,nousvousconseillonsdenutiliserquedescaractresnonaccentus,deschiffres P et les caractres $ et _ (soulign) pour vos alias de table. Lutilisation de tout autre caractre imposera en effet de dlimiter lalias soit par des apostrophes obliques (`) soit par des guillemets (") si la configuration du serveurlepermet.

b.Restreindrelersultat :clauseWHERE
UneclauseWHEREpeuttreajoutelarequteSELECTpourrestreindrelersultat. Syntaxe SELECT [DISTINCT] expression[,...] | * FROM nom_tableWHERE conditions SeulesleslignesvrifiantlesconditionsdelaclauseWHEREsontretournes. Lasyntaxegnraleduneconditionestlasuivante : expression1 oprateur expression2 expression1 et expression2 sont des expressions du type de celles qui peuvent figurer dans la clause SELECT : colonne,valeurlittraleouexpressioncalcule. UneconditionretourneTRUE,FALSEouNULL. Lesoprateurslesplussouventutilisssontlessuivants : = galit > Strictementsuprieur >=

- 6-

ENI Editions - All rigths reserved

Suprieurougal < Strictementinfrieur <= Infrieurougal <>ou!= Diffrent BETWEENminANDmax Suprieurougalminetinfrieurougalmax IN (valeur,...) galitavecnimportequellmentduneliste IS NULL, IS NOT NULL TestesiuneexpressionestNULLounon LIKE Correspondanceparrapportunmodle LesoprateursBETWEEN,INetLIKEpeuventtreinverssparlemotclNOT(NOT BETWEEN,NOT INetNOT LIKE). Exemples mysql> SELECT nom FROM collection WHERE id = 1; +--------------------------+ | nom | +--------------------------+ | Ressources Informatiques | +--------------------------+ 1 row in set (0.01 sec) mysql> SELECT id,nom FROM collection WHERE id <> 1; +----+----------------------+ | id | nom | +----+----------------------+ | 2 | TechNote | | 3 | Les TP Informatiques | | 4 | Coffret Technique | +----+----------------------+ 3 rows in set (0.00 sec)1 row in set (0.00 sec) mysql> SELECT id,nom FROM collection WHERE id IN (1,2); +----+--------------------------+ | id | nom | +----+--------------------------+ | 1 | Ressources Informatiques | | 2 | TechNote | +----+--------------------------+ 2 rows in set (0.01 sec) mysql> SELECT nom,prix_ht FROM collection WHERE prix_ht < 25; +--------------------------+---------+ | nom | prix_ht | +--------------------------+---------+ | Ressources Informatiques | 24.44 | | TechNote | 9.48 | +--------------------------+---------+

ENI Editions - All rigths reserved

- 7-

2 rows in set (0.00 sec) mysql> SELECT nom,prix_ht FROM collection -> WHERE prix_ht BETWEEN 10 AND 25; +--------------------------+---------+ | nom | prix_ht | +--------------------------+---------+ | Ressources Informatiques | 24.44 | +--------------------------+---------+ 1 row in set (0.00 sec) mysql> SELECT prix_ht FROM collection WHERE nom = TECHNOTE; +---------+ | prix_ht | +---------+ | 9.48 | +---------+ 1 row in set (0.00 sec) mysql> -- Recherche sensible la casse mysql> SELECT prix_ht FROM collection WHERE nom = B I N A R Y TECHNOTE; Empty set (0.00 sec) mysql> -- Recherche sur un couple de colonnes mysql> SELECT sous_titre FROM livre -> WHERE (titre,annee_parution) = (Oracle 10g,2005); +------------------------------------------------------------+ | sous_titre | +------------------------------------------------------------+ | Administration | | Installation du serveur sous Windows/Linux - Oracle Net | | Sauvegarde et restauration de la base de donnes avec RMAN | +------------------------------------------------------------+ 3 rows in set (0.00 sec) Les colonnes de type DATETIME ou TIMESTAMP sont susceptibles de stocker une composante horaire. Cette composante horaire peut poser des problmes pour la recherche uniquement sur la partie date. Une premire solutionconsisteeffectuerunerechercheborne unedeuximesolutionconsisteappliquerlafonction DATEla colonnepourliminerlacomposantehoraire(cf.chapitreUtiliserlesfonctionsMySQLFonctionsdates). Exemple mysql> SELECT titre FROM livre WHERE date_maj = 2008-01-19; Empty set (0.01 sec) mysql> SELECT titre FROM livre WHERE DATE(date_maj) = 2008-01-19; +--------------------------------+ | titre | +--------------------------------+ | PHP 5.2 | +--------------------------------+ 1 row in set (0.01 sec) mysql> SELECT titre FROM livre -> WHERE date_maj BETWEEN -> 2008-01-19 00:00:00 AND 2008-01-19 23:59:59; +--------------------------------+ | titre | +--------------------------------+ | PHP 5.2 | +--------------------------------+ 1 row in set (0.01 sec) Pourtestersiuneexpressionest NULL(ounon NULL),ilnefautpasutiliserloprateur =(ou !=)maisloprateur IS NULL(ouIS NOT NULL).Utiliserlesoprateurs=ou!=negnrepasderreur,maislinterrogationneretourneaucun rsultat. Exemple

- 8-

ENI Editions - All rigths reserved

mysql> SELECT titre FROM livre WHERE sous_titre = NULL; Empty set (0.00 sec) mysql> SELECT titre FROM livre WHERE sous_titre IS NULL; +-------------------+ | titre | +-------------------+ | BusinessObjects 6 | +-------------------+ 1 row in set (0.00 sec) mysql> SELECT DISTINCT titre FROM livre -> WHERE sous_titre IS NOT NULL; +--------------------------------+ | titre | +--------------------------------+ | PHP 4 | | PHP 5.2 | | PHP 5 | | Oracle 10g | | MySQL 5 | | PHP et MySQL (versions 4 et 5) | | MySQL 5 et PHP 5 | +--------------------------------+ 7 rows in set (0.00 sec) AvecloprateurLIKE,ilestpossibledutiliserdeuxcaractres"joker" : % Remplaceunnombrequelconquedecaractres(ycomprisaucun). _(soulign) Remplaceexactementuncaractre. Pourrechercherundecesdeuxcaractres,vousdevezlefaireprcderducaractredchappementantislashdans lemodle.Sivoussouhaitezutiliserunautrecaractredchappement,vouspouvezajouterlaclause ESCAPE c, c tantgalaucaractredchappementutilis. Exemple mysql> SELECT DISTINCT titre FROM livre WHERE titre LIKE PHP%; +--------------------------------+ | titre | +--------------------------------+ | PHP 4 | | PHP 5.2 | | PHP 5 | | PHP et MySQL (versions 4 et 5) | +--------------------------------+ 4 rows in set (0.00 sec) mysql> SELECT DISTINCT titre FROM livre -> WHERE titre LIKE %MySQL%PHP%; +------------------+ | titre | +------------------+ | MySQL 5 et PHP 5 | +------------------+ 1 row in set (0.00 sec) Plusieurs conditions simples peuvent tre combines laide des oprateurs logiques habituels OR, AND et NOT. La prcdentepardfautdecesoprateursest NOT,ANDetOR(duplusprioritaireaumoinsprioritaire).Pourvaluerles conditionsdansunordrediffrent,ilfaututiliserdesparenthses. Exemple mysql> SELECT titre FROM livre

ENI Editions - All rigths reserved

- 9-

-> WHERE annee_parution = 2005 AND id_collection = 1; +------------+ | titre | +------------+ | Oracle 10g | +------------+ 1 row in set (0.00 sec) mysql> SELECT titre,annee_parution FROM livre -> WHERE (annee_parution = 2005 OR annee_parution = 2006) -> AND id_collection = 1; +------------+----------------+ | titre | annee_parution | +------------+----------------+ | Oracle 10g | 2005 | | MySQL 5 | 2006 | +------------+----------------+ 2 rows in set (0.01 sec)

c.Trierlersultat :clauseORDERBY
Pardfaut,lersultatduneinterrogationestretourndansunordreindtermin. UneclauseORDER BYpeuttreajoutelarequteSELECTpourtrierlersultat. Syntaxe SELECT [DISTINCT] expression[,...] | * FROM nom_table [WHERE conditions] ORDER BY expression [ASC | DESC][,...] SilarequtecomporteuneclauseWHERE,laclauseORDER BYdoitfigureraprs. Letripeuttrecroissant(ASC)oudcroissant(DESC)ilestcroissantpardfaut.Laclause ORDER BY peut contenir plusieurs expressions de tri spares par des virgules lordre des expressions dtermine lordre de priorit des niveauxdetri. expressionpeuttre :
q

unecolonne uneexpressionbasesurdescolonnes unaliasdecolonne un numro correspondant la position dune expression de la clause SELECT (syntaxe dconseille et obsolte).

Exemples mysql> SELECT nom,prix_ht+ROUND(prix_ht*5.5/100,2) -> FROM collection -> O R D E R B Y n o m ; +--------------------------+----------------------------------+ | nom | prix_ht+ROUND(prix_ht*5.5/100,2) | +--------------------------+----------------------------------+ | Coffret Technique | 49.00 | | Les TP Informatiques | 27.00 | | Ressources Informatiques | 25.78 | | TechNote | 10.00 | +--------------------------+----------------------------------+ 4 rows in set (0.00 sec) mysql> SELECT nom,prix_ht+ROUND(prix_ht*5.5/100,2) -> FROM collection -> O R D E R B Y p r i x _ h t + R O U N D ( p r i x _ h t * 5 . 5 / 1 0 0 , 2 ) ;

- 10 -

ENI Editions - All rigths reserved

+--------------------------+----------------------------------+ | nom | prix_ht+ROUND(prix_ht*5.5/100,2) | +--------------------------+----------------------------------+ | TechNote | 10.00 | | Ressources Informatiques | 25.78 | | Les TP Informatiques | 27.00 | | Coffret Technique | 49.00 | +--------------------------+----------------------------------+ 4 rows in set (0.00 sec) mysql> SELECT nom,prix_ht+ROUND(prix_ht*5.5/100,2) p r i x _ t t c -> FROM collection -> O R D E R B Y p r i x _ t t c D E S C ; +--------------------------+----------+ | nom | prix_ttc | +--------------------------+----------+ | Coffret Technique | 49.00 | | Les TP Informatiques | 27.00 | | Ressources Informatiques | 25.78 | | TechNote | 10.00 | +--------------------------+----------+ 4 rows in set (0.00 sec) mysql> SELECT id_parent,titre -> FROM rubrique -> O R D E R B Y i d _ p a r e n t , t i t r e ; +-----------+----------------------+ | id_parent | titre | +-----------+----------------------+ | NULL | Base de donnes | | NULL | Dveloppement | | NULL | Internet | | NULL | Messagerie et travai | | NULL | Open Source | | 1 | MySQL | | 1 | Oracle | | 2 | Langages | | 2 | Mthode | | 3 | Conception Web | | 3 | HTML - XML | | 3 | Scurit | | 4 | Base de donnes | | 4 | Langages | | 4 | Systme | +-----------+----------------------+ 15 rows in set (0.00 sec)

L esvaleursNULLapparaissentenpremierdansuntricroissant.

d.Limiterlenombredelignes :clauseLIMIT
UneclauseLIMITpeuttreajoutelarequteSELECTpourlimiterlenombredelignesretournes. Syntaxe SELECT [DISTINCT] expression[,...] | * FROM nom_table [WHERE conditions] [ORDER BY expression [ASC | DESC][,...]]LIMIT [offset,] nombre_lignes nombre_lignesestuneconstanteentirequispcifielenombredelignesretourner. offset, sil est prsent, est aussi une constante entire qui spcifie le numro de la premire ligne retourner (0 pourlapremireligne).LIMIT nestquivalentLIMIT 0,n. SilarequtecomporteuneclauseWHEREet/ouuneclauseORDER BY,laclauseLIMITdoitfigureraprs.

ENI Editions - All rigths reserved

- 11 -

Laclause LIMITestvalueaprslesclauses WHEREet ORDER BY.Combineuneclause ORDER BY,laclause LIMIT esttrspratiquepourlesinterrogationsdetype"palmars"("TopN"). Exemple mysql> -- afficher les trois plus "gros" livres (en nombre de pages) mysql> SELECT titre,nombre_pages -> FROM livre -> ORDER BY nombre_pages DESC -> LIMIT 3; +------------------+--------------+ | titre | nombre_pages | +------------------+--------------+ | MySQL 5 et PHP 5 | 972 | | PHP 5.2 | 518 | | Oracle 10g | 489 | +------------------+--------------+ 3 rows in set (0.00 sec) -- afficher les deux suivants mysql> SELECT titre,nombre_pages -> FROM livre -> ORDER BY nombre_pages DESC -> LIMIT 3,2; +-------------------+--------------+ | titre | nombre_pages | +-------------------+--------------+ | BusinessObjects 6 | 470 | | MySQL 5 | 468 | +-------------------+--------------+ 2 rows in set (0.00 sec)

e.Liredansplusieurstables :jointure
Dansuneinterrogation,ilestsouventncessairedextrairedesinformationsdansplusieurstables. Pour cela, il faut lister les tables souhaites dans la clause FROM et effectuer une jointure entre les tables. Une jointureconsisteindiquerauserveurMySQLcommentrelierlestablesentreelles. Lister les tables dans la clause FROM et oublier dcrire la jointure nest pas une erreur de syntaxe. Le serveur retourne un rsultat en effectuant un produit cartsien entre les tables : chaque ligne de la premire table est combineavecchaquelignedeladeuximetable.Untelrsultatestrarementsouhait ! MySQLsupporteplusieurssyntaxespourcrireunejointure.Nousprsenteronsicilesplusutilises. Jointureinterne Pourcrireunejointureinterne("simple")entredeuxtables,vouspouvezutiliserunedestroissyntaxessuivantes : FROM nom_table1,nom_table2 WHERE nom_table1.nom_colonne1 = nom_table2.nom_colonne2 FROM nom_table1 [INNER] JOIN nom_table2 ON nom_table1.nom_colonne1 = nom_table2.nom_colonne2 FROM nom_table1 [INNER] JOIN nom_table2 USING (nom_colonne[,...]) Unejointuresematrialiseleplussouventparuneconditiondgalitentreunecolonnedelapremiretableetune colonnedeladeuximetable :cestune"quijointure",jointurelaplussouventutilise(maisilexistedautretypes dejointures,nonbasessurunegalit). Danslapremiresyntaxe,laconditiondejointureestcritedanslaclauseWHEREetlestablessontsparesparune virguledanslaclauseFROM.Cettesyntaxe,bienquellesoitsupportepardenombreuxSGBDR,nestpaslasyntaxe delanormeANSI. Les deux dernires syntaxes sont conformes la norme ANSI. Les tables sont jointes dans la clause FROM par lintermdiaire du mot cl JOIN (INNER est optionnel, cest la valeur par dfaut) et la condition de jointure est, elle aussi,spcifiedanslaclauseFROMsoitavecuneclauseONsoitavecuneclause USING.AveclaclauseON,lacondition dejointureestcriteexplicitement(commedanslaclause WHEREdelapremiresyntaxe).Aveclaclause USING,une quijointureestimplicitementralisesurlescolonnesmentionnesquidoiventdoncporterlemmenomdansles
- 12 ENI Editions - All rigths reserved

deuxtables USING (nom_colonne)estquivalentON nom_table1.nom_colonne = nom_table2.nom_colonne. orsque vous crivez des interrogations portant sur plusieurs tables, il est vivement conseill de dfinir des L aliasdetablesetdelesutiliserpourprfixerlenomdescolonnes. Exempleavecdeuxtables mysql> SELECT col.nom,liv.titre -> FROM collection col,livre liv -> WHERE col.id = liv.id_collection -> AND liv.annee_parution=2006; +--------------------------+------------------+ | nom | titre | +--------------------------+------------------+ | Ressources Informatiques | MySQL 5 | | TechNote | PHP 5 | | Coffret Technique | MySQL 5 et PHP 5 | +--------------------------+------------------+ 3 rows in set (0.00 sec) mysql> SELECT col.nom,liv.titre -> FROM collection col JOIN livre liv -> ON (col.id = liv.id_collection) -> WHERE liv.annee_parution=2006; +--------------------------+------------------+ | nom | titre | +--------------------------+------------------+ | Ressources Informatiques | MySQL 5 | | TechNote | PHP 5 | | Coffret Technique | MySQL 5 et PHP 5 | +--------------------------+------------------+ 3 rows in set (0.00 sec) Exempleavectroistables mysql> SELECT -> liv.id, -> liv.titre, -> aut.nom -> FROM -> livre liv, -> auteur_livre aul, -> auteur aut -> WHERE -> liv.id = aul.id_livre -> AND aul.id_auteur = aut.id -> AND liv.annee_parution=2006 -> ORDER BY -> liv.titre; +----+------------------+---------+ | id | titre | nom | +----+------------------+---------+ | 7 | MySQL 5 | THIBAUD | | 9 | MySQL 5 et PHP 5 | HEURTEL | | 9 | MySQL 5 et PHP 5 | THIBAUD | | 2 | PHP 5 | HEURTEL | +----+------------------+---------+ 4 rows in set (0.00 sec) mysql> SELECT -> liv.id, -> liv.titre, -> aut.nom -> FROM -> livre liv -> JOIN -> auteur_livre aul

ENI Editions - All rigths reserved

- 13 -

-> ON (liv.id = aul.id_livre) -> JOIN -> auteur aut -> ON (aul.id_auteur = aut.id) -> WHERE -> liv.annee_parution=2006 -> ORDER BY -> liv.titre; +----+------------------+---------+ | id | titre | nom | +----+------------------+---------+ | 7 | MySQL 5 | THIBAUD | | 9 | MySQL 5 et PHP 5 | HEURTEL | | 9 | MySQL 5 et PHP 5 | THIBAUD | | 2 | PHP 5 | HEURTEL | +----+------------------+---------+ 4 rows in set (0.00 sec)

Jointureexterne Dansune jointureinterne,seulesleslignesencorrespondancedanslesdeuxtablessontretournes :siuneligne de la premire table na pas de correspondance dans la deuxime table, elle nest pas retourne (et rciproquement). Exemple mysql> SELECT titre,id_promotion FROM livre -> WHERE annee_parution = 2006; +------------------+--------------+ | titre | id_promotion | +------------------+--------------+ | PHP 5 | 1 | | MySQL 5 | NULL | | MySQL 5 et PHP 5 | 2 | +------------------+--------------+ 3 rows in set (0.00 sec) mysql> SELECT liv.titre,pro.intitule -> FROM livre liv JOIN promotion pro -> ON (liv.id_promotion = pro.id) -> WHERE liv.annee_parution = 2006; +------------------+---------------------------------------+ | titre | intitule | +------------------+---------------------------------------+ | PHP 5 | -5% sur cet ouvrage | | MySQL 5 et PHP 5 | Frais de port offerts sur cet ouvrage | +------------------+---------------------------------------+ 2 rows in set (0.00 sec) Surcetexemple,lelivre"MySQL5"nestpasretournparladeuximerequtecarilnapasdepromotion. Pourretournertoutesleslignesdunedesdeuxtablesmmesiellesnontpasdecorrespondance,ilfautcrireune jointureexterne.Avecunejointureexterne,leserveurMySQLcreuneligneavecdesvaleursNULLpourlatablequi napasdeligneencorrespondanceaveclautretable cetteligne"vide"estutilisepourtablirla"correspondance" aveclautretable. orsque vous crivez une jointure, posezvous toujours la question de savoir sil peut ne pas y avoir de L correspondance entre les deux tables, et si cest le cas, ce que vous souhaitez faire : conserver ou non les lignesenquestion. Pourcrireunejointureexterneentredeuxtables,vouspouvezutiliserunedesquatresyntaxessuivantes : FROM nom_table1 LEFT [OUTER] JOIN nom_table2 ON nom_table1.nom_colonne1 = nom_table2.nom_colonne2 FROM nom_table1 LEFT [OUTER] JOIN nom_table2 USING (nom_colonne[,...])

- 14 -

ENI Editions - All rigths reserved

FROM nom_table1 RIGHT [OUTER] JOIN nom_table2 ON nom_table1.nom_colonne1 = nom_table2.nom_colonne2 FROM nom_table1 RIGHT [OUTER] JOIN nom_table2 USING (nom_colonne[,...]) LemotclOUTERestoptionnelcarlesensdelajointureexternedoittreprcisaveclemotclLEFTou RIGHT.Dans une jointure "gauche" nom_table1 LEFT JOIN nom_table2, les lignes de la table de "gauche" nom_table1 sont retournes mme si elles nont pas de correspondance dans lautre table. Dans une jointure "droite" nom_table1 RIGHT JOIN nom_table2, les lignes de la table de "droite" nom_table2 sont retournes mme si elles nont pas de correspondancedanslautretable. Commepourlajointureinterne,laconditiondejointurepeuttrespcifielaideduneclauseONouUSING. Exemple mysql> SELECT liv.titre,pro.intitule -> FROM livre liv L E F T JOIN promotion pro -> ON (liv.id_promotion = pro.id) -> WHERE liv.annee_parution = 2006; +------------------+---------------------------------------+ | titre | intitule | +------------------+---------------------------------------+ | PHP 5 | -5% sur cet ouvrage | | MySQL 5 | NULL | | MySQL 5 et PHP 5 | Frais de port offerts sur cet ouvrage | +------------------+---------------------------------------+ 3 rows in set (0.00 sec) Maintenant,lelivre"MySQL5"estbienretourndanslersultat,bienquilnaitpasdepromotion. Si la requte comporte une condition supplmentaire sur la table externe (celle sur laquelle une ligne vide est gnre pour la mise en correspondance), il faut la mettre dans la clause ON de la jointure et non dans la clause WHERE,souspeinedobtenirunejointuresimplelaplacedelajointureexterne. Exemple mysql> SELECT liv.titre,pro.intitule -> FROM livre liv LEFT JOIN promotion pro -> ON (liv.id_promotion = pro.id) -> WHERE liv.annee_parution = 2006 -> AND pro.est_active = TRUE; +-------+---------------------+ | titre | intitule | +-------+---------------------+ | PHP 5 | -5% sur cet ouvrage | +-------+---------------------+ 1 row in set (0.00 sec) mysql> SELECT liv.titre,pro.intitule -> FROM livre liv LEFT JOIN promotion pro -> ON (liv.id_promotion = pro.id -> AND pro.est_active = TRUE) -> WHERE liv.annee_parution = 2006; +------------------+---------------------+ | titre | intitule | +------------------+---------------------+ | PHP 5 | -5% sur cet ouvrage | | MySQL 5 | NULL | | MySQL 5 et PHP 5 | NULL | +------------------+---------------------+ 3 rows in set (0.00 sec)

Autojointure Il est possible de joindre une table avec ellemme (notion dauto jointure). Pour cela, il faut faire figurer la table deuxfoisdanslaclause FROM,avecdesaliasdetablediffrents,etcrirelajointureentrelesdeuxtablescommesil sagissaitdetablesdiffrentes.Cettetechniqueestparticulirementutilepourinterrogerunetablequiimplmente unestructurehirarchique.

ENI Editions - All rigths reserved

- 15 -

Exemple mysql> SELECT par.titre rubrique,enf.titre sous_rubrique -> FROM rubrique par,rubrique enf -> WHERE enf.id_parent = par.id; +-----------------+-----------------+ | rubrique | sous_rubrique | +-----------------+-----------------+ | Base de donnes | MySQL | | Base de donnes | Oracle | | Dveloppement | Langages | | Dveloppement | Mthode | | Internet | HTML - XML | | Internet | Conception Web | | Internet | Scurit | | Open Source | Systme | | Open Source | Langages | | Open Source | Base de donnes | +-----------------+-----------------+ 10 rows in set (0.00 sec)

5.Ajouterdeslignesdansunetable
LordreSQLINSERTpermetdajouterdeslignesdansunetable. Syntaxe1 INSERT [IGNORE] [INTO] nom_table [(nom_colonne,...)] VALUES ({expression | DEFAULT},...),(...),... [ ON DUPLICATE KEY UPDATE nom_colonne=expression, ... ] Syntaxe2 INSERT [IGNORE] [INTO] nom_table SET nom_colonne ={ expression | DEFAULT}, ... [ ON DUPLICATE KEY UPDATE nom_colonne= expression, ... ] nom_tableestlenomdelatabledanslaquellelesdonnessontajoutes. Lescolonnesconcernesparlinsertionsontspcifiessoitparunelistedenomsdecolonnesdernirelenomdela table(premiresyntaxe),soitparlaclauseSET(deuximesyntaxe).Danslapremiresyntaxe,silalistedescolonnes est absente, toutes les colonnes de la table sont concernes par dfaut. Il faut noter quil ny a pas dobligation insrerunevaleurdanstouteslescolonnesdelatable. LesvaleursdescolonnessontspcifiessoitparlaclauseVALUES(premiresyntaxe),soitparlaclause SET(deuxime syntaxe).Danslapremiresyntaxe,laclause VALUESdoitcomporteruneexpressionpourchaquecolonnementionne danslalistedescolonnes(danslordre) silalistedescolonnesestabsente,laclause VALUESdoitfournirunevaleur pourchaquecolonnedelatable,danslordredescolonnesdelatable.Dansladeuximesyntaxe,lavaleurdechaque colonneestdonneparlexpressionsituedroitedusigne=.Danslapremiresyntaxe,plusieurslistesdevaleurs peuventtrespcifies(sparespardesvirgules)afindinsrerplusieurslignesenuneseuleopration. anslapremiresyntaxe,pourducodeenproduction,ilestconseilldetoujoursspcifierlalistedescolonnes, D afinquelarequtepuissecontinuerfonctionnermmesidescolonnessontajoutesdanslatable. Exemples mysql> DESC collection; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | nom | varchar(25) | NO | UNI | | | | prix_ht | decimal(5,2) | YES | | 20.00 | | | frais_ht | decimal(5,2) | YES | | NULL | |

- 16 -

ENI Editions - All rigths reserved

+----------+--------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) mysql> INSERT INTO collection -> VALUES(5,Solutions Informatiques,36.97,1.25); Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO collection(nom) -> VALUES(ExpertIT); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM collection WHERE id >= 5; +----+-------------------------+---------+----------+ | id | nom | prix_ht | frais_ht | +----+-------------------------+---------+----------+ | 5 | Solutions Informatiques | 36.97 | 1.25 | | 6 | ExpertIT | 20.00 | NULL | +----+-------------------------+---------+----------+ 2 rows in set (0.00 sec) Comme le montre cet exemple, si une colonne nestpasmentionnedanslinsertion, mais quelle a t dfinie avec lattribut AUTO_INCREMENT (cf. chapitre Construire une base de donnes dans MySQL Grer les tables), un entier unique lui est affect. Si ce nest pas le cas la valeur par dfaut de la colonne lui est affecte le mot cl DEFAULT permetdaffecterexplicitementlavaleurpardfautdelacolonne. Comme nous le verrons dans le chapitre Construire une base de donnes dans MySQL, la valeur par dfaut dune colonnepeuttredfinielorsdelacrationdelatable.Lorsdelinsertion,siaucunevaleurpardfautnestdfinie explicitementpourunecolonneetquelacolonneautoriselesvaleurs NULL,lavaleur NULLestaffectecommevaleur pardfaut.Parcontre,silacolonneestobligatoire,lefonctionnementdpenddumodeSQLactif :
q

SilemodeSQLstrictnestpasactif(caspardfaut),MySQLutilisesaproprevaleurpardfautlieautypede donnes :0pourunnombre,chanevidepourunechane,date"zro"pourunedate. SilemodeSQLstrictestactif,uneerreurseproduit.

Exemples mysql> SELECT @@sql_mode; +------------+ | @@sql_mode | +------------+ | | +------------+ 1 row in set (0.00 sec) mysql> INSERT INTO collection() -- un peu bizarre comme INSERT -> VALUES(); -- mais cest pour tester ! Q u e r y O K , 1 row affected, 1 w a r n i n g (0.00 sec) mysql> SHOW WARNINGS; +---------+------+------------------------------------------+ | Level | Code | Message | +---------+------+------------------------------------------+ | Warning | 1364 | Field nom doesnt have a default value | +---------+------+------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT nom,prix_ht FROM collection -> WHERE id = last_insert_id(); +-----+---------+ | nom | prix_ht | +-----+---------+ | | 20.00 | +-----+---------+ 1 row in set (0.00 sec) mysql> SET @@sql_mode= S T R I C T _ A L L _ T A B L E S ; Query OK, 0 rows affected (0.00 sec)

ENI Editions - All rigths reserved

- 17 -

mysql> INSERT INTO collection() -> VALUES(); ERROR 1364 (HY000): Field nom doesnt have a default value mysql> SET @@sql_mode=; Query OK, 0 rows affected (0.00 sec)

a fonction last_insert_id utilise dans cet exemple retourne la valeur automatiquement gnre par une L colonne de type AUTO_INCREMENT lors du dernier INSERT (cf. chapitre Utiliser les fonctions MySQL Fonctions systme). LecomportementdeMySQLvisvisdelinsertiondunevaleurinvalide(dateinexistanteparexemple)outropgrande (OlivierdansunVARCHAR(4))dpendaussidumodeSQL :
q q

unechanetropgrandeesttronque unedateinvalideestremplaceparunedate"zro" unnombretropgrandestremplacparlavaleurmaximumautoriseparletype.

SilemodeSQLstrictestactif,uneerreurestgnre.

Exemples mysql> SELECT @@sql_mode; +------------+ | @@sql_mode | +------------+ | | +------------+ 1 row in set (0.00 sec) mysql> INSERT INTO collection(nom,prix_ht) -> VALUES( C o f f r e t T e c h n i q u e C e r t i f i c a t i o n , 1 2 3 4 ); Q u e r y O K , 1 row affected, 2 w a r n i n g s (0.00 sec) mysql> SHOW WARNINGS; +---------+------+-----------------------------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------------------------+ | Warning | 1265 | Data truncated for column nom at row 1 | | Warning | 1264 | Out of range value adjusted for column prix_ht at row 1 | +---------+------+-----------------------------------------------------------+ 2 rows in set (0.00 sec) mysql> SELECT nom,prix_ht FROM collection -> WHERE id = last_insert_id(); +---------------------------+---------+ | nom | prix_ht | +---------------------------+---------+ | Coffret Technique Certifi | 999.99 | +---------------------------+---------+ 1 row in set (0.00 sec) mysql> SET @@sql_mode=<$I[]STRICT_ALL_TABLES> S T R I C T _ A L L _ T A B L E S ; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO collection(nom,prix_ht) -> VALUES( C o f f r e t T e c h n i q u e C e r t i f i c a t i o n , 1 2 3 4 ); ERROR 1406 (22001): Data too long for column nom at row 1 mysql> SET @@sql_mode=; Query OK, 0 rows affected (0.00 sec)

- 18 -

ENI Editions - All rigths reserved

ClauseIGNORE Laclause IGNOREpermetdignorerleserreurslieslinsertiondunelignequiprovoqueraitundoublondansunecl primaireouunique silecasseproduit,lalignenestpasinsreetaucunmessagederreurnestaffich. Exemples mysql> INSERT INTO collection(id,nom,prix_ht) -> VALUES(1,Epsilon,51.18); ERROR 1062 (23000): Duplicate entry 1 for key 1 mysql> INSERT I G N O R E INTO collection(id,nom,prix_ht) -> VALUES( 1 ,Epsilon,51.18); Q u e r y O K , 0 r o w s a f f e c t e d (0.01 sec) mysql> SELECT nom FROM collection WHERE id = 1; +--------------------------+ | nom | +--------------------------+ | Ressources Informatiques | +--------------------------+ 1 row in set (0.00 sec)

ClauseONDUPLICATEKEYUPDATE Laclause ON DUPLICATE KEY UPDATEpermetdetransformeren UPDATElinsertiondunelignequiprovoqueundoublon suruneclprimaireouunique. Dans la clause UPDATE, lexpression VALUES(nom_colonne) permet de faire rfrence la valeur de la colonne dans la clauseINSERTdorigine. Exemples mysql> INSERT INTO auteur(nom,prenom,mail) -> VALUES(HEURTEL,Olivier,contact@olivier-heurtel.fr); ERROR 1062 (23000): Duplicate entry HEURTEL-Olivier for key 2 mysql> INSERT INTO auteur(nom,prenom,mail) -> VALUES(HEURTEL,Olivier,contact@olivier-heurtel.fr) -> O N D U P L I C A T E K E Y U P D A T E m a i l = V A L U E S ( m a i l ) ; Query OK, 2 rows affected (0.00 sec) mysql> SELECT mail FROM auteur WHERE nom = HEURTEL; +----------------------------+ | mail | +----------------------------+ | contact@olivier-heurtel.fr | +----------------------------+ 1 row in set (0.00 sec)

ttention ! Si la ligne insre provoque un doublon sur deux lignes (par exemple sur la cl primaire pour la A premireligneetsurunecluniquepourladeuximeligne),seuleuneligneseramisejour.Ilestconseill dvitercegenredesituation.

Insertiondeplusieurslignes Dans la premire syntaxe de lordre INSERT, plusieurs listes de valeurs peuvent tre spcifies (spares par des virgules)afindinsrerplusieurslignesenuneseuleopration. Siuneerreurseproduitlorsdun INSERTmultilignes,lordreestinterrompuetleslignesdjinsressontconserves oupasselonletypedetable :
q

pour une table non transactionnelle (cest le cas par dfaut en gnral), les lignes dj insres sont conserves pourunetabletransactionnelle(cf.chapitreTechniquesavancesavecMySQLGrerlestransactionsetles

ENI Editions - All rigths reserved

- 19 -

accsconcurrents),leslignesdjinsressontannules. Exempleavecunetablenontransactionnelle mysql> INSERT INTO -> auteur(nom,prenom) -> VALUES -> (NOIRAULT,Claire), -> (GABILLAUD,Jrme), -> (HEURTEL,Olivier), -- existe dj !! -> (HUGO,Victor); ERROR 1062 (23000): Duplicate entry HEURTEL-Olivier for key 2 mysql> SELECT id,nom,prenom FROM auteur WHERE id > 3; +----+-----------+--------+ | id | nom | prenom | +----+-----------+--------+ | 4 | NOIRAULT | Claire | | 5 | GABILLAUD | Jrme | +----+-----------+--------+ 2 rows in set (0.00 sec) Lauteur"VictorHugo"napastinsrdanslatable. anslechapitreTechniquesavancesavecMySQLUtiliserdessousrequtes,nousverronscommentajouter D deslignesdansunetablelaideduneautrerequte(sousrequte).

6.Modifierdeslignesdansunetable
LordreSQLUPDATEpermetdemodifierdeslignesdansunetable. Syntaxe UPDATE [IGNORE] nom_table SET nom_colonne={expression | DEFAULT} [,...] [WHERE condition] [ORDER BY tri] [LIMIT nombre_lignes] nom_tableestlenomdelatabledanslaquellelesdonnessontmodifies. La clause SET indique les colonnes modifier avec leur nouvelle valeur. Il faut noter quil ny a pas dobligation modifiertouteslescolonnesdelatable. Lemotcl DEFAULTpermetdaffecterexplicitementlavaleurpardfautdelacolonne.Commedanslecasdelinsertion, silavaleurDEFAULTestmentionne,maisquaucunevaleurpardfautnestdfinieexplicitementsurlacolonneetque la colonne est obligatoire, MySQL utilise sa propre valeur par dfaut lie au type de donnes (0 pour un nombre, chanevidepourunechane,date"zro"pourunedate). La clause WHERE est optionnelle. Si elle est omise, toutes les lignes de la table sont modifies. Si elle est spcifie, seulesleslignesvrifiantlaconditionsontmisesjour.Lasyntaxepourcrireuneconditionestlammequepourla clauseWHEREdelordreSELECT. Exemples mysql> UPDATE auteur SET mail = olivier.heurtel@gmail.com -> WHERE nom = HEURTEL AND prenom = Olivier; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> UPDATE collection SET nom = Epsilon,prix_ht=51.18 -> WHERE nom = ; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> UPDATE collection

- 20 -

ENI Editions - All rigths reserved

-> SET prix_ht = ROUND(prix_ht*1.015,2) -- augmentation de 1,5% -> WHERE nom = Epsilon; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> UPDATE livre SET niveau=Confirm WHERE id_collection = 2; Query OK, 3 rows affected (0.00 sec) Rows matched: 3 Changed: 3 Warnings: 0 Silavaleurdunecolonneestinchange,MySQLnefaitpaslamisejour ilpeutdoncyavoirunediffrenceentrele nombredelignesslectionnesetlenombredelignesmodifies. Exemple mysql> UPDATE livre SET id_promotion=1 WHERE id_collection=1; Query OK, 3 r o w s a f f e c t e d (0.00 sec) Rows matched: 5 C h a n g e d : 3 Warnings: 0 Surcetexemple,deuxlivresdelacollectionn1ontdjlecodepromotionn1 enconsquence,larequtenemet rellementjourquetroislivresparmilescinqdelacollection. Lecomportementvisvisdesvaleursinvalidesoutropgrandes,ouvisvisdeserreursdansun UPDATEmultilignes estlemmequepourlordreINSERT. Exemple mysql> UPDATE collection SET prix_ht = 5 2 0 0 WHERE nom = Epsilon; Query OK, 1 row affected, 1 warning (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 1 mysql> SHOW WARNINGS; +---------+------+-----------------------------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------------------------+ | Warning | 1264 | Out of range value adjusted for column prix_ht at row 1 | +---------+------+-----------------------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT prix_ht FROM collection WHERE nom = Epsilon; +---------+ | prix_ht | +---------+ | 999.99 | +---------+ 1 row in set (0.00 sec)

ClausesORDERBYetLIMIT Siuneclause ORDER BYestspcifie,leslignessontmodifiesdanslordredfiniparlaclause.Danslapratique,cette clauseneprsenteunintrtquelorsquelleestutiliseaveclaclauseLIMIT. La clause LIMIT permet de limiter le nombre de lignes slectionnes (avant la version 4.0.13, cette clause limitait le nombredelignesmodifies). Exemple:augmenterleprixdelacollectionlamoinschre mysql> SELECT nom,prix_ht FROM collection ORDER BY prix_ht LIMIT 1; +----------+---------+ | nom | prix_ht | +----------+---------+ | TechNote | 9.48 | +----------+---------+ 1 row in set (0.00 sec) mysql> UPDATE collection SET prix_ht = prix_ht + 0.50 -> ORDER BY prix_ht LIMIT 1; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT nom,prix_ht FROM collection ORDER BY prix_ht LIMIT 1;
ENI Editions - All rigths reserved - 21 -

+----------+---------+ | nom | prix_ht | +----------+---------+ | TechNote | 9.98 | +----------+---------+ 1 row in set (0.01 sec)

ClauseIGNORE LaclauseIGNOREpermetdignorerleserreurslieslamodificationdelignesquiprovoqueraitundoublondansunecl primaire ou unique si le cas se produit, la ligne nest pas modifie, aucun message derreur nest affich et la modificationsepoursuitsurlesautreslignes. Exemple mysql> UPDATE collection SET nom = TechNote WHERE id = 1; ERROR 1062 (23000): Duplicate entry TechNote for key 2 mysql> UPDATE I G N O R E collection SET nom = TechNote WHERE id = 1; Q u e r y O K , 0 r o w s a f f e c t e d (0.00 sec) Rows matched: 1 C h a n g e d : 0 Warnings: 0 mysql> SELECT nom FROM collection WHERE id = 1; +--------------------------+ | nom | +--------------------------+ | Ressources Informatiques | +--------------------------+ 1 row in set (0.00 sec)

Misejourdansplusieurstablesjointes MySQLsupporteaussiunesyntaxedemisejourdansplusieurstablesjointes. Exemple mysql> SELECT col.nom,col.prix_ht,liv.isbn,liv.id_promotion -> FROM livre liv JOIN collection col -> ON (liv.id_collection = col.id) -> WHERE -> col.nom = TechNote; +----------+---------+---------------+--------------+ | nom | prix_ht | isbn | id_promotion | +----------+---------+---------------+--------------+ | TechNote | 9.98 | 2-7460-3104-3 | 1 | | TechNote | 9.98 | 2-7460-2834-4 | NULL | | TechNote | 9.98 | 2-7460-2833-6 | NULL | +----------+---------+---------------+--------------+ 2 rows in set (0.00 sec) mysql> UPDATE -> livre liv JOIN collection col -> ON (liv.id_collection = col.id) -> SET -> -- augmenter le prix de la collection -> col.prix_ht = col.prix_ht + 0.5, -> -- mettre les livres (de la collection) en promotion -> liv.id_promotion = 2 -> WHERE -> col.nom = TechNote -> AND liv.id_promotion IS NULL; -- pas dj en promotion Query OK, 3 r o w s a f f e c t e d (0.01 sec) Rows matched: 3 Changed: 3 Warnings: 0 mysql> SELECT col.nom,col.prix_ht,liv.isbn,liv.id_promotion -> FROM livre liv JOIN collection col -> ON (liv.id_collection = col.id) -> WHERE

- 22 -

ENI Editions - All rigths reserved

-> col.nom = TechNote; +----------+---------+---------------+--------------+ | nom | prix_ht | isbn | id_promotion | +----------+---------+---------------+--------------+ | TechNote | 10.48 | 2-7460-3104-3 | 1 | | TechNote | 10.48 | 2-7460-2834-4 | 2 | | TechNote | 10.48 | 2-7460-2833-6 | 2 | +----------+---------+---------------+--------------+ 3 rows in set (0.00 sec) Surcetexemple,lestables collectionet livresontmisesjouravecunseulordre UPDATE:leprixdelacollection "TechNote"estaugmentetleslivresdecettecollectionquintaientpasdjenpromotionsontmisenpromotion.Il yabientroislignesmisesjour:unedanslatablecollectionetdeuxdanslatablelivre. Les diffrentes syntaxes de jointure (interne et externe) prsentes prcdemment sont supportes. Pour plus dinformationssurcettesyntaxe,consultezladocumentation.

7.Supprimerdeslignesdansunetable
LordreSQLDELETEpermetdesupprimerdeslignesdansunetable. Syntaxe DELETE [WHERE [ORDER [LIMIT [IGNORE] FROM nom_table condition] BY tri] nombre_lignes]

nom_tableestlenomdelatabledanslaquellelesdonnessontsupprimes. Laclause WHEREestoptionnelle.Sielleestomise,toutesleslignesdelatablesontsupprimes.Sielleestspcifie, seulesleslignesvrifiantlaconditionsontsupprimes.Lasyntaxepourcrireuneconditionestlammequepourla clauseWHEREdelordreSELECT. Exemples mysql> DELETE FROM promotion WHERE id = 3; Query OK, 1 row affected (0.00 sec) mysql> DELETE FROM collection WHERE prix_ht = 999.99; Query OK, 2 rows affected (0.00 sec)

ClausesORDERBYetLIMIT SiuneclauseORDER BYestspcifie,leslignessontsupprimesdanslordredfiniparlaclause.Danslapratique,cette clauseneprsenteunintrtquelorsquelleestutiliseaveclaclauseLIMIT. LaclauseLIMITpermetdelimiterlenombredelignessupprimes. Exemple:supprimerla"dernire"ligne(plusgrandidentifiant) mysql> SELECT id,titre FROM rubrique ORDER BY id DESC LIMIT 1; +----+----------------------+ | id | titre | +----+----------------------+ | 15 | Messagerie et travai | +----+----------------------+ 1 row in set (0.00 sec) mysql> DELETE FROM rubrique ORDER BY id DESC LIMIT 1; Query OK, 1 row affected (0.00 sec) mysql> SELECT id,titre FROM rubrique ORDER BY id DESC LIMIT 1; +----+-----------------+ | id | titre | +----+-----------------+ | 14 | Base de donnes | +----+-----------------+

ENI Editions - All rigths reserved

- 23 -

1 row in set (0.00 sec)

ClauseIGNORE LaclauseIGNOREpermetdignorerleserreurslieslasuppressiondelignesquiprovoqueraientuneerreur(violation decltrangrecf.chapitreConstruireunebasededonnesdansMySQLUtiliserlesclsetlesindex) silecasse produit,lalignenestpassupprime,aucunmessagederreurnestaffichetlasuppressionsepoursuitsurlesautres lignes. Suppressiondansplusieurstablesjointes MySQLsupporteaussiunesyntaxedesuppressiondansplusieurstablesjointes. Exemple mysql> SELECT id,isbn FROM livre WHERE id = 1; +----+---------------+ | id | isbn | +----+---------------+ | 1 | 2-7460-1451-3 | +----+---------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM rubrique_livre WHERE id_livre = 1; +-------------+----------+ | id_rubrique | id_livre | +-------------+----------+ | 7 | 1 | | 10 | 1 | | 13 | 1 | +-------------+----------+ 3 rows in set (0.01 sec) mysql> SELECT * FROM auteur_livre WHERE id_livre = 1; +-----------+----------+ | id_auteur | id_livre | +-----------+----------+ | 1 | 1 | +-----------+----------+ 1 row in set (0.00 sec) mysql> -> -> -> -> -> -> -> Query DELETE FROM liv,rul,aul -- alias dfinis dans la clause USING USING livre liv,rubrique_livre rul,auteur_livre aul WHERE liv.id = rul.id_livre AND liv.id = aul.id_livre AND liv.isbn = 2-7460-1451-3; OK, 5 rows affected (0.00 sec)

mysql> SELECT id,isbn FROM livre WHERE id = 1; Empty set (0.01 sec) mysql> SELECT * FROM rubrique_livre WHERE id_livre = 1; Empty set (0.01 sec) mysql> SELECT * FROM auteur_livre WHERE id_livre = 1; Empty set (0.00 sec) Sur cet exemple, lordre DELETE supprime une ligne dans la table livre, ainsi que les lignes jointes dans les tables rubrique_livreetauteur_livre(ceslignesnontpluslieudtre). Laclause FROMspcifielestablesdanslesquellesdeslignesdoiventtresupprimes.Laclause USINGspcifietoutes lestablesutilisesdanslajointureilpeutyavoirdanslaclause USINGdestablesnonprsentesdanslaclauseFROM (tablesutilisesenjointuremaisdanslesquellesilnyapasdelignessupprimer). SiunaliasdetableestdfinidanslaclauseUSINGalorscetaliasdoittreutilisdanslaclauseFROM. Les diffrentes syntaxes de jointure (interne et externe) prsentes prcdemment sont supportes. Une autre
- 24 ENI Editions - All rigths reserved

syntaxe de suppression multitable peut tre utilise. Pour plus dinformations sur les diffrentes syntaxes de suppressionmultitable,consultezladocumentation.

8.Exporteretimporterdesdonnes
a.Exporterdesdonnes
LordreSQL SELECTpeutconteniruneclause INTO OUTFILEquipermetdestockerlersultatdelarequtedansun fichier. Syntaxe INTO OUTFILE nom_fichier [FIELDS [TERMINATED BY caractres] [[OPTIONALLY] ENCLOSED BY caractre] [ESCAPED BY caractre ]] [LINES [STARTING BY caractres] [TERMINATED BY caractres]] LaclauseINTO OUTFILE,sielleestprsente,doittredfiniejusteavantlaclauseFROM. Pourutilisercetteclause,lutilisateurdoitavoirleprivilgeFILE(cf.chapitre4BGrerlesutilisateursetlesdroits). Lefichierdanslequellesdonnessontcritesnedoitpasdjexister.Deplus,leserveurMySQLdoitavoirlesdroits ncessairespourcriredanslefichier.SuruneplateformeWindows,pourspcifierlechemindufichier,vousdevez auchoixchapperlantislash(c:\\temp\\data.txt)ouutiliserleslash(c:/temp/data.txt). LaclauseoptionnelleFIELDSpermetdedfinirlesoptionssuivantes : TERMINATED BY Dlimiteurdefindechamp(plusieurscaractresautoriss,tabulationpardfaut :\t). [OPTIONALLY] ENCLOSED BY Caractreutilispourentourerleschamps(unseulcaractreautoris,videpardfaut).SilemotclOPTIONALLYest absent,seulesleschampsdetypetextesontentours silestprsent,tousleschampssontentours. ESCAPED BY Caractreutilispourchapperlescaractressuivants(unseulcaractreautoris,antislashpardfaut :\\) :
q

lecaractreluimme lecaractredfiniparloptionENCLOSED BY lepremiercaractredesoptionsTERMINATED BY(FIELDSetLINES) lecaractredecodeASCII0.

SilaclauseFIELDSestomise,lesvaleurspardfautsontlessuivantes : FIELDS TERMINATED BY \t ENCLOSED BY ESCAPED BY \\ LaclauseoptionnelleLINESpermetdedfinirlesoptionssuivantes : STARTING BY Dlimiteurdedbutdeligne(plusieurscaractresautoriss,videpardfaut). TERMINATED BY Dlimiteurdefindeligne(plusieurscaractresautoriss,retourlalignepardfaut :\n). SilaclauseLINESestomise,lesvaleurspardfautsontlessuivantes :
ENI Editions - All rigths reserved - 25 -

LINES TERMINATED BY \n LamaniredontlesvaleursNULLsontcritesdanslefichierdpenddelavaleurdeloptionESCAPED BY :


q

Siloptionestvide,lemotNULLestcritdanslechamp. Siloptionnestpasvide,lalettreNprcdeducaractredchappementdfiniparloptionestcritedansle champ(\Nparexemple).

Exemple SELECT liv.isbn,liv.annee_parution,pro.intitule FROM livre liv LEFT JOIN promotion pro ON liv.id_promotion = pro.id INTO OUTFILE /tmp/liste-livre-1.txt; Rsultatdanslefichierliste-livre-1.txt 978-2-7460-3992-6 2-7460-3104-3 2006 2-7460-2778-X 2005 2-7460-2834-4 2005 2-7460-2833-6 2005 2-7460-2281-8 2004 2-7460-3004-7 2006 2-7460-2340-7 2004 2-7460-3377-1 2006 Exemple SELECT liv.isbn,liv.annee_parution,pro.intitule FROM livre liv LEFT JOIN promotion pro ON liv.id_promotion = pro.id INTO OUTFILE /tmp/liste-livre-2.txt FIELDS TERMINATED BY | OPTIONALLY ENCLOSED BY " LINES STARTING BY ->; Rsultatdanslefichierliste-livre-2.txt ->"978-2-7460-3992-6"|2007|"-5% sur cet ouvrage" ->"2-7460-3104-3"|2006|"-5% sur cet ouvrage" ->"2-7460-2778-X"|2005|"-5% sur cet ouvrage" ->"2-7460-2834-4"|2005|"Frais de port offerts sur cet ouvrage" ->"2-7460-2833-6"|2005|"Frais de port offerts sur cet ouvrage" ->"2-7460-2281-8"|2004|"-5% sur cet ouvrage" ->"2-7460-3004-7"|2006|"-5% sur cet ouvrage" ->"2-7460-2340-7"|2004|\N ->"2-7460-3377-1"|2006|"Frais de port offerts sur cet ouvrage" 2007 -5% sur cet ouvrage -5% sur cet ouvrage -5% sur cet ouvrage Frais de port offerts sur cet ouvrage Frais de port offerts sur cet ouvrage -5% sur cet ouvrage -5% sur cet ouvrage \N Frais de port offerts sur cet ouvrage

b.Importerdesdonnes
LordreSQLLOAD DATApermetdimporterdesdonnesdansunetable. Syntaxe LOAD DATA [LOCAL] INFILE nom_fichier [REPLACE | IGNORE] INTO TABLE nom_table [FIELDS [TERMINATED BY caractres] [[OPTIONALLY] ENCLOSED BY caractre] [ESCAPED BY caractre]] [LINES [STARTING BY caractres] [TERMINATED BY caractres]] [IGNORE nombre LINES]
- 26 ENI Editions - All rigths reserved

[(nom_colonne[,...])] [SET nom_colonne = expression[,...]] Pour utiliser cette commande, lutilisateur doit avoir le privilge FILE (cf. chapitre Construire une base de donnes dansMySQLGrerlesutilisateursetlesdroits). Silemotcl LOCALestspcifi,lefichierestlupartirdelamachinecliente sinon,lefichierestlusurleserveur. Selonlecas,leclientMySQLouleserveurMySQLdoitavoirledroitdelirelefichier.SuruneplateformeWindows, pourspcifierlechemindufichier,vousdevezauchoixchapperlantislash(c:\\temp\\data.txt)ouutiliserleslash (c:/temp/data.txt). Laclause IGNOREou REPLACEindiqueMySQLsildoitignorerleslignesquiontlammeclprimaireouuniqueque desenregistrementsdjprsentsdanslatable,ousildoitremplacerlesenregistrementsenquestion. LesclausesFIELDSetLINESsontidentiquescellesdelaclauseINTO OUTFILEprsenteprcdemment. LaclauseIGNOREpermetdignoreruncertainnombredelignesaudbutdufichier(lignedetitreparexemple). La liste de noms de colonnes permet de dfinir les colonnes dans lesquelles MySQL va charger le contenu des diffrentschamps.Silalisteestomise,leschampsserontchargsdanstouteslescolonnesdelatable,danslordre descolonnesdelatable.Silnyapassuffisammentdechampsdanslalignecharge,lescolonnesrestantesseront alimentesaveclavaleurpardfautdelacolonne. LaclauseSETpeuttreutilisepouraffecterdescolonnesdelatabledesvaleursquisontcalculeslaidedune expression. Cette expression peut rfrencer dautres colonnes de la table qui sont alimentes directement par le fichier.Danslalistedescolonnes,ilestpossibledespcifierunnomdevariableutilisateurlaplacedun nom de colonne,etdutilisercettevariabledanslaclause SET.Spcifierunnomdevariabledanslalistedescolonnesetne pasutilisercettevariableestutilepourignorerunchampdufichier. Exemple
q

Contenudufichiercatalogue.txt:

titre|code|prix_ht Oracle 10g - Administration|RI410GORAA|33.18 PHP 5 - Laccs aux donnes|TE5PHPAD|9.48


q

Chargementdanslatablecatalogue:

mysql> LOAD DATA INFILE /tmp/catalogue.txt INTO TABLE catalogue -> FIELDS TERMINATED BY | -- sparateur de champ -> LINES TERMINATED BY \n -> IGNORE 1 LINES -- ignorer la ligne de titre -> (titre,code,@prix_ht) -- charger le prix HT dans une variable -> -- calculer le prix TTC stock dans la table -> -- partir du prix HT -> SET prix_ttc = @prix_ht+ROUND(@prix_ht*5.5/100,2); Query OK, 2 rows affected (0.00 sec) Records: 2 Deleted: 0 Skipped: 0 Warnings: 0 mysql> SELECT * FROM catalogue; +------------+-----------------------------+----------+ | code | titre | prix_ttc | +------------+-----------------------------+----------+ | RI410GORAA | Oracle 10g - Administration | 35.00 | | TE5PHPAD | PHP 5 - Laccs aux donnes | 10.00 | +------------+-----------------------------+----------+ 2 rows in set (0.00 sec)

ENI Editions - All rigths reserved

- 27 -

Introduction
Commenouslavonsvuplusieursreprisesdepuisledbutdecetouvrage,nouspouvonsutiliserdesexpressionsdans les diffrentes clauses des ordres SQL. Une expression peut tre crite en utilisant des colonnes, des expressions littrales,desoprateursetdesfonctionsSQL. Danscechapitre,nousallonsprsenterlesfonctionsSQLlesplussouventutilises.Nousneprsenteronspastoutes les fonctions existantes (il y en a plus de 250 !). Nous ne prsenterons pas non plus systmatiquement toutes les optionspossiblesdunefonction.Pourensavoirplus,reportezvousladocumentationSQL. Lasyntaxegnraledunefonctionestlasuivante : nom_fonction([argument][,...]) argument peut tre toute expression dont la valeur est passe en paramtre la fonction argument peut luimme appelerdautresfonctions. Rappel :saufindicationcontraire,uneexpressionquicontientunNULLdonneunrsultatNULL.

ENI Editions - All rigths reserved

- 1-

Fonctionsdecontrle
Lesfonctionssuivantessontprsentesdanscettesection : IF Fonctiondutype sialorssinon basesurunecondition. IFNULL Fonctiondutype sialorssinon basesurlanullitduneexpression. NULLIF RetourneNULLsideuxexpressionssontgales. CASE Structuredecontrleconditiondutype sialorssinon (gnralisationdelafonctionIF). IF Syntaxe IF(condition,valeur_si_vrai,valeur_si_faux) Silexpression conditionestvraie(TRUE),lafonctionretournelexpression valeur_si_vrai sinon(condition = FALSE ouNULL),elleretournelexpressionvaleur_si_faux. Exemple mysql> SELECT -> titre, -> annee_parution, -> IF(2008-annee_parution > 2,Ancien,Rcent) age -> FROM livre -> WHERE id_collection = 1; +-------------------+----------------+--------+ | titre | annee_parution | age | +-------------------+----------------+--------+ | PHP 5.2 | 2007 | Rcent | | Oracle 10g | 2005 | Ancien | | BusinessObjects 6 | 2004 | Ancien | | MySQL 5 | 2006 | Rcent | +-------------------+----------------+--------+ 4 rows in set (0.00 sec)

IFNULL Syntaxe IFNULL(expression,valeur_si_null) SilexpressionexpressionestNULL,lafonctionretournelexpressionvaleur_si_null sinon(expressionnestpasNULL), elleretournelexpressionexpression. Lafonction IFNULLesttrsutiledanslesexpressionspourdonnerunevaleuruneexpressionNULLetviterdavoirun rsultatNULL. Exemple mysql> SELECT -> nom,prix_ht,frais_ht,prix_ht+ f r a i s _ h t total_ht -> FROM collection; +--------------------------+---------+----------+----------+ | nom | prix_ht | frais_ht | total_ht |

ENI Editions - All rigths reserved

- 1-

+--------------------------+---------+----------+----------+ | Ressources Informatiques | 24.44 | 1.50 | 25.94 | | TechNote | 10.48 | NULL | NULL | | Les TP Informatiques | 25.59 | 1.50 | 27.09 | | Coffret Technique | 46.45 | 2.00 | 48.45 | | Solutions Informatiques | 36.97 | 1.25 | 38.22 | | ExpertIT | 20.00 | NULL | NULL | +--------------------------+---------+----------+----------+ 6 rows in set (0.00 sec) mysql> SELECT -> nom,prix_ht,frais_ht,prix_ht+ I F N U L L ( f r a i s _ h t , 0 ) total_ht -> FROM collection; +--------------------------+---------+----------+----------+ | nom | prix_ht | frais_ht | total_ht | +--------------------------+---------+----------+----------+ | Ressources Informatiques | 24.44 | 1.50 | 25.94 | | TechNote | 10.48 | NULL | 10.48 | | Les TP Informatiques | 25.59 | 1.50 | 27.09 | | Coffret Technique | 46.45 | 2.00 | 48.45 | | Solutions Informatiques | 36.97 | 1.25 | 38.22 | | ExpertIT | 20.00 | NULL | 20.00 | +--------------------------+---------+----------+----------+ 6 rows in set (0.00 sec)

NULLIF Syntaxe NULLIF(expression1,expression2) Silesexpressionsexpression1etexpression2sontgales,lafonctionretourneNULL sinon(expressionnestpasNULL), elleretournelexpressionexpression1. CASE Syntaxe1 CASE valeur_a_tester WHEN valeur1 THEN rsultat1 [ WHEN valeur2 THEN rsultat2 ] [...] [ ELSE resultat ] END Syntaxe2 CASE WHEN condition1 THEN rsultat1 [ WHEN condition2 THEN rsultat2 ] [...] [ ELSE resultat ] END Avec la premire syntaxe, la fonction retourne la premire expression rsultatN pour laquelle les expressions valeur_a_tester et valeurN sont gales. Avec la deuxime syntaxe, la fonction retourne la premire expression rsultatN pour laquelle lexpression conditionN est vraie. Dans les deux syntaxes, sil ny a pas de correspondance, cestlexpressionresultatdelaclauseELSEquiestretourne( NULLsilnyapasdeELSE). Exemple mysql> SELECT -> titre, -> nombre_pages, -> CASE -> WHEN nombre_pages < 400 -> THEN 1.5 -> WHEN nombre_pages BETWEEN 400 AND 500

- 2-

ENI Editions - All rigths reserved

-> THEN 2 -> ELSE 2.5 -> END frais_envoi -> FROM livre -> WHERE id_collection <> 2 -> ORDER BY nombre_pages; +--------------------------------+--------------+-------------+ | titre | nombre_pages | frais_envoi | +--------------------------------+--------------+-------------+ | PHP et MySQL (versions 4 et 5) | 272 | 1.5 | | MySQL 5 | 468 | 2 | | BusinessObjects 6 | 470 | 2 | | Oracle 10g | 489 | 2 | | PHP 5.2 | 518 | 2.5 | | MySQL 5 et PHP 5 | 972 | 2.5 | +--------------------------------+--------------+-------------+ 6 rows in set (0.00 sec) mysql> SELECT -> titre, -> annee_parution, -> CASE annee_parution -> WHEN 2007 THEN Trs rcent -> WHEN 2006 THEN Rcent -> ELSE Ancien -> END age -> FROM livre -> WHERE id_collection = 1; +-------------------+----------------+-------------+ | titre | annee_parution | age | +-------------------+----------------+-------------+ | PHP 5.2 | 2007 | Trs rcent | | Oracle 10g | 2005 | Ancien | | BusinessObjects 6 | 2004 | Ancien | | MySQL 5 | 2006 | Rcent | +-------------------+----------------+-------------+ 4 rows in set (0.00 sec)

ENI Editions - All rigths reserved

- 3-

Fonctionsdecomparaison
Lesfonctionssuivantessontprsentesdanscettesection : LEAST Pluspetitevaleurdunelistedevaleurs. GREATEST Plusgrandevaleurdunelistedevaleurs. COALESCE PremireexpressionnonNULLdunelistedexpressions. LEASTGREATEST Syntaxe LEAST(expression1,expression2[,...]) GREATEST(expression1,expression2[,...]) Les fonctions LEAST et GREATEST retournent respectivement la plus petite et la plus grande valeur dune liste dexpressions. Exemple mysql> -- Calcul du montant dune remise mysql> -- de 5% plafonne 1.5 mysql> SELECT -> nom, -> prix_ht, -> LEAST(ROUND(prix_ht*5/100,2),1.5) remise -> FROM collection; +--------------------------+---------+--------+ | nom | prix_ht | remise | +--------------------------+---------+--------+ | Ressources Informatiques | 24.44 | 1.22 | | TechNote | 10.48 | 0.52 | | Les TP Informatiques | 25.59 | 1.28 | | Coffret Technique | 46.45 | 1.5 | | Solutions Informatiques | 36.97 | 1.5 | | ExpertIT | 20.00 | 1.00 | +--------------------------+---------+--------+ 6 rows in set (0.01 sec) mysql> -- Calcul du montant dune remise mysql> -- de 5% avec un minimum de 1 mysql> SELECT -> nom, -> prix_ht, -> GREATEST(ROUND(prix_ht*5/100,2),1) remise -> FROM collection; +--------------------------+---------+--------+ | nom | prix_ht | remise | +--------------------------+---------+--------+ | Ressources Informatiques | 24.44 | 1.22 | | TechNote | 10.48 | 1 | | Les TP Informatiques | 25.59 | 1.28 | | Coffret Technique | 46.45 | 2.32 | | Solutions Informatiques | 36.97 | 1.85 | | ExpertIT | 20.00 | 1.00 | +--------------------------+---------+--------+ 6 rows in set (0.00 sec)

ENI Editions - All rigths reserved

- 1-

COALESCE Syntaxe COALESCE(expression1,expression2[,...]) La fonction retourne la premire expression expressionN qui est non NULL la fonction retourne NULL si toutes les expressionssontNULL. Exemple mysql> -- Afficher un numro de tlphone parmi les numros de mysql> -- tlphones possibles des auteurs mysql> SELECT -> nom, -> tel_bureau, -> tel_portable, -> tel_domicile, -> COALESCE(tel_bureau,tel_portable,tel_domicile) telephone -> FROM -> auteur; +-----------+------------+--------------+--------------+------------+ | nom | tel_bureau | tel_portable | tel_domicile | telephone | +-----------+------------+--------------+--------------+------------+ | HEURTEL | NULL | 0687731346 | 0102030405 | 0687731346 | | THIBAUD | 0203040506 | NULL | NULL | 0203040506 | | GUERIN | NULL | NULL | 0304050607 | 0304050607 | | NOIRAULT | NULL | NULL | NULL | NULL | | GABILLAUD | NULL | NULL | NULL | NULL | +-----------+------------+--------------+--------------+------------+ 5 rows in set (0.01 sec)

- 2-

ENI Editions - All rigths reserved

Fonctionsnumriques
Lesfonctionssuivantessontprsentesdanscettesection : ABS Valeurabsoluedunnombre. CEILING,CEIL Pluspetitentierquinestpasinfrieurunnombre. DIV Rsultatdeladivisionentirededeuxnombres. FLOOR Plusgrandentierquinestpassuprieurunnombre. MOD,% Restedeladivisionentirededeuxnombres. RAND Nombrealatoiresuprieurougal0etstrictementinfrieur1. ROUND Nombrearrondilaprcisiondemande. TRUNCATE Nombretronqulaprcisiondemande. UnedivisionparzrodonneunrsultatNULL.

ABS Syntaxe ABS(nombre) LafonctionABSretournelavaleurabsoluedunnombre. CEILINGCEIL Syntaxe CEIL(nombre) LafonctionCEILING(ousonsynonymeCEIL)retournelepluspetitentierquinestpasinfrieurunnombre. Exemple mysql> SELECT nom,prix_ht,CEIL(prix_ht) FROM collection; +--------------------------+---------+---------------+ | nom | prix_ht | CEIL(prix_ht) | +--------------------------+---------+---------------+ | Ressources Informatiques | 24.44 | 25 | | TechNote | 10.48 | 11 | | Les TP Informatiques | 25.59 | 26 | | Coffret Technique | 46.45 | 47 |

ENI Editions - All rigths reserved

- 1-

| Solutions Informatiques | 36.97 | 37 | | ExpertIT | 20.00 | 20 | +--------------------------+---------+---------------+ 6 rows in set (0.00 sec)

DIV Syntaxe dividende DIV diviseur LoprateurDIVretournelersultatdeladivisionentirededeuxnombres. Exemple mysql> SELECT -> titre,nombre_pages,nombre_pages DIV 100 nb_cent_pages -> FROM livre WHERE id_collection = 1; +-------------------+--------------+---------------+ | titre | nombre_pages | nb_cent_pages | +-------------------+--------------+---------------+ | PHP 5.2 | 518 | 5 | | Oracle 10g | 489 | 4 | | BusinessObjects 6 | 470 | 4 | | MySQL 5 | 468 | 4 | +-------------------+--------------+---------------+ 4 rows in set (0.00 sec)

FLOOR Syntaxe FLOOR(nombre) LafonctionFLOORretourneleplusgrandentierquinestpassuprieurunnombre. Exemple mysql> SELECT nom,prix_ht,FLOOR(prix_ht) FROM collection; +--------------------------+---------+----------------+ | nom | prix_ht | FLOOR(prix_ht) | +--------------------------+---------+----------------+ | Ressources Informatiques | 24.44 | 24 | | TechNote | 10.48 | 10 | | Les TP Informatiques | 25.59 | 25 | | Coffret Technique | 46.45 | 46 | | Solutions Informatiques | 36.97 | 36 | | ExpertIT | 20.00 | 20 | +--------------------------+---------+----------------+ 6 rows in set (0.00 sec)

MOD% Syntaxe MOD(dividende,diviseur) dividende MOD diviseur dividende % diviseur La fonction MOD (modulo) retourne le reste de la division entire de deux nombres. MOD est aussi un oprateur loprateur%donnelemmersultat. Exemple mysql> SELECT -> titre,nombre_pages,nombre_pages MOD 100 reste_pages -> FROM livre WHERE id_collection = 1;

- 2-

ENI Editions - All rigths reserved

+-------------------+--------------+-------------+ | titre | nombre_pages | reste_pages | +-------------------+--------------+-------------+ | PHP 5.2 | 518 | 18 | | Oracle 10g | 489 | 89 | | BusinessObjects 6 | 470 | 70 | | MySQL 5 | 468 | 68 | +-------------------+--------------+-------------+ 4 rows in set (0.01 sec)

RAND Syntaxe RAND() LafonctionRANDretourneunnombrealatoiresuprieurougal0etstrictementinfrieur1. Exemple mysql> SELECT rand(),rand(),rand(); +------------------+-------------------+------------------+ | rand() | rand() | rand() | +------------------+-------------------+------------------+ | 0.23858279198276 | 0.075853456813706 | 0.66351893885389 | +------------------+-------------------+------------------+ 1 row in set (0.00 sec) Cette fonction peut tre utilise pour trier le rsultat dune requte selon un ordre alatoire, ou tirer au sort une ou plusieurslignes. Exemple mysql> SELECT nom FROM collection O R D E R B Y r a n d ( ) L I M I T 1 ; +-------------------+ | nom | +-------------------+ | Coffret Technique | +-------------------+ 1 row in set (0.00 sec) mysql> SELECT nom FROM collection O R D E R B Y r a n d ( ) L I M I T 1 ; +----------+ | nom | +----------+ | TechNote | +----------+ 1 row in set (0.00 sec)

ROUND Syntaxe ROUND(nombre[,prcision]) LafonctionROUNDretourneunnombrearrondilaprcisiondemande. prcision est gal 0 par dfaut (arrondi lentier le plus proche). prcision peut tre ngatif pour arrondir un certainnombredechiffresavantlavirgule. Exemple mysql> SELECT -> nom, -> prix_ht, -> ROUND(prix_ht) r1, -> ROUND(prix_ht,1) r2, -> ROUND(prix_ht,-1) r3

ENI Editions - All rigths reserved

- 3-

-> FROM collection; +--------------------------+---------+------+------+------+ | nom | prix_ht | r1 | r2 | r3 | +--------------------------+---------+------+------+------+ | Ressources Informatiques | 24.44 | 24 | 24.4 | 20 | | TechNote | 10.48 | 10 | 10.5 | 10 | | Les TP Informatiques | 25.59 | 26 | 25.6 | 30 | | Coffret Technique | 46.45 | 46 | 46.5 | 50 | | Solutions Informatiques | 36.97 | 37 | 37.0 | 40 | | ExpertIT | 20.00 | 20 | 20.0 | 20 | +--------------------------+---------+------+------+------+ 6 rows in set (0.00 sec)

TRUNCATE Syntaxe TRUNCATE(nombre,prcision) LafonctionTRUNCATEretourneunnombretronqulaprcisiondemande. Siprcisionestgal0latroncatureseffectuelentierleplusproche.prcisionpeuttrengatifpourtronquerun certainnombredechiffresavantlavirgule. Exemple mysql> SELECT -> nom, -> prix_ht, -> TRUNCATE(prix_ht,0) r1, -> TRUNCATE(prix_ht,1) r2, -> TRUNCATE(prix_ht,-1) r3 -> FROM collection; +--------------------------+---------+------+------+------+ | nom | prix_ht | r1 | r2 | r3 | +--------------------------+---------+------+------+------+ | Ressources Informatiques | 24.44 | 24 | 24.4 | 20 | | TechNote | 10.48 | 10 | 10.4 | 10 | | Les TP Informatiques | 25.59 | 25 | 25.5 | 20 | | Coffret Technique | 46.45 | 46 | 46.4 | 40 | | Solutions Informatiques | 36.97 | 36 | 36.9 | 30 | | ExpertIT | 20.00 | 20 | 20.0 | 20 | +--------------------------+---------+------+------+------+ 6 rows in set (0.00 sec)

- 4-

ENI Editions - All rigths reserved

Fonctionscaractres
Lesfonctionssuivantessontprsentesdanscettesection : CONCAT,CONCAT_WS Concatnationdechanesdecaractres. INSTR Positiondelapremireoccurrencedunechanelintrieureduneautrechane. LEFT,RIGHT npremiersounderniercaractresdunechane. LENGTH Longueurdunechane. LOWER,UPPER Chaneenminusculesouenmajuscules. LPAD,RPAD Chanecompltegaucheoudroiteparunesquencedecaractresjusquunecertainelongueur. LTRIM,RTRIM,TRIM Suppressiondespace(oudautrescaractres)endbutouenfindechane. REPEAT,SPACE Chaneconstruiteenrptantunesquencedecaractresuncertainnombredefois. REPLACE Remplacementdetouteslesoccurrencesdunechaneparuneautre. SUBSTRING,SUBSTR,SUBSTRING_INDEX Portiondunechane. R appel :seulesleschanesdecaractres binaires sontsensibleslacasse.

CONCATCONCAT_WS Syntaxe CONCAT(chane1,chane2[,...]) CONCAT_WS(sparateur,chane1,chane2[,...]) LafonctionCONCATretourneunechanedecaractresquiconcatnetoussesarguments. Lafonction CONCAT_WSestunevariantedelafonctionCONCAT.Lepremierargumentestunechanequiestutilisecomme sparateurdanslaconcatnationdesautresarguments. Exemple mysql> SELECT CONCAT(prenom, ,nom) FROM auteur; +------------------------+ | CONCAT(prenom, ,nom) | +------------------------+

ENI Editions - All rigths reserved

- 1-

| Jrme GABILLAUD | | Brice-Arnaud GUERIN | | Olivier HEURTEL | | Claire NOIRAULT | | Cyril THIBAUD | +------------------------+ 5 rows in set (0.00 sec) mysql> SELECT CONCAT_WS(,,nom,prenom) FROM auteur; +---------------------------+ | CONCAT_WS(,,nom,prenom) | +---------------------------+ | GABILLAUD,Jrme | | GUERIN,Brice-Arnaud | | HEURTEL,Olivier | | NOIRAULT,Claire | | THIBAUD,Cyril | +---------------------------+ 5 rows in set (0.00 sec)

INSTR Syntaxe INSTR(chane,chane_cherche) LafonctionINSTRretournelapositiondelapremireoccurrencedunechanelintrieureduneautrechane. Lafonctionretourne0silachanerecherchenestpastrouve. Exemple mysql> SELECT nom,INSTR(nom,Informatique) FROM collection; +--------------------------+---------------------------+ | nom | INSTR(nom,Informatique) | +--------------------------+---------------------------+ | Coffret Technique | 0 | | ExpertIT | 0 | | Les TP Informatiques | 8 | | Ressources Informatiques | 12 | | Solutions Informatiques | 11 | | TechNote | 0 | +--------------------------+---------------------------+ 6 rows in set (0.01 sec)

LEFTRIGHT Syntaxe LEFT(chane,nombre_caractres) RIGHT(chane,nombre_caractres) LesfonctionsLEFTetRIGHTretournentrespectivementlesn premiersoulesn derniercaractresdunechane. Exemple mysql> SELECT nom,LEFT(nom,8),RIGHT(nom,8) FROM collection; +--------------------------+-------------+--------------+ | nom | LEFT(nom,8) | RIGHT(nom,8) | +--------------------------+-------------+--------------+ | Coffret Technique | Coffret | echnique | | ExpertIT | ExpertIT | ExpertIT | | Les TP Informatiques | Les TP I | matiques | | Ressources Informatiques | Ressourc | matiques | | Solutions Informatiques | Solution | matiques | | TechNote | TechNote | TechNote | +--------------------------+-------------+--------------+ 6 rows in set (0.01 sec)

- 2-

ENI Editions - All rigths reserved

LENGTH Syntaxe LENGTH(chane) LafonctionLENGTHretournelalongueurdunechane. Exemple mysql> SELECT nom,LENGTH(nom) FROM collection; +--------------------------+-------------+ | nom | LENGTH(nom) | +--------------------------+-------------+ | Coffret Technique | 17 | | ExpertIT | 8 | | Les TP Informatiques | 20 | | Ressources Informatiques | 24 | | Solutions Informatiques | 23 | | TechNote | 8 | +--------------------------+-------------+ 6 rows in set (0.00 sec)

LOWERUPPER Syntaxe LOWER(chane) UPPER(chane) Les fonctions LOWER et UPPER retournent une chane avec toutes les lettres respectivement en minuscules ou en majuscules. Exemple mysql> SELECT LOWER(nom),UPPER(prenom) FROM auteur; +------------+---------------+ | LOWER(nom) | UPPER(prenom) | +------------+---------------+ | gabillaud | JRME | | guerin | BRICE-ARNAUD | | heurtel | OLIVIER | | noirault | CLAIRE | | thibaud | CYRIL | +------------+---------------+ 5 rows in set (0.00 sec)

LPADRPAD Syntaxe LPAD(chane,longueur,caractres) RPAD(chane,longueur,caractres) LesfonctionsLPADet RPADretournentunechanecomplterespectivementgaucheoudroiteparunesquencede caractresjusquunecertainelongueur. Exemple mysql> SELECT LPAD(nom,30,.) FROM collection; +--------------------------------+ | LPAD(nom,30,.) | +--------------------------------+ | .............Coffret Technique | | ......................ExpertIT | | ..........Les TP Informatiques | | ......Ressources Informatiques |
ENI Editions - All rigths reserved - 3-

| .......Solutions Informatiques | | ......................TechNote | +--------------------------------+ 6 rows in set (0.00 sec) mysql> SELECT RPAD(nom,30,.) FROM collection; +--------------------------------+ | RPAD(nom,30,.) | +--------------------------------+ | Coffret Technique............. | | ExpertIT...................... | | Les TP Informatiques.......... | | Ressources Informatiques...... | | Solutions Informatiques....... | | TechNote...................... | +--------------------------------+ 6 rows in set (0.01 sec)

LTRIMRTRIMTRIM Syntaxe LTRIM(chane) RTRIM(chane) TRIM([[BOTH | LEADING | TRAILING] [caractres] FROM] chane) LesfonctionsLTRIMet RTRIMretournentunechaneaprssuppressiondesespacessitusrespectivementaudbutou lafindelachane. LafonctionTRIMestunegnralisationdesfonctions LTRIMetRTRIMquipermetnotammentdespcifierlasquencede caractressupprimer. caractresspcifielasquencedecaractressupprimer(espacepardfaut). BOTH,LEADINGetTRAILINGindiquentque lasuppressiondoitseffectuerrespectivementdesdeuxcts(pardfaut),audbutoulafindelachane. Exemple mysql> SET @x= abc ; Query OK, 0 rows affected (0.00 sec) mysql> SELECT -> CONCAT(|,@x,|) x, -> CONCAT(|,LTRIM(@x),|) "ltrim(x)", -> CONCAT(|,RTRIM(@x),|) "rtrim(x)", -> CONCAT(|,TRIM(@x),|) "trim(x)"; +-------------+----------+----------+---------+ | x | ltrim(x) | rtrim(x) | trim(x) | +-------------+----------+----------+---------+ | | abc | | |abc | | | abc| | |abc| | +-------------+----------+----------+---------+ 1 row in set (0.00 sec) mysql> SET @x=***abc***; Query OK, 0 rows affected (0.00 sec) mysql> SELECT -> @x x, -> TRIM(BOTH * FROM @x) "trim(x)"; +-----------+---------+ | x | trim(x) | +-----------+---------+ | ***abc*** | abc | +-----------+---------+ 1 row in set (0.00 sec)

REPEATSPACE Syntaxe

- 4-

ENI Editions - All rigths reserved

REPEAT(caractres,nombre_fois) SPACE(nombre_fois) LafonctionREPEATretourneunechaneconstruiteenrptantunesquencedecaractresuncertainnombredefois. LafonctionSPACEestuncasparticulierdeREPEATolasquencedecaractresestunespace. Exemple mysql> SELECT CONCAT(REPEAT(*,5),SPACE(5),REPEAT(*,5)) x; +-----------------+ | x | +-----------------+ | ***** ***** | +-----------------+ 1 row in set (0.01 sec)

REPLACE Syntaxe REPLACE(chane,chane_cherche,chane_remplacement) LafonctionREPLACEretourneunechaneaprsremplacementdetouteslesoccurrencesdunechaneparuneautre. Exemple mysql> SELECT nom,REPLACE(nom,Informatiques,Techniques) nouveau -> FROM collection WHERE nom LIKE %informatiques%; +--------------------------+-----------------------+ | nom | nouveau | +--------------------------+-----------------------+ | Les TP Informatiques | Les TP Techniques | | Ressources Informatiques | Ressources Techniques | | Solutions Informatiques | Solutions Techniques | +--------------------------+-----------------------+ 3 rows in set (0.00 sec)

SUBSTRINGSUBSTRSUBSTRING_INDEX Syntaxe SUBSTRING(chane,position[,longueur]) SUBSTRING(chane FROM position [FOR longueur]) SUBSTRING_INDEX(chane,dlimiteur,occurrence) La fonction SUBSTRING retourne la portion dune chane qui commence une certaine position et qui a une certaine longueur.LafonctionSUBSTRestunsynonymedelafonctionSUBSTRING. positionspcifielapositiondupremiercaractreextraire(1pourlepremiercaractredelachane) si positionest ngatif,lapositionestcomptepartirdelafindelachane. longueurspcifielenombredecaractresextraire silestomis,lafonctionretournetouslescaractresjusqulafin delachane. LafonctionSUBSTRING_INDEXretournelaportiondunechanesitueavantouaprslanimeoccurrencedundlimiteur. dlimiteurspcifielachaneutilisecommedlimiteur. occurrence spcifie loccurrence du dlimiteur utiliser (1 pour la premire occurrence). Si occurrence est positif, les occurrencessontcomptesenpartantdudbutdelachaneetlafonctionretournelaportiondechanesitueavantle dlimiteur. si occurrence est ngatif, les occurrences sont comptes en partant de la fin de la chane et la fonction retournelaportiondechanesitueaprsledlimiteur. Exemple mysql> SELECT -> nom, -> SUBSTR(nom,6), -> SUBSTR(nom,6,3)

ENI Editions - All rigths reserved

- 5-

-> FROM collection; +--------------------------+---------------------+-----------------+ | nom | SUBSTR(nom,6) | SUBSTR(nom,6,3) | +--------------------------+---------------------+-----------------+ | Coffret Technique | et Technique | et | | ExpertIT | tIT | tIT | | Les TP Informatiques | P Informatiques | P I | | Ressources Informatiques | urces Informatiques | urc | | Solutions Informatiques | ions Informatiques | ion | | TechNote | ote | ote | +--------------------------+---------------------+-----------------+ 6 rows in set (0.00 sec) mysql> SELECT -> nom, -> SUBSTR(nom,-6), -> SUBSTR(nom,-6,3) -> FROM collection; +--------------------------+----------------+------------------+ | nom | SUBSTR(nom,-6) | SUBSTR(nom,-6,3) | +--------------------------+----------------+------------------+ | Coffret Technique | hnique | hni | | ExpertIT | pertIT | per | | Les TP Informatiques | tiques | tiq | | Ressources Informatiques | tiques | tiq | | Solutions Informatiques | tiques | tiq | | TechNote | chNote | chN | +--------------------------+----------------+------------------+ 6 rows in set (0.00 sec) mysql> SET @x=/chemin/vers/fichier.txt; Query OK, 0 rows affected (0.00 sec) mysql> SELECT SUBSTRING_INDEX(@x,/,2); +---------------------------+ | SUBSTRING_INDEX(@x,/,2) | +---------------------------+ | /chemin | +---------------------------+ 1 row in set (0.00 sec) mysql> SELECT SUBSTRING_INDEX(@x,/,-1); +----------------------------+ | SUBSTRING_INDEX(@x,/,-1) | +----------------------------+ | fichier.txt | +----------------------------+ 1 row in set (0.00 sec)

- 6-

ENI Editions - All rigths reserved

Fonctionsdates
Lesfonctionssuivantessontprsentesdanscettesection : ADDDATE,DATE_ADD,DATE_SUB,SUBDATE Ajouteouretrancheunintervalledetempsunedate. CURDATE,CURRENT_DATE,UTC_DATE Datecourante. CURTIME,CURRENT_TIME,UTC_TIME Heurecourante. CURRENT_TIMESTAMP,NOW,LOCALTIME,LOCALTIMESTAMP,SYSDATE,UTC_TIMESTAMP Date/heurecourante. DATE Extraitlapartiedatedunedate/heure. DATEDIFF Diffrenceennombredejourentredeuxdates. DAYOFWEEK,WEEKDAY,DAYOFMONTH,DAYOFYEAR Extraitlenumrodujourdanslasemaine,danslemoisoudanslannedunedate. EXTRACT Extraitunecomposantedunedate. LAST_DAY Dernierjourdumoisdunedate. MONTH Numrodemoisdunedate. WEEK,WEEKOFYEAR Numrodesemainedunedate. YEAR Annedunedate. lexceptiondeSYSDATE,lesfonctionsquiretournentladateet/oulheure courante sontvaluesunefoisau dbutdelarequte cesfonctionsretournentdoncladateet/oulheurededbutdexcutiondelarequte.Si une telle fonction est appele plusieurs fois lintrieur de la requte, cest donc toujours la mme valeur qui est retourne.

ADDDATEDATE_ADDDATE_SUBSUBDATE Syntaxe ADDDATE(date,INTERVAL valeur unit) ADDDATE(date,nombre_jours) DATE_ADD(date,INTERVAL valeur unit)

ENI Editions - All rigths reserved

- 1-

DATE_SUB(date,INTERVAL valeur unit) SUBDATE(date,INTERVAL valeur unit) SUBDATE(date,nombre_jours) Lesfonctions ADDDATE,DATE_ADD, DATE_SUBetSUBDATEretournentunedateaprsajoutousoustractiondunintervallede temps. Dans les syntaxes avec le mot cl INTERVAL, unit est un mot cl qui donne lunit de lintervalle (voir cidessous) et valeurestuneexpressionquidonnelavaleurdelintervalleajouterouretrancherladate(valeurpeuttrepositif oungatif). Exemplesdintervalle Motcl Valeur SECOND Secondes MINUTE Minutes HOUR Heures DAY Jours WEEK Semaines MONTH Mois QUARTER Trimestres YEAR Annes MINUTE_SECOND Minutesetsecondesauformatm:s HOUR_SECOND Heures,minutesetsecondesauformath:m:s HOUR_MINUTE Heuresetminutesauformath:m DAY_SECOND Jours,heures,minutesetsecondesauformatjh:m:s DAY_MINUTE Jours,heuresetminutesauformatjm:s

- 2-

ENI Editions - All rigths reserved

DAY_HOUR Joursetheuresauformatjh YEAR_MONTH Annesetmoisauformatam lexisteaussidesintervallesquipermettentdespcifierdesmicrosecondes.Nimportequeldlimiteurpeuttre I utilisdanslesformats. ADDDATE,danssasyntaxeaveclemotclINTERVAL,estunsynonymedeDATE_ADD.SUBDATE,danssasyntaxeaveclemot clINTERVAL,estunsynonymedeDATE_SUB. ADDDATE(date,n) est quivalent DATE_ADD(date,INTERVAL (date,INTERVAL n DAY). n DAY). SUBDATE(date,n) est quivalent DATE_SUB

Lesmmesoprationspeuventtreeffectuesdirectementsurunedateenutilisantlesoprateurs +, -etlemotcl INTERVAL : date + INTERVAL valeur unit date - INTERVAL valeur unit

orsduneoprationaveclesmoisetlesannes,silersultatdonneunjourplusgrandquelenombredejours L dumois,lejourestajustaunombremaximumdejoursdumoisrsultat. Exemple mysql> SET @d=2008-01-22; Query OK, 0 rows affected (0.00 sec) mysql> SELECT -> @d, -> ADDDATE(@d,1) "+ 1 jour", -> ADDDATE(@d,INTERVAL 10 DAY) "+ 10 jours", -> ADDDATE(@d,INTERVAL 1-3 YEAR_MONTH) "+ 1 an et 3 mois"; +------------+------------+------------+------------------+ | @d | + 1 jour | + 10 jours | + 1 an et 3 mois | +------------+------------+------------+------------------+ | 2008-01-22 | 2008-01-23 | 2008-02-01 | 2009-04-22 | +------------+------------+------------+------------------+ 1 row in set (0.00 sec)

CURDATECURRENT_DATEUTC_DATE Syntaxe CURDATE() CURRENT_DATE() UTC_DATE() Lesfonctions CURDATEet CURRENT_DATEretournentladatedudbutdexcutiondelarequteauformat YYYY-MM-DDou YYYYMMDDselonquelafonctionestappeledansuncontextedechaneoudenombre. LafonctionUTC_DATEretournelammechosemaispourladateUTC. Exemple mysql> SELECT CURDATE(); +------------+ | CURDATE() | +------------+ | 2008-01-22 | +------------+

ENI Editions - All rigths reserved

- 3-

1 row in set (0.00 sec) mysql> SELECT date_debut,date_fin FROM promotion WHERE id = 2; +------------+----------+ | date_debut | date_fin | +------------+----------+ | NULL | NULL | +------------+----------+ 1 row in set (0.01 sec) mysql> UPDATE promotion -> SET date_debut = CURDATE(),date_fin = ADDDATE(CURDATE(),7) -> WHERE id = 2; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT date_debut,date_fin FROM promotion WHERE id = 2; +------------+------------+ | date_debut | date_fin | +------------+------------+ | 2008-01-22 | 2008-01-29 | +------------+------------+ 1 row in set (0.00 sec)

CURTIMECURRENT_TIMEUTC_TIME Syntaxe CURTIME() CURRENT_TIME() UTC_TIME() Les fonctions CURTIME et CURRENT_TIME retournent lheure du dbut dexcution de la requte au format HH:MM:SS ou HHMMSSselonquelafonctionestappeledansuncontextedechaneoudenombre. LafonctionUTC_TIMEretournelammechosemaispourlheureUTC. Exemple mysql> SELECT CURTIME(); +-----------+ | CURTIME() | +-----------+ | 15:30:16 | +-----------+ 1 row in set (0.00 sec)

CURRENT_TIMESTAMPNOWLOCALTIMELOCALTIMESTAMPSYSDATEUTC_TIMESTAMP Syntaxe CURRENT_TIMESTAMP() NOW() LOCALTIME() LOCALTIMESTAMP() SYSDATE() UTC_TIMESTAMP() La fonction NOW retourne la date/heure du dbut dexcution de la requte au format YYYY-MM-DD HH:MM:SS ou YYYYMMDDHHMMSS selon que la fonction est appele dans un contexte de chane ou de nombre. Les fonctions CURRENT_TIMESTAMP, LOCALTIMEet LOCALTIMESTAMPsontdessynonymesdelafonction NOW.Silafonction NOWestappele plusieursfoisdansunerequte(ouuneprocdurestocke),elleretournetoujourslemmersultat. LafonctionUTC_TIMESTAMPretournelammechosemaispourladate/heureUTC. La fonction SYSDATE retourne la date/heure courante au format YYYY-MM-DD HH:MM:SS ou YYYYMMDDHHMMSS selon que la fonctionestappeledansuncontextedechaneoudenombre.Silafonction SYSDATEestappeleplusieursfoisdans unerequte(ouuneprocdurestocke),elleestrvaluechaquefois.

- 4-

ENI Editions - All rigths reserved

Exemple mysql> SELECT NOW(),UTC_TIMESTAMP(); +---------------------+---------------------+ | NOW() | UTC_TIMESTAMP() | +---------------------+---------------------+ | 2008-01-22 15:30:51 | 2008-01-22 14:30:51 | +---------------------+---------------------+ 1 row in set (0.00 sec)

DATE Syntaxe DATE(date) LafonctionDATEretournelapartiedatedunedate/heure. Exemple mysql> SELECT date_maj,DATE(date_maj) FROM livre WHERE id = 2; +---------------------+----------------+ | date_maj | DATE(date_maj) | +---------------------+----------------+ | 2008-01-22 15:26:16 | 2008-01-22 | +---------------------+----------------+ 1 row in set (0.00 sec)

DATEDIFF Syntaxe DATEDIFF(date1,date2) Lafonction DATEDIFFretourneladiffrenceennombredejoursentredeuxdates(lescomposanteshorairesventuelles desdeuxdatessontignores). Exemple mysql> SELECT DATEDIFF(date_fin,date_debut) -> FROM promotion WHERE id = 2; +-------------------------------+ | DATEDIFF(date_fin,date_debut) | +-------------------------------+ | 7 | +-------------------------------+ 1 row in set (0.00 sec)

DAYOFWEEKDAYOFMONTHDAYOFYEARWEEKDAY Syntaxe DAYOFWEEK(date) DAYOFMONTH(date) DAYOFYEAR(date) Les fonctions DAYOFWEEK (ou WEEKDAY), DAYOFMONTH et DAYOFYEAR retournent respectivement le numro du jour dans la semaine,danslemoisoudanslannedunedate. Lafonction DAYOFWEEKretourneunnombrecomprisentre1et7(1=dimanche).LafonctionWEEKDAYretourneunnombre comprisentre0et6(0=lundi). Exemple mysql> SET @d=2008-04-06; -- dimanche 6 avril Query OK, 0 rows affected (0.00 sec)

ENI Editions - All rigths reserved

- 5-

mysql> SELECT -> @d, -> DAYOFWEEK(@d), -> DAYOFMONTH(@d), -> DAYOFYEAR(@d) -> ; +------------+---------------+----------------+---------------+ | @d | DAYOFWEEK(@d) | DAYOFMONTH(@d) | DAYOFYEAR(@d) | +------------+---------------+----------------+---------------+ | 2008-04-06 | 1 | 6 | 97 | +------------+---------------+----------------+---------------+ 1 row in set (0.00 sec)

EXTRACT Syntaxe EXTRACT(unit FROM date) LafonctionEXTRACTretourneunecomposantedunedate. unit est un mot cl qui spcifie la composante extraire ce sont les mmes mots cls que pour la spcification de lintervalledanslesfonctionsDATE_ADDetDATE_SUB. Exemple mysql> SELECT -> NOW(), -> EXTRACT(DAY FROM NOW()) jour, -> EXTRACT(MONTH FROM NOW()) mois, -> EXTRACT(YEAR FROM NOW()) annee, -> EXTRACT(HOUR FROM NOW()) heure -> ; +---------------------+------+------+-------+-------+ | NOW() | jour | mois | annee | heure | +---------------------+------+------+-------+-------+ | 2008-01-22 15:42:25 | 22 | 1 | 2008 | 15 | +---------------------+------+------+-------+-------+ 1 row in set (0.00 sec)

LASTDAY Syntaxe LAST_DAY(date) LafonctionLAST_DAYretourneunedatecorrespondantaudernierjourdumoisdunedate. Exemple mysql> SELECT -> LAST_DAY(NOW()), -> LAST_DAY(NOW()+INTERVAL 1 MONTH); +-----------------+----------------------------------+ | LAST_DAY(NOW()) | LAST_DAY(NOW()+INTERVAL 1 MONTH) | +-----------------+----------------------------------+ | 2008-01-31 | 2008-02-29 | +-----------------+----------------------------------+ 1 row in set (0.01 sec)

MONTH Syntaxe MONTH(date) LafonctionMONTHretournelenumrodemoisdunedate.

- 6-

ENI Editions - All rigths reserved

Exemple mysql> SELECT CURRENT_DATE(),MONTH(CURRENT_DATE()); +----------------+-----------------------+ | CURRENT_DATE() | MONTH(CURRENT_DATE()) | +----------------+-----------------------+ | 2008-01-22 | 1 | +----------------+-----------------------+ 1 row in set (0.00 sec)

WEEKWEEKOFYEAR Syntaxe WEEK(date,mode) WEEKOFYEAR(date) LesfonctionsWEEKetWEEKOFYEARretournentlenumrodesemainedunedate. modepermetdindiquersilasemainedmarreundimancheouunlundi,etsilersultatdoittrecomprisentre0et53ou entre1et53.Lesvaleurspossiblessontlessuivantes : Premierjourdela semaine Lasemaine1estla semaine Avecundimanchedans cetteanne Avecplusde3jours cetteanne Avecundimanchedans cetteanne Avecplusde3jours cetteanne Avecplusde3jours cetteanne Avecunlundidanscette anne Avecplusde3jours cetteanne Avecunlundidanscette anne

Mode

Rsultat

Dimanche

053

Lundi

053

Dimanche

153

Lundi

153

Dimanche

053

Lundi

053

Dimanche

153

Lundi

153

WEEKOFYEAR(date)estquivalentWEEK(date,3). Exemple mysql> SELECT CURRENT_DATE(),WEEKOFYEAR(CURRENT_DATE()); +----------------+----------------------------+ | CURRENT_DATE() | WEEKOFYEAR(CURRENT_DATE()) | +----------------+----------------------------+ | 2008-01-22 | 4 | +----------------+----------------------------+ 1 row in set (0.00 sec)

YEAR Syntaxe

ENI Editions - All rigths reserved

- 7-

YEAR(date) LafonctionYEARretournelannedunedate. Exemple mysql> SELECT CURRENT_DATE(),YEAR(CURRENT_DATE()); +----------------+----------------------+ | CURRENT_DATE() | YEAR(CURRENT_DATE()) | +----------------+----------------------+ | 2008-01-22 | 2008 | +----------------+----------------------+ 1 row in set (0.01 sec)

- 8-

ENI Editions - All rigths reserved

Fonctionsdetranstypageetdemiseenforme
Lesfonctionssuivantessontprsentesdanscettesection : BINARY Conversiondunechaneenchanebinaire. CAST,CONVERT Conversiondunedonneduntypeenunautre. DATE_FORMAT Formateunedate. FORMAT Formateunnombre. STR_TO_DATE Conversiondunechaneendate. BINARY Syntaxe BINARY chane LoprateurBINARYconvertitunechaneenchanebinaire. Exemple mysql> -- Recherche non sensible la casse mysql> SELECT prix_ht FROM collection WHERE nom = TECHNOTE; +---------+ | prix_ht | +---------+ | 10.48 | +---------+ 1 row in set (0.00 sec) mysql> -- Recherche sensible la casse mysql> SELECT prix_ht FROM collection WHERE nom = BINARY TECHNOTE; Empty set (0.00 sec)

CASTCONVERT Syntaxe CAST(expression AS type) CONVERT(expression,type) LesfonctionsCASTetCONVERTconvertissentuneexpressionduntypequelconquedansunautretype. typepeuttreunedesvaleurssuivantes : BINARY[(n)] Chanebinaire(ventuellementlimitenoctets) CHAR[(n)] Chanebinaire(ventuellementlimitencaractres)

ENI Editions - All rigths reserved

- 1-

DATE Date DATETIME Date/heure DECIMAL Nombredcimal SIGNED [INTEGER] Entiersign TIME Heure UNSIGNED [INTEGER] Entiernonsign Exemple mysql> SELECT -> prix_ht, -> CAST(prix_ht AS SIGNED) entier, -> CAST(prix_ht AS CHAR) chaine -> FROM -> collection; +---------+--------+--------+ | prix_ht | entier | chaine | +---------+--------+--------+ | 24.44 | 24 | 24.44 | | 10.48 | 10 | 10.48 | | 25.59 | 26 | 25.59 | | 46.45 | 46 | 46.45 | | 36.97 | 37 | 36.97 | | 20.00 | 20 | 20.00 | +---------+--------+--------+ 6 rows in set (0.00 sec)

S ilaconversionnepeutpastreeffectue,lafonctionretourneunevaleurarbitrairemaisnegnrepasderreur.

DATE_FORMAT Syntaxe DATE_FORMAT(date,format) LafonctionDATE_FORMATretourneunedateformateselonuncertainformat. formatpermetdespcifierleformat lessquencessuivantespeuventtreutilisespourspcifierleformat(listenon exhaustive) : %e Numrodujourdumois(131) %d Numrodujourdumois(0131)


- 2 ENI Editions - All rigths reserved

%c Numrodumois(112) %m Numrodumois(0112) %Y Annesur4chiffres %y Annesur2chiffres %H Heure(0023) %i Minutes(0059) %S,%s Secondes(0059) %T Heure(sur24heures),minutesetsecondesauformathh:mm:ss %j Numrodujourdanslanne(001366) %W Nomdujourdelasemaine %M Nomdumois Lavariablesystme lc_time_namesdfinitlalangueutilisepourafficherlesnomsdejouroudemois.Lavaleur fr_FR peuttreutilisepouravoirdesnomsenfranais(SET lc_time_names = fr_FR). LafonctionGET_FORMATpeuttreutilisepourrcuprerdesformats standards . Syntaxe : GET_FORMAT(DATE | TIME | TIMESTAMP, EUR | USA | JIS | ISO | INTERNAL)

Appel GET_FORMAT(DATE,USA) GET_FORMAT(DATE,JIS) GET_FORMAT(DATE,ISO) GET_FORMAT(DATE,EUR) GET_FORMAT(DATE,INTERNAL)

Rsultat %m.%d.%Y %Y-%m-%d %Y-%m-%d %d.%m.%Y %Y%m%d


ENI Editions - All rigths reserved - 3-

GET_FORMAT(TIMESTAMP,USA) GET_FORMAT(TIMESTAMP,JIS) GET_FORMAT(TIMESTAMP,ISO) GET_FORMAT(TIMESTAMP,EUR) GET_FORMAT(TIMESTAMP,INTERNAL) GET_FORMAT(TIME,USA) GET_FORMAT(TIME,JIS) GET_FORMAT(TIME,ISO) GET_FORMAT(TIME,EUR) GET_FORMAT(TIME,INTERNAL) Exemple

%Y-%m-%d-%H.%i.%s %Y-%m-%d %H:%i:%s %Y-%m-%d %H:%i:%s %Y-%m-%d-%H.%i.%s %Y%m%d%H%i%s %h:%i:%s %p

%H:%i:%s
%H:%i:%s %H.%i.%S %H%i%s

mysql> SELECT -> NOW(), -> DATE_FORMAT(NOW(),%d/%m/%Y %H:%i:%s) france, -> DATE_FORMAT(NOW(),GET_FORMAT(TIMESTAMP,EUR)) europe; +---------------------+---------------------+---------------------+ | NOW() | france | europe | +---------------------+---------------------+---------------------+ | 2008-01-22 16:21:50 | 22/01/2008 16:21:50 | 2008-01-22 16.21.50 | +---------------------+---------------------+---------------------+ 1 row in set (0.00 sec)

FORMAT Syntaxe FORMAT(nombre,dcimales) LafonctionFORMATretourneunnombreavecunemiseenformedutype#,###,###.##. Lenombreestarrondiaunombrededcimalesspcifiparlargumentdcimales. Exemple mysql> SET @x=1234.567; Query OK, 0 rows affected (0.00 sec) mysql> SELECT @x,FORMAT(@x,2); +----------+--------------+ | @x | FORMAT(@x,2) | +----------+--------------+ | 1234.567 | 1,234.57 | +----------+--------------+ 1 row in set (0.00 sec)

STR_TO_DATE Syntaxe STR_TO_DATE(chane,format) LafonctionSTR_TO_DATEconvertitunechaneendate cestlinversedelafonctionFORMAT_DATE.

- 4-

ENI Editions - All rigths reserved

format permet de spcifier le format de la chane, laide des mmes symboles que ceux utiliss dans la fonction FORMAT_DATE. Exemple mysql> SET @x=20080122-180709; Query OK, 0 rows affected (0.00 sec) mysql> SELECT @x,STR_TO_DATE(@x,%Y%m%d-%H%i%s); +-----------------+---------------------------------+ | @x | STR_TO_DATE(@x,%Y%m%d-%H%i%s) | +-----------------+---------------------------------+ | 20080122-180709 | 2008-01-22 18:07:09 | +-----------------+---------------------------------+ 1 row in set (0.00 sec)

ENI Editions - All rigths reserved

- 5-

Fonctionssystme
Lesfonctionssuivantessontprsentesdanscettesection : CURRENT_USER,SESSION_USER,SYSTEM_USER,USER Utilisateurcourant. DATABASE,SCHEMA Basededonnescourante. FOUND_ROWS NombredelignesretournesparledernierordreSELECT. LAST_INSERT_ID ValeurautomatiquementgnreparunecolonnedetypeAUTO_INCREMENTlorsdudernierINSERT. ROW_COUNT NombredelignesmisesjourparledernierordreINSERT,UPDATEouDELETE. VERSION VersiondeMySQL. CURRENT_USERSESSION_USERSYSTEM_USERUSER Syntaxe CURRENT_USER() USER() SESSION_USER() SYSTEM_USER() La fonction CURRENT_USER retourne le nom dutilisateur et le nom de la machine de la session courante, sous la forme utilisateur@machine. La fonction USER retourne le nom dutilisateur et le nom de la machine spcifis lors de lidentification avec le serveur MySQL, sous la forme utilisateur@machine. Les fonctions SESSION_USER et SYSTEM_USER sont des synonymes de la fonctionUSER. Le rsultat des deux fonctions peut tre diffrent. Par exemple, si un client a t identifi par le serveur comme utilisateuranonyme,lafonction CURRENT_USERretourneraunnomdutilisateurvide,alorsquelafonctionUSERretournele nomrellementspcifidanslachanedeconnexion. Exemple [root@xampp ~]# mysql -u root ... mysql> SELECT CURRENT_USER(),USER(); +----------------+----------------+ | CURRENT_USER() | USER() | +----------------+----------------+ | root@localhost | root@localhost | +----------------+----------------+ 1 row in set (0.00 sec) mysql> exit Bye [root@xampp ~]# mysql -u eni ... mysql> SELECT CURRENT_USER(),USER(); +----------------+---------------+
ENI Editions - All rigths reserved - 1-

| CURRENT_USER() | USER() | +----------------+---------------+ | @localhost | eni@localhost | +----------------+---------------+ 1 row in set (0.00 sec)

DATABASESCHEMA Syntaxe DATABASE()SCHEMA() Les fonctions DATABASE et SCHEMA retournent le nom de la base de donnes courante ( NULL sil ny a pas de base de donnescourante).LafonctionSCHEMAestunsynonymedelafonctionDATABASEquiestapparuenversion5.0.2. Exemple mysql> SELECT DATABASE(),SCHEMA(); +------------+----------+ | DATABASE() | SCHEMA() | +------------+----------+ | NULL | NULL | +------------+----------+ 1 row in set (0.00 sec) mysql> USE eni; Database changed mysql> SELECT DATABASE(),SCHEMA(); +------------+----------+ | DATABASE() | SCHEMA() | +------------+----------+ | eni | eni | +------------+----------+ 1 row in set (0.00 sec)

FOUND_ROWS Syntaxe FOUND_ROWS() LafonctionFOUND_ROWSretournelenombredelignesrenvoyesparledernierordreSELECT. Exemple mysql> SELECT titre FROM livre WHERE id_collection = 1; +-------------------+ | titre | +-------------------+ | PHP 5.2 | | Oracle 10g | | BusinessObjects 6 | | MySQL 5 | +-------------------+ 4 rows in set (0.00 sec) mysql> SELECT FOUND_ROWS(); +--------------+ | FOUND_ROWS() | +--------------+ | 4 | +--------------+ 1 row in set (0.01 sec)

LAST_INSERT_ID Syntaxe

- 2-

ENI Editions - All rigths reserved

LAST_INSERT_ID() Lafonction LAST_INSERT_IDretournelavaleurautomatiquementgnreparunecolonnedetype AUTO_INCREMENTlors dudernierINSERT.SiledernierINSERTainsrplusieurslignes,cestlavaleurgnrepourlapremireligneinsrequi estretourne. Lorsquevousutilisezunordre INSERT IGNOREetquuneligneestignore,lecompteur AUTO_INCREMENTestmalgrtout incrment. Avant la version 5.1.12, la fonction LAST_INSERT_ID retourne la valeur gnre pour la premire ligne insre,mmesicelleciatignore depuislaversion5.1.12,lafonctionretournelavaleurgnrepourlapremire ligneinsreavecsuccs. Exemple mysql> INSERT INTO rubrique(titre) VALUES(Certification); Query OK, 1 row affected (0.00 sec) mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 16 | +------------------+ 1 row in set (0.01 sec)

ROW_COUNT Syntaxe ROW_COUNT() LafonctionROW_COUNTretournelenombredelignestraitesavecsuccsparledernierordreINSERT,UPDATEouDELETE. Exemple mysql> DELETE FROM catalogue; Query OK, 2 rows affected (0.00 sec) mysql> SELECT ROW_COUNT(); +-------------+ | ROW_COUNT() | +-------------+ | 2 | +-------------+ 1 row in set (0.01 sec)

VERSION Syntaxe VERSION() LafonctionVERSIONretournelaversionduserveurMySQL. Exemple mysql> SELECT VERSION(); +-----------+ | VERSION() | +-----------+ | 5.0.45 | +-----------+ 1 row in set (0.00 sec)

ENI Editions - All rigths reserved

- 3-

Fonctionsdechiffrementetdecompression
Lesfonctionssuivantessontprsentesdanscettesection : AES_ENCRYPT,AES_DECRYPT Chiffrement/dchiffrementdedonnesutilisantlalgorithmeAES. COMPRESS,UNCOMPRESS Compression/dcompressiondedonnes. MD5,SHA1,SHA Sommedevrificationdunechane. PASSWORD Motdepassechiffr. esfonctionsdechiffrageetdecompressionretournentdeschanesbinaires pourlestockageenbasedetelles L donnes,ilestconseilldutiliserunecolonnedetypeBLOB.

AES_ENCRYPTAES_DECRYPT Syntaxe AES_ENCRYPT(chane,cl) AES_DECRYPT(chane,cl) Les fonctions AES_ENCRYPT et AES_DECRYPT chiffrent et dchiffrent une chane en utilisant lalgorithme AES (Advanced EncryptionStandard)avecuneclde128bits. Exemple mysql> UPDATE auteur -> SET mot_de_passe = AES_ENCRYPT(abc123,secretdefense) -> WHERE id = 1; Query OK, 0 rows affected (0.00 sec) Rows matched: 1 Changed: 0 Warnings: 0 mysql> SELECT mot_de_passe FROM auteur WHERE id = 1; +------------------+ | mot_de_passe | +------------------+ | ~YU(@zB | +------------------+ 1 row in set (0.00 sec) mysql> SELECT AES_DECRYPT(mot_de_passe,secretdefense) -> FROM auteur WHERE id = 1; +-------------------------------------------+ | AES_DECRYPT(mot_de_passe,secretdefense) | +-------------------------------------------+ | abc123 | +-------------------------------------------+ 1 row in set (0.00 sec)

COMPRESSUNCOMPRESS Syntaxe COMPRESS(chane) UNCOMPRESS(chane)


ENI Editions - All rigths reserved - 1-

Lesfonctions COMPRESS et UNCOMPRESScompressentetdcompressentunechane.CesfonctionsncessitentqueMySQL aittcompilavecunelibrairiedecompression sicenestpaslecas,cesfonctionsretournenttoujoursNULL. Exemple mysql> UPDATE auteur -> SET profil = COMPRESS(Une longue description ...) -> WHERE id = 1; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT profil FROM auteur WHERE id = 1; +----------------------------------------+ | profil | +----------------------------------------+ | x KUK/MUHI-N.,(S A | +----------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT UNCOMPRESS(profil) FROM auteur WHERE id = 1; +----------------------------+ | UNCOMPRESS(profil) | +----------------------------+ | Une longue description ... | +----------------------------+ 1 row in set (0.00 sec)

MD5SHA1SHA Syntaxe MD5(chane) SHA1(chane) Les fonctions MD5 et SHA1 retournent la somme de vrification dune chane en utilisant respectivement les algorithmes MD5(128bits)etSHA1(160bits).LafonctionSHAestunsynonymedelafonctionSHA1. Exemple mysql> SELECT SHA1(Olivier Heurtel); +------------------------------------------+ | SHA1(Olivier Heurtel) | +------------------------------------------+ | 7c9e072cdc1132ce6e3746911cfc65d63db99959 | +------------------------------------------+ 1 row in set (0.00 sec)

PASSWORD Syntaxe PASSWORD(chane) LafonctionPASSWORDestlafonctionutiliseparMySQLpourchiffrerunmotdepasse lechiffrageestirrversible. Exemple mysql> UPDATE auteur -> SET mot_de_passe = PASSWORD(abc123) -> WHERE id = 1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT OK FROM auteur -> WHERE id = 1 AND mot_de_passe = PASSWORD(123abc); Empty set (0.00 sec)

- 2-

ENI Editions - All rigths reserved

mysql> SELECT OK FROM auteur -> WHERE id = 1 AND mot_de_passe = PASSWORD(abc123); +----+ | OK | +----+ | OK | +----+ 1 row in set (0.00 sec)

ENI Editions - All rigths reserved

- 3-

Fonctionsdagrgat
Lesfonctionsdagrgatsontparticulires :ellesretournentunelignedersultatpargroupedelignesenentre. Ces fonctions sont la plupart du temps utilises dans les requtes qui groupent les donnes (utilisation de la clause GROUP BY,cf.chapitreTechniquesavancesavecMySQLGrouperlesdonnes). Sicesfonctionssontutilisesdansunerequtequineffectuepasdegroupementdedonnes,celarevientgrouper toutesleslignes :lafonctionretourneuneseulelignedersultat.Danscecas,laclause SELECTdelarequtenedoit contenirquedesexpressionsquiutilisentunefonctiondagrgat. Lesfonctionssuivantessontprsentesdanscettesection : MIN,MAX Minimumoumaximum. SUM Somme. AVG Moyenne. COUNT Nombre. ourtoutescesfonctions,lesvaleursNULLsontignores laprsencedunevaleurNULLdanslecalculnedonne P pasunrsultatNULL.

MINMAX Syntaxe MIN(expression) MAX(expression) LesfonctionsMINetMAXretournentrespectivementleminimumetlemaximumdetouteslesvaleursdeexpression. Exemple mysql> SELECT MIN(nombre_pages),MAX(nombre_pages) -> FROM livre WHERE id_collection = 1; +-------------------+-------------------+ | MIN(nombre_pages) | MAX(nombre_pages) | +-------------------+-------------------+ | 447 | 518 | +-------------------+-------------------+ 1 row in set (0.00 sec)

SUMAVG Syntaxe SUM(expression) AVG(expression) LesfonctionsSUMetAVGretournentrespectivementlasommeetlamoyennedetouteslesvaleursdeexpression. Pourlafonction AVG,lefaitquelesvaleursNULLsoientignoresinfluesurlenombredevaleursprisesencomptedansle calcul. Exemple

ENI Editions - All rigths reserved

- 1-

mysql> SELECT frais_ht FROM collection; +----------+ | frais_ht | +----------+ | 1.50 | | NULL | | 1.50 | | 2.00 | | 1.25 | | NULL | +----------+ 6 rows in set (0.00 sec) mysql> SELECT SUM(frais_ht),AVG(frais_ht) FROM collection; +---------------+---------------+ | SUM(frais_ht) | AVG(frais_ht) | +---------------+---------------+ | 6.25 | 1.562500 | +---------------+---------------+ 1 row in set (0.01 sec) mysql> SELECT SUM(frais_ht),AVG(frais_ht),AVG(IFNULL(frais_ht,0)) -> FROM collection; +---------------+---------------+-------------------------+ | SUM(frais_ht) | AVG(frais_ht) | AVG(IFNULL(frais_ht,0)) | +---------------+---------------+-------------------------+ | 6.25 | 1.562500 | 1.041667 | +---------------+---------------+-------------------------+ 1 row in set (0.00 sec) mysql> -- Vrification mysql> SELECT (1.5+1.5+2+1.25)/4,(1.5+0+1.5+2+1.25+0)/6; +--------------------+------------------------+ | (1.5+1.5+2+1.25)/4 | (1.5+0+1.5+2+1.25+0)/6 | +--------------------+------------------------+ | 1.562500 | 1.041667 | +--------------------+------------------------+ 1 row in set (0.00 sec)

COUNT Syntaxe COUNT([DISTINCT] expression) COUNT(*) Dans sa premire syntaxe, la fonction COUNT compte le nombre de fois o expression nest pas NULL. Avec le mot cl DISTINCT,lafonctioncomptelenombredevaleursdistinctesdeexpression,enignorantlavaleurNULL. Danssadeuximesyntaxe,lafonctionCOUNTcomptelenombretotaldelignes. Exemple mysql> SELECT frais_ht FROM collection; +----------+ | frais_ht | +----------+ | 1.50 | | NULL | | 1.50 | | 2.00 | | 1.25 | | NULL | +----------+ 6 rows in set (0.01 sec) mysql> SELECT -> COUNT(*), -> COUNT(frais_ht),

- 2-

ENI Editions - All rigths reserved

-> COUNT(DISTINCT frais_ht) -> FROM collection; +----------+-----------------+--------------------------+ | COUNT(*) | COUNT(frais_ht) | COUNT(DISTINCT frais_ht) | +----------+-----------------+--------------------------+ | 6 | 4 | 3 | +----------+-----------------+--------------------------+ 1 row in set (0.00 sec)

ENI Editions - All rigths reserved

- 3-

Creretsupprimerunebasededonnes
LordreSQLCREATE DATABASEpermetdecrerunenouvellebasededonnes. Syntaxe CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] nom_base nom_baseestlenomdelanouvellebasededonnes.CenomdoitrespecterlesrglesdenommagedesobjetsMySQL. CREATE SCHEMA est un synonyme de CREATE DATABASE (depuis la version 5, une base de donnes est aussi appele "schma"). Une erreur se produit si une base de donnes de mme nom existe dj et que la clause IF NOT EXISTS nest pas prsente. Pourcrerunebasededonnes,ilfautleprivilgeglobalCREATE. Physiquement,unebasededonnesMySQLsematrialiseparunrpertoirequicontiendralesfichierscorrespondant auxdiffrentestablesdelabasededonnes. Exemple mysql> CREATE DATABASE biblio; Query OK, 1 row affected (0.00 sec) LordreSQLDROP DATABASEpermetdesupprimerunebasededonnes. Syntaxe DROP {DATABASE | SCHEMA} [IF EXISTS] nom_base DROP SCHEMAestunsynonymedeDROP DATABASE. UneerreurseproduitsilabasededonnesnexistepasetquelaclauseIF EXISTSnestpasprsente. Poursupprimerunebasededonnes,ilfautleprivilgeglobalDROP. ordre DROP DATABASE supprime tout, sans demander de confirmation. Il faut y rflchir deux fois avant L dexcutercettecommande !

ENI Editions - All rigths reserved

- 1-

Grerlesutilisateursetlesdroits
1.Vuedensemble
LorsdelinstallationdeMySQL,uncomptesuperutilisateurnommrootestautomatiquementcr. LecompterootestnormalementrservladministrationduserveurMySQL. Encomplmentducompteroot,ilestdoncconseilldecrerauminimumuncompteparapplicationetventuellementuncompteparutilisateur finaldelapplication.Decettemanire,ilserapossibledegrertrsfinementlesdroitsattribuschaqueutilisateur/applicationetdelimiterles risqueslislutilisationducompteroot. DansMySQL,unutilisateurestidentifidemanireuniqueparlacombinaisondedeuxinformations :
q

unnomdutilisateur unnomdhte(ouadresseIP)partirduquellutilisateurpeutseconnecter.

Chaquecoupleutilisateur/hteestconsidrparMySQLcommeunutilisateuruniquequiaunmotdepassepourseconnecter(ventuellement aucun)etdesdroits.Unmmeutilisateur(ausensdunnomdutilisateurdonn)peutdoncavoirdesdroitsdiffrentsselonlhtepartirduquelil seconnecte. Lasyntaxeutilisepourdsignerunutilisateurestdonclasuivante : nom_utilisateur[@nom_hte] Pour le nom dhte, la valeur % signifie "nimporte quel hte" cest la valeur par dfaut utilise lorsque le nom dhte nest pas spcifi. Le caractre % peut aussi tre utilis comme caractre joker dans le nom dhte ou ladresse IP pour spcifier une liste de machine (oheurtel@%.olivier-heurtel.fr) ou une plage dadresses IP ( oheurtel@192.168.1.%). Le nom dutilisateur peut tre vide (utilisateur anonyme). Il est possible davoir un utilisateur nom_utilisateur@% qui peut se connecter partir de nimporte quelle machine avec certains droits et un "autre"utilisateur nom_utilisateur@nom_hoteayantlemmenom,maispouvantseconnecterpartidunemachineavecdesdroitsdiffrents(par exempleplusrestrictifssilamachineestconsidrecommepeusre,oumoinsrestrictifssilamachineestconsidrecommetrssre). orsquun utilisateur se connecte localement (directement sur le serveur), cest le nom dhte localhost qui est utilis dans son L identification cenomdhtenestpasconsidrcommefaisantpartiede"tousleshtes"dfinipar%.Siunutilisateurestautorisse connecter partir de nimporte quelle machine, y compris le serveur, il faudra crer 2 comptes : xxxx@% et xxxx@localhost (et grer correctementlesdroitssurlesdeuxcomptes). Lesinformationssurlesutilisateursetleursdroitssontstocksdanslabasededonnesmysql : Table Contenu Listedesutilisateursavecleursprivilgesglobaux(privilgesqui sappliquentauserveurMySQLettouteslesbasesdedonnesdu serveur). Listedesprivilgesdeniveaubasededonnesattribusaux utilisateurs. Listedesprivilgesdeniveauobjetattribusauxutilisateurs.

user

dbethost

tables_priv,columns_privetprocs_priv

ourgrerlesutilisateursetlesdroits,ilfautdesprivilgesglobauxprcis(CREATE USER,GRANT OPTION,etc.).Pardfaut,cesprivilgessont P attribusaucompte root,puisquecederniertouslesdroits.Danslasuite,noussupposeronsquelagestiondesutilisateursetdesdroits esteffectuelaide du compte root et nous ne prciserons pas quel droit est requis pour effectuer telle action. Pour en savoir plus sur ce sujet,reportezvousladocumentationMySQL.

2.Grerlesutilisateurs
a.Crerdesutilisateurs
Avantlaversion5.0.2,unnouvelutilisateurtaitcrimplicitementparattributiondunpremierdroitlaidedelordreSQLGRANT(voirciaprs). Depuislaversion5.0.2,lordreSQLCREATE USERpermetdecrerexplicitementunutilisateur. Syntaxe CREATE USER spcification_utilisateur [,...] spcification_utilisateur = nom_utilisateur[@nom_hte] [IDENTIFIED BY [PASSWORD] mot_de_passe]

ENI Editions - All rigths reserved

- 1-

nom_utilisateuret mot_de_passesontrespectivementlenometlemotdepassedunouveaucompte.Silaclause IDENTIFIED BYestabsente,le compteestcrsansmotdepasse. nom_htepermetdespcifierlenomdelamachinepartirdelaquellelenouvelutilisateurpeutseconnecter.Sicetteclauseestomise,lavaleur pardfaut%estutilise danscecas,lutilisateurpeutseconnecterpartirdenimportequelhte. Silemotcl PASSWORDestomis,lemotdepassedoittresaisienclair ilseraautomatiquementchiffr(hach)parMySQLlaidedelafonction PASSWORD avant dtre stock dans la base mysql. Si le mot cl PASSWORD est prsent, il faut saisir un mot de passe dj chiffr (nombre hexadcimalde41chiffres). Exemple mysql> CREATE USER eniadm IDENTIFIED BY eni; Query OK, 0 rows affected (0.01 sec) mysql> CREATE USER oheurtel@localhost IDENTIFIED BY oh; Query OK, 0 rows affected (0.00 sec) mysql> SELECT host,user,password FROM mysql.user; +-----------+----------+-------------------------------------------+ | host | user | password | +-----------+----------+-------------------------------------------+ | localhost | root | | | linux | root | | | localhost | | | | linux | | | | localhost | pma | | | localhost | eniweb | *7F3BF7031A324F9FA79930B44A098C84FA3FBB97 | | % | eniadm | *EF068FAEFCC1D0D291B52D66CA1CAD5D3B1546F1 | | localhost | oheurtel | *BE6735F99EBE04720DC10FB173FF7E76A881E16F | +-----------+----------+-------------------------------------------+ 8 rows in set (0.01 sec) mysql> exit Bye [root@xampp ~]# m y s q l - u e n i a d m - p Enter password: ERROR 1045 (28000): Access denied for user eniadm@localhost (using password: YES) Cetexempleillustrelepointexpliquprcdemment:lhte localhost nestpasconsidrcommefaisantpartiede"tousleshtes"dfinipar %. Lutilisateur ainsi cr ne peut pas se connecter partir du serveur (par contre, il peut se connecter partir de nimporte quelle autre machine). Pourrsoudreceproblme,ilestpossibledecrerun"deuxime"utilisateur. Exemple mysql> CREATE USER eniadm@localhost IDENTIFIED BY eni; Query OK, 0 rows affected (0.01 sec) mysql> SELECT host,user,password -> FROM mysql.user WHERE user = eniadm; +-----------+--------+-------------------------------------------+ | host | user | password | +-----------+--------+-------------------------------------------+ | localhost | eniadm | *EF068FAEFCC1D0D291B52D66CA1CAD5D3B1546F1 | | % | eniadm | *EF068FAEFCC1D0D291B52D66CA1CAD5D3B1546F1 | +-----------+--------+-------------------------------------------+ 2 rows in set (0.00 sec) mysql> exit Bye [root@xampp ~]# m y s q l - u e n i - p Enter password: Welcome to the MySQL monitor. ...

Commands end with ; or \g.

Ce"deuxime"utilisateurauraitputrecravecunmotdepassediffrent(ventuellementsansmotdepasse).

b.Supprimerdesutilisateurs
Avantlaversion4.1.1,unutilisateurtaitsupprimparun DELETEdirectementdanslatable mysql.user,aprsrvocationdetoussesdroits laidedelordreSQLREVOKE(voirciaprs). Depuislaversion4.1.1,lordreSQLDROP USERpermetdesupprimerexplicitementunutilisateur. Syntaxe DROP USER nom_utilisateur[@nom_hte[,...] Silenomdhteestomis,lavaleurpardfaut%estutilise. Lorsdelasuppressiondunutilisateur,lesdroitsdelutilisateursontaussisupprims parcontre,lesobjetsventuelscrsparlutilisateurne

- 2-

ENI Editions - All rigths reserved

sontpassupprims.

c.Modifierlemotdepassedesutilisateurs
LordreSQLSET PASSWORDpermetdemodifierlemotdepassedunutilisateur. Syntaxe SET PASSWORD [FOR nom_utilisateur[@nom_hte]] = PASSWORD(nouveau_mot_de_passe_en_clair) | nouveau_mot_de_passe_hach Silenomdhteestomis,lavaleurpardfaut%estutilise. SilaclauseFORestomise,cettecommandepermetdemodifierlemotdepassedelutilisateurcourant. LafonctionPASSWORDappliqueaunouveaumotdepassesaisienclairpermetdelechiffrer(hacherplusprcisment)avantsonstockagedans labasededonnesmysql.Lemotdepassedjhachpeuttresaisidirectementdanslacommande. Exemple mysql> SET PASSWORD FOR eniadm = PASSWORD(secret); Query OK, 0 rows affected (0.00 sec) mysql> SELECT host,user,password -> FROM mysql.user WHERE user = eniadm; +-----------+--------+-------------------------------------------+ | host | user | password | +-----------+--------+-------------------------------------------+ | % | eniadm | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | | localhost | eniadm | *EF068FAEFCC1D0D291B52D66CA1CAD5D3B1546F1 | +-----------+--------+-------------------------------------------+ 2 rows in set (0.00 sec) mysql> SELECT PASSWORD(secret); +-------------------------------------------+ | PASSWORD(secret) | +-------------------------------------------+ | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | +-------------------------------------------+ 1 row in set (0.00 sec) mysql> SET PASSWORD FOR eniadm@localhost = -> *14E65567ABDB5135D0CFD9A70B3032C179A49EE7; Query OK, 0 rows affected (0.00 sec) mysql> SELECT host,user,password -> FROM mysql.user WHERE user = eniadm; +-----------+--------+-------------------------------------------+ | host | user | password | +-----------+--------+-------------------------------------------+ | % | eniadm | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | | localhost | eniadm | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | +-----------+--------+-------------------------------------------+ 2 rows in set (0.00 sec)

3.Grerlesdroitsdesutilisateurs
a.Attribuerdesdroitsauxutilisateurs
LordreSQLGRANTpermetdattribuerdesdroitsauxutilisateurs. Syntaxesimplifie GRANT privilge,[,...] ON spcification_cible TO spcification_utilisateur [,...] spcification_cible = *.* | [nom_base.]* | [TABLE | FUNCTION | PROCEDURE] [nom_base.]nom_objet spcification_utilisateur = nom_utilisateur[@nom_hte] [IDENTIFIED BY [PASSWORD] mot_de_passe] Laclause spcification_utilisateurestlammequepourlordre CREATE USER.Silutilisateur(ausenscoupleutilisateur/hte)nexistepas,il estautomatiquementcr,avecousansmotdepasseselonquelaclauseIDENTIFIED BYestprsenteoupas. Lesprivilgespeuventtreattribustroisniveaux :

ENI Editions - All rigths reserved

- 3-

Global Lesprivilgesattribusauniveauglobalsappliquenttouteslesbasesdedonnesduserveur.Pourattribuerunprivilgeauniveauglobal,il faututiliserlavaleur*.*pourlaclausespcification_cible. Basededonnes Lesprivilgesattribusauniveaubasededonnessappliquenttouslesobjetsdunebasededonnes.Pourattribuerunprivilgeauniveau basededonnes,ilfaututiliserlavaleur[nom_base].*pourlaclausespcification_cible.Sinom_baseestomis,lesdroitssontattribuspourla basededonnescourante. Objet Les privilges attribus au niveau objet sappliquent un objet dune base de donnes : table, vue, programme stock. Pour attribuer un privilgeauniveauobjet,ilfaututiliserlavaleur [TABLE | FUNCTION | PROCEDURE] [nom_base.]nom_objetpourlaclause spcification_cible.Si nom_baseestomis,lobjetestrecherchdanslabasededonnescourante.LemotclTABLE,FUNCTIONouPROCEDUREpermetdeprciserlanature delobjetconcern pourattribuerundroitsurunetableouunevue,lemotclTABLEpeuttreomis(cestlavaleurpardfaut). privilgeestunnomdeprivilge.Lesprivilgeslesplussouventutilisssontlessuivants : Nom Signification Niveau(1) G Touslesdroits applicablespourle niveauconcern. Autoriselamodification destables(ordreALTER TABLE).Auniveauglobal oubasededonnes, autoriseaussila modificationdunebase dedonnes(ordre ALTER DATABASE). Autoriselamodification oulasuppressiondes programmesstocks (ordres{ALTER | DROP} {FUNCTION | PROCEDURE}). Autoriselacrationdes tables(ordreCREATE TABLE).Auniveauglobal oubasededonnes, autoriseaussila crationdunebasede donnes(ordreCREATE DATABASE). Autoriselacrationdes programmesstocks (ordresCREATE {FUNCTION | PROCEDURE}). Autoriselacrationdes tablestemporaires (ordreCREATE TEMPORARY TABLE). Autoriselagestiondes utilisateurs(ordres {CREATE | DROP | RENAME} USER), Autoriselacrationdes vues(ordreCREATE VIEW). Autoriselasuppression delignesdansles tables(ordreDELETE), Autoriselasuppression destablesetdesvues (ordreDROP {TABLE | VIEW}).Auniveauglobal oubasededonnes, B O

ALL [PRIVILEGES]

ALTER

ALTER ROUTINE

CREATE

CREATE ROUTINE

CREATE TEMPORARY TABLES

CREATE USER

CREATE VIEW

DELETE

DROP

- 4-

ENI Editions - All rigths reserved

autoriseaussila suppressiondunebase dedonnes(ordreDRUP DATABASE). Autoriselexcutiondes programmesstocks (ordreCALLouappel dunefonctionstocke). Autoriseles dchargementset chargementsde donnes(ordres SELECT ... INTO OUTFILEetLOAD DATE INFILE). Autoriselattributionet larvocationdes privilges(ordresGRANT etREVOKE). Autoriselacrationetla suppressiondesindex (ordres{CREATE | DROP} INDEX). Autoriselinsertionde lignesdanslestables (ordreINSERT). Autoriseleverrouillage destables(ordreLOCK TABLES).Ncessiteaussi leprivilgeSELECTsur lestables. Autoriselaslectionde lignesdanslestables (ordreSELECT). Autoriselaffichagedela listedesbasesde donnes(ordreSHOW DATABASES). Autoriselaffichagedela dfinitiondunevue (ordreSHOW CREATE VIEW). Autoriselacrationetla suppressiondes triggers(ordres{CREATE | DROP} TRIGGER). Autoriselamodification delignesdansles tables(ordreUPDATE).

EXECUTE

FILE

GRANT OPTION

INDEX

INSERT[(nom_colonne [,...])]

LOCK TABLES

SELECT[(nom_colonne [,...])]

SHOW DATABASES

SHOW VIEW

TRIGGER

UPDATE[(nom_colonne [,...])]

(1)G=niveauglobalB=niveaubasededonnesO=niveauobjet L orsquaucunprivilgedeniveauglobalnestattribuunutilisateur,cedernieraleprivilgepardfautUSAGE.

LorsquelesprivilgesSELECT,INSERTouUPDATEsontattribussurunetableousurunevue(niveauobjet),ilestpossiblederestreindreledroit unelistedecolonnes seuleslescolonnesmentionnespourronttrelues,insresoumodifies. LacommandeSHOW PRIVILEGESaffichelalistedetouslesprivilgessupportsparMySQL.

Exemples mysql> -- Lutilisateur "eniadm" est ladministrateur de mysql> -- la base "eni" : il a tous les droits sur cette base. mysql> GRANT ALL ON eni.* TO eniadm,eniadm@localhost; Query OK, 0 rows affected (0.00 sec) mysql> -- Lutilisateur "eniadm" a aussi le droit de lire mysql> -- les donnes de la table "rubrique" de la base "demo".

ENI Editions - All rigths reserved

- 5-

mysql> GRANT SELECT ON demo.rubrique TO eniadm,eniadm@localhost; Query OK, 0 rows affected (0.00 sec) mysql> -- Lutilisateur "oheurtel" est un utilisateur de mysql> -- la base "eni" : il a uniquement les droits de mysql> -- lire et mettre jour les donnes, et dexcuter mysql> -- les programmes stocks. mysql> GRANT SELECT,INSERT,UPDATE,DELETE,EXECUTE ON eni.* -> TO oheurtel@localhost; Query OK, 0 rows affected (0.00 sec) mysql> -- Donnons aussi lutilisateur "oheurtel" le droit mysql> -- de charger et dcharger des donnes. mysql> GRANT FILE ON *.* TO oheurtel@localhost; Query OK, 0 rows affected (0.00 sec) UnutilisateurnapasbesoinduprivilgeSHOW DATABASESpourlisterlesbasesdedonnespourlesquellesilaunprivilgequelconque. Parailleurs,lorsquunutilisateurlistelestableslaidedelordreSHOW TABLES,ilnevoitquelestablessurlesquellesilaaumoinsundroit.

b.Listerlesdroitsdunutilisateur
LordreSQLSHOW GRANTSpermetdelisterlesdroitsdunutilisateur. Syntaxe SHOW GRANTS [FOR nom_utilisateur[@nom_hte]] SilaclauseFORestomise,lacommandelistelesdroitsdelasessioncourante. Exemple mysql> SHOW GRANTS FOR oheurtel@localhost; +--------------------------------------------------------------------------------------------------------------+ | Grants for oheurtel@localhost | +--------------------------------------------------------------------------------------------------------------+ | GRANT FILE ON *.* TO oheurtel@localhost IDENTIFIED BY PASSWORD *BE6735F99EBE04720DC10FB173FF7E76A881E16F| | GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON `eni`.* TO oheurtel@localhost | +--------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec) Commevouspouvezleconstatersurcetexemple,lesdroitssontaffichssouslaformedunelistedecommandesdattributiondeprivilges. Pouravoiruneprsentationdiffrente,ilfautinterrogerdirectementlestablesdelabasemysql.

c.Rvoquerdesdroitsdunutilisateur
LordreSQLREVOKEpermetdervoquerdesdroitsdunutilisateur. Syntaxe1 REVOKE privilge,[,...] ON spcification_cible FROM nom_utilisateur[@nom_hte][,...] spcification_cible = *.* | [nom_base.]* | [TABLE | FUNCTION | PROCEDURE] [nom_base.]nom_objet spcification_ciblealammesignificationquepourlordreSQLGRANT. Syntaxe2 REVOKE ALL PRIVILEGES, GRANT OPTION FROM nom_utilisateur[@nom_hte][,...] Cettedeuximesyntaxepermetdervoquerfacilementtouslesdroitsdunutilisateur,touslesniveaux(global,basededonnesetobjet). ySQL ne supprime pas automatiquement les privilges lorsquune table, une vue ou une base de donnes est supprime. Par contre, M lorsquunprogrammestockestsupprim,lesprivilgesattribussurleprogrammesontsupprims.Lorsquunutilisateurestsupprim, lesprivilgesquiluitaientattribussontsupprims. Exemple mysql> -- Finalement, lutilisateur "oheurtel" na plus le droit mysql> -- de charger et dcharger des donnes. mysql> REVOKE FILE ON *.* FROM oheurtel@localhost; Query OK, 0 rows affected (0.00 sec) mysql> SHOW GRANTS FOR oheurtel@localhost;

- 6-

ENI Editions - All rigths reserved

+--------------------------------------------------------------------------------------------------------------+ | Grants for oheurtel@localhost | +--------------------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO oheurtel@localhost IDENTIFIED BY PASSWORD *BE6735F99EBE04720DC10FB173FF7E76A881E16F| | GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON `eni`.* TO oheurtel@localhost | +--------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec)

ENI Editions - All rigths reserved

- 7-

Grerlestables
1.Crerunetable
LordreSQLCREATE TABLEpermetdecrerunenouvelletable. Syntaxesimplifie CREATE [TEMPORARY] TABLE [IF NOT EXISTS] nom_table ( spcification_colonne , ... ) [ENGINE|TYPE[=] moteur] spcification_colonne = nom_colonne type_colonne [ option_colonne ] option_colonne = [NOT NULL | NULL] [DEFAULT valeur] [AUTO_INCREMENT] [[PRIMARY] KEY] [UNIQUE [KEY]] Exemplesimple mysql> CREATE TABLE evenement -> ( -> id INT, -> nom VARCHAR(20) -> ); Query OK, 0 rows affected (0.00 sec) mysql> DESC evenement; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | nom | varchar(20) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) Le nom de la nouvelle table doit respecter les rgles de nommage des identifiants MySQL. Par dfaut, la table est stocke dans la base de donnes courante le nom de la table peut tre de la forme nom_base.nom_table pour la stockerdansuneautrebasededonnes. Le mot cl TEMPORARY indique que la table est temporaire. Une table temporaire nest visible que dans la connexion couranteetestautomatiquementsupprimelorsquelatransactioncourantesetermine.Deuxconnexionsdiffrentes peuventutiliserlemmenomdetabletemporairesansconflit. LaclauseIF NOT EXISTSpermetdviterdobteniruneerreursiunetabledemmenomexiste(lastructuredelatable nestpasvrifiepoursavoirsilsagiteffectivementdelammetable). La clause optionnelle ENGINE (anciennement TYPE) permet de dfinir le moteur de stockage utilis pour la table. Le moteurdterminelamaniredontlesdonnessontstockesetquellesoprationssontautorisessurlesdonnes. Lesmoteursdestockagelesplusutilisssontlessuivants : ARCHIVE Moteurquistockelesdonnesdansunformatcompress.Cemoteurestintressantpourlestablesvolumineuses maislacompression/dcompressionralentitlesoprationsdelectureoudemisejour. MEMORY(anciennementHEAP) Moteurquistockelesdonnesenmmoire.Cemoteuresttrsintressantpourlestablestemporaires(maisles donnessontperdueslorsqueleserveursarrte). InnoDB

ENI Editions - All rigths reserved

- 1-

Moteurpermettantdegrerlesclstrangres(cf.danscechapitreUtiliserlesclsetlesindexCltrangre)ainsi quelestransactionsetleverrouillagedeniveauligne(cf.chapitreTechniquesavancesavecMySQLGrerles transactionsetlesaccsconcurrents).PourautoriserlutilisationdestablesInnoDB,ilfautmettreencommentairele paramtreskip-innodbdanslefichierdeconfigurationdeMySQL. MyISAM Moteurutilispardfaut.Cemoteuresttrsperformantmaisilnegrepaslestransactions. haque moteur possde ces propres paramtres dans le fichier de configuration de MySQL (voir la C documentation).Lacommande SHOW ENGINESpermetdevoirquelssontlesmoteursdisponiblesdansleserveur MySQL. Si un moteur est spcifi mais que celuici nest pas disponible, MySQL utilise le moteur par dfaut (normalementMyISAM)etgnreunealerte(pasuneerreur). Chaque colonne de la table est dfinie avec au minimum un nom de colonne et un type de donnes. Le nom de la colonnedoitrespecterlesrglesdenommagedesidentifiantsMySQL.Letypededonnesdoittreundestypesde donnesprsentauchapitreIntroductionMySQL. Encomplment,chaquecolonnepeutavoirunouplusieursdesattributssuivants : NOT NULL | NULL NOT NULLindiquequelacolonneestobligatoire(ellenacceptepaslesvaleursNULL).LavaleurpardfautestNULL :la colonneacceptelesvaleursNULL. DEFAULT valeur Cetteclausepermetdedfinirlavaleurpardfautdelacolonne cettevaleurestinsreautomatiquementdansla colonnelorsquecettedernirenestpasprsentedansunINSERT(oulorsquelemotclDEFAULTestutiliscomme valeurlorsdunINSERToudunUPDATE).Lavaleurdoittreuneconstante utiliserunefonctionestinterdit.Cette clausenestpasautorisepourunecolonnedetypeBLOBouTEXT.SilaclauseDEFAULTestomise,lecomportementde MySQLdpenddumodeSQLactif(voirciaprs). AUTO_INCREMENT CetteclauseindiquequeMySQLdoitinsrerunevaleurentireuniquedanslacolonnelorsdelinsertion,siaucune valeurautrequeNULLou0nestaffectelacolonne.Lanumrotationcommence1etlavaleurautomatiquement insreestgalelavaleurlaplusgrandeactuellementstockedanslacolonneplusun.Lesrestrictionssuivantes sappliquentlorsquunecolonneestdetypeAUTO_INCREMENT :
q

Uniquementpourlescolonnesdetypeentier Uneseulecolonnedecetypepartable ClauseDEFAULTinterdite Lacolonnedoittreindexe(cequiestgnralementlecascarlescolonnesdecetypesontsouventdfinies commeclprimaire)

a valeur automatiquement insre dans une colonne AUTO_INCREMENT peut tre rcupre grce la fonction L LAST_INSERT_ID(cf.chapitreUtiliserlesfonctionsMySQLFonctionssystme).

[PRIMARY] KEY Cetteclauseindiquequelacolonneestlaclprimairedelatable(cf.UtiliserlesclsetlesindexClprimaireou uniquedecechapitrepourplusdinformations). UNIQUE [KEY] Cetteclauseindiquequelacolonneestuneclunique(cf.UtiliserlesclsetlesindexClprimaireouuniquedece chapitrepourplusdinformations). Siaucunevaleurpardfautnestdfinieexplicitementpourunecolonneetquelacolonneautoriselesvaleurs NULL,la

- 2-

ENI Editions - All rigths reserved

valeurNULLestdfiniecommevaleurpardfaut.Parcontre,silacolonneestobligatoire,lefonctionnementdpenddu modeSQLactif :
q

SilemodeSQLstrictnestpasactif(caspardfaut),MySQLutilisesaproprevaleurpardfautlieautypede donnes :0pourunnombre,chanevidepourunechane,date"zro"pourunedate. SilemodeSQLstrictestactif,uneerreurseproduit.

iaucunevaleurpardfautnestspcifiepourlapremirecolonnedetype TIMESTAMPdunetable,MySQLen S dfinituneautomatiquementgaleCURRENT_TIMESTAMP(fonctionquidonneladate/heureactuellecf.chapitre UtiliserlesfonctionsMySQLFonctionsdates). Exemple mysql> CREATE TABLE utilisateur -> ( -> id INT PRIMARY KEY AUTO_INCREMENT, -> nom VARCHAR(40) NOT NULL, -> prenom VARCHAR(40) NOT NULL, -> mail VARCHAR(200) NOT NULL UNIQUE KEY, -> mot_de_passe BLOB NOT NULL, -> est_actif BOOLEAN NOT NULL DEFAULT TRUE, -> date_maj TIMESTAMP -> ); Query OK, 0 rows affected (0.02 sec) mysql> DESC utilisateur; +--------------+--------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+-------------------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | nom | varchar(40) | NO | | | | | prenom | varchar(40) | NO | | | | | mail | varchar(200) | NO | UNI | | | | mot_de_passe | blob | NO | | | | | est_actif | tinyint(1) | NO | | 1 | | | date_maj | timestamp | NO | | CURRENT_TIMESTAMP | | +--------------+--------------+------+-----+-------------------+----------------+ 7 rows in set (0.01 sec)

2.Crerunetableparcopie
LordreSQLCREATE TABLEpossdedeuxvariantesquipermettentdecrerunetable,soitparcopieduneautretable, soitparcopiedursultatdunerequteSELECT. Copieduneautretable Syntaxe CREATE [TEMPORARY] TABLE [IF NOT EXISTS] nom_table { LIKE nom_autre_table | (LIKE nom_autre_table) } Cette commande cre une table vide dont la dfinition est identique une autre table (y compris les attributs des colonnesetlesindexdfinissurlatabledorigine). Exemple mysql> CREATE TABLE responsable_collection LIKE auteur; Query OK, 0 rows affected (0.00 sec) mysql> DESC responsable_collection; +--------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+----------------+

ENI Editions - All rigths reserved

- 3-

| id | int(11) | NO | PRI | NULL | auto_increment | | nom | varchar(40) | NO | MUL | | | | prenom | varchar(40) | NO | | | | | mail | varchar(200) | YES | | NULL | | | tel_bureau | varchar(10) | YES | | NULL | | | tel_portable | varchar(10) | YES | | NULL | | | tel_domicile | varchar(10) | YES | | NULL | | | mot_de_passe | blob | YES | | NULL | | | profil | blob | YES | | NULL | | +--------------+--------------+------+-----+---------+----------------+ 9 rows in set (0.00 sec)

CopiedursultatdunerequteSELECT Syntaxe CREATE [TEMPORARY] TABLE [IF NOT EXISTS] nom_table [( spcification_colonne [,...])] [ENGINE|TYPE[=] moteur] [IGNORE | REPLACE] [AS] requte_SELECT Laclauseoptionnelle spcification_colonnepermetdedfinirexplicitementdescolonnesdelanouvelletable.Dans cetteclause,lescolonnessontdfiniesaveclammesyntaxequedanslordre CREATE TABLEprsentdanslasection prcdente. Si la clause spcification_colonnes est omise, la table est cre avec la structure correspondant au rsultat de la requteSELECTetlersultatdelarequteSELECTestinsrdanslanouvelletable. Si la clause spcification_colonnes est prsente, la structure correspondant au rsultat de la requte SELECT est ajouteladfinitiondelatableetlersultatdelarequteSELECTestinsrdanslanouvelletable,aveclesvaleurs pardfautaffectesauxcolonnesexplicitementdfinies.Lalistedescolonnesexplicitementdfiniespeutcomporter une colonne de mme nom quune colonne de la requte SELECT dans ce cas, cette colonne est alimente par la colonnehomonymedelarequteSELECT(lacolonneconserveletypededonnesquiluiatexplicitementattribu). P ensezutiliserdesaliasdecolonnespourlesexpressionsdelarequteSELECT.

Danslesdeuxcas,lanouvelletableestcresanscl(primaireouunique)etsansindex. SilaclauseIF NOT EXISTSestprsenteetquunetabledemmenomexistedj,lersultatdelarequte SELECTest quand mme insr dans la table. Dans ce cas, si une ligne insre provoque un doublon dans une cl primaire ou unique,uneerreurestretourne,saufsilaclauseoptionnelleIGNOREouREPLACEestutilise :IGNOREpermetderejeter leslignesquiprovoqueundoublonetREPLACEpermetderemplacerlancienneligneparlanouvelle. Exemple mysql> CREATE TABLE categorie(id INT PRIMARY KEY AUTO_INCREMENT) -> AS SELECT titre nom FROM rubrique WHERE id_parent IS NULL; Query OK, 5 rows affected (0.02 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql> DESC categorie; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | nom | varchar(20) | NO | | | | +-------+-------------+------+-----+---------+----------------+ 2 rows in set (0.00 sec) mysql> SELECT * FROM categorie; +----+-----------------+ | id | nom | +----+-----------------+ | 1 | Base de donnes | | 2 | Dveloppement | | 3 | Internet | | 4 | Open Source |

- 4-

ENI Editions - All rigths reserved

| 5 | Certification | +----+-----------------+ 5 rows in set (0.00 sec)

3.Renommerunetable
LordreSQLRENAME TABLEpermetderenommerunetable. Syntaxe RENAME TABLE ancien_nom TO nouveau_nom Exemple mysql> RENAME TABLE utilisateur TO client; Query OK, 0 rows affected (0.00 sec) Avec cette syntaxe, il est possible de dplacer une table dune base une autre, sous rserve davoir les droits suffisants. Unevariantedecettesyntaxepermetderenommerplusieurstablesenuneseulecommande(unanciennompouvant mmetoutdesuitetrerutilis). Syntaxe RENAME TABLE a TO temp, b TO a, temp TO b; UnetablepeutaussitrerenommeparunordreALTER TABLE. Syntaxe ALTER TABLE ancien_nom RENAME [AS | TO] nouveau_nom

4.Modifierlastructuredunetable
LordreSQLALTER TABLEpeuttreutilispourmodifierlastructuredunetable.Cetordrepermetnotamment :
q

Dajouterdescolonnes Desupprimerdescolonnes Demodifierlesattributsdescolonnes.

acommande ALTER TABLEoffredautrespossibilits(modifierlemoteurdunetablenotamment).Pourensavoir L plus,consultezladocumentationMySQL.

Ajouteruneouplusieurscolonnes Syntaxe ALTER TABLE nom_table ADD [COLUMN] spcification_colonne [FIRST | AFTER nom_colonne] ALTER TABLE nom_table ADD [COLUMN] ( spcification_colonne [,...]) La clause spcification_colonne permet de dfinir les caractristiques des colonnes ajoutes dans la table. La syntaxeestlammequedanslordreCREATE TABLE. La premire syntaxe permet dajouter une seule colonne, ventuellement un endroit prcis spcifi par la clause FIRSTouAFTER pardfaut,lacolonneestajoutelafindelatable. Ladeuximesyntaxepermetdajouterplusieurscolonnes,lafindelatable.

ENI Editions - All rigths reserved

- 5-

Exemple mysql> ALTER TABLE evenement ADD -> ( -> date_debut DATE, -> date_fin DATE, -> id_collection INT DEFAULT 1, -> pays VARCHAR(50) -> ); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> DESC evenement; +---------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | nom | varchar(20) | YES | | NULL | | | date_debut | date | YES | | NULL | | | date_fin | date | YES | | NULL | | | id_collection | int(11) | YES | | 1 | | | pays | varchar(50) | YES | | NULL | | +---------------+-------------+------+-----+---------+-------+ 6 rows in set (0.01 sec) Si une colonne AUTO_INCREMENT est ajoute une table qui contient des donnes, la colonne est automatiquement alimentepardesnombrespartirde1. Si une colonne ayant une clause DEFAULT est ajoute une table qui contient des donnes, la colonne est automatiquementalimenteaveclavaleurpardfaut. SiunecolonneNOT NULLestajouteunetablequicontientdesdonnes,lacolonneestautomatiquementalimente aveclavaleurpardfautdelacolonne(valeurpardfautimplicitesiaucuneclauseDEFAULTexplicitenestdfinie). Supprimerunecolonne Syntaxe ALTER TABLE nom_table DROP [COLUMN] nom_colonne Exemple mysql> ALTER TABLE evenement DROP id_collection; Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> DESC evenement; +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | nom | varchar(20) | YES | | NULL | | | date_debut | date | YES | | NULL | | | date_fin | date | YES | | NULL | | | pays | varchar(50) | YES | | NULL | | +------------+-------------+------+-----+---------+-------+ 5 rows in set (0.00 sec) Silacolonnefaitpartiedunindex,elleestaussisupprimedelindex sictaitlaseulecolonnedelindex,lindexest supprim. Modifierousupprimerlavaleurpardfautdunecolonne Syntaxe ALTER TABLE nom_table ALTER [COLUMN] nom_column {SET DEFAULT valeur | DROP DEFAULT}

- 6-

ENI Editions - All rigths reserved

Exemple mysql> ALTER TABLE evenement ALTER pays SET DEFAULT FRANCE; Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> DESC evenement; +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | nom | varchar(20) | YES | | NULL | | | date_debut | date | YES | | NULL | | | date_fin | date | YES | | NULL | | | pays | varchar(50) | YES | | FRANCE | | +------------+-------------+------+-----+---------+-------+ 5 rows in set (0.00 sec)

Modifierlesattributsdescolonnes Syntaxe ALTER TABLE nom_table CHANGE [COLUMN] ancien_nom_colonne nouveau_nom_colonne type_colonne [ option_colonne ] ALTER TABLE nom_table MODIFY [COLUMN] nom_colonne type_colonne [ option_colonne ] Lapremiresyntaxepermetdemodifierlesattributsdunecolonne,ycomprissonnom.Ladeuximesyntaxepermet demodifierlesattributsdunecolonneenconservantlemmenomdecolonne. Laclauseoption_colonnepermetdedfinirlesnouvellesoptionsdelacolonne(NOT NULL,DEFAULT,etc).Lasyntaxeest la mme que dans lordre CREATE TABLE. Si vous ne souhaitez pas modifier une option de la colonne, vous devez la remettrelidentiquedanslordreALTER TABLE,sinonloptionenquestionestsupprime. Exemple mysql> ALTER TABLE evenement CHANGE -> pays code_pays VARCHAR(50) DEFAULT FR; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> DESC evenement; +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | nom | varchar(20) | YES | | NULL | | | date_debut | date | YES | | NULL | | | date_fin | date | YES | | NULL | | | code_pays | varchar(50) | YES | | FR | | +------------+-------------+------+-----+---------+-------+ 5 rows in set (0.00 sec) mysql> ALTER TABLE evenement MODIFY -> code_pays CHAR(2) NOT NULL; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> DESC evenement; +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | nom | varchar(20) | YES | | NULL | | | date_debut | date | YES | | NULL | | | date_fin | date | YES | | NULL | | | code_pays | char(2) | NO | | | |

ENI Editions - All rigths reserved

- 7-

+------------+-------------+------+-----+---------+-------+ 5 rows in set (0.00 sec) mysql> ALTER TABLE evenement MODIFY id INT AUTO_INCREMENT; ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key LedernierexemplemontrequunecolonnenepeutpasavoirlattributAUTO_INCREMENTsiellenestpasindexe. Si une colonne devient obligatoire (NOT NULL), les valeurs NULL ventuellement prsentes dans la colonne sont remplacesparlavaleurpardfautimpliciteassocieautype. n cas de modification du type de donnes, MySQL tente de convertir les donnes aumieux vers le nouveau E type. Si la longueur dune colonne de type chane est diminue, les valeurs actuellement stockes dans la colonne sont ventuellement tronques pour sadapter la nouvelle longueur. De mme, si la longueur dune colonne numrique est diminue, les valeurs trop grandes actuellement stockes dans la colonne sont ventuellementremplacesparlavaleurmaximumpermiseparlanouvellelongueur.

5.Supprimerunetable
LordreSQLDROP TABLEpermetdesupprimerunetable(ouplusieurstables). Syntaxe DROP [TEMPORARY] TABLE [IF EXISTS] nom_table[,...] Lorsquunetableestsupprime,lesprivilgesattribusauxutilisateurssurcettetablenesontpassupprims. LaclauseIF EXISTSpermetdviterdobteniruneerreursiunetablesupprimernexistepas.

- 8-

ENI Editions - All rigths reserved

Utiliserlesclsetlesindex
1.Clprimaireouunique
a.Dfinition
Uneclprimaire(oucontraintedeclprimaire)garantitquilnyaurajamaisdeuxlignesdanslatablequiaurontla mmevaleurdansla(les)colonne(s)quicompose(nt)lacl.Parailleurs,touteslescolonnesdelaclprimairesont obligatoires(clauseNOT NULLimplicitepourlescolonnesconcernes).Uneseuleclprimaireestautorisepartable. Une cl unique (ou contrainte de cl unique) garantit quil ny aura jamais deux lignes dans la table qui auront la mme valeur dans la(les) colonne(s) qui compose(nt) la cl. la diffrence de la cl primaire, les colonnes qui composentlacluniquenesontpasforcmentobligatoires pourlescolonnesdelaclquinesontpasobligatoires, plusieurs lignes peuvent avoir la valeur NULL sans violer la contrainte. Plusieurs cls uniques sont autorises par table. Uneclprimaireouuniquepeuttreconstitueduneseulecolonneoudeplusieurscolonnes. Lorsduneinsertionoudunemodification,uneerreurseproduitsiunecl(primaireouunique)contientunevaleur quiexistedjdanslatable. es cls primaires et uniques sont des index particuliers qui imposent une contrainte dunicit. Un accs par L uneclprimaireouuniqueestdoncperformant.

b.Gestion
Une cl primaire ou unique constitue dune seule colonne peut tre dfinie directement dans les options de la colonne, lors du CREATE TABLE, ou lors dun ALTER TABLE ... {CHANGE|MODIFY} (voir la syntaxe de ces diffrents ordresdanslessectionsprcdentes). Sinon,dunemanireplusgnrale,uneclprimaireouunique,monocolonneoumulticolonne,peuttredclare paruneclausespcifiquededfinitiondecontrainte. Syntaxe [CONSTRAINT [nom_contrainte]] PRIMARY KEY (nom_colonne[,...]) [CONSTRAINT [nom_contrainte]] UNIQUE [INDEX|KEY] (nom_colonne[,...]) nom_contrainte est le nom attribu la contrainte. Pour une cl primaire, ce nom est ignor une cl primaire sappelle obligatoirement PRIMARY. Pour une cl unique, le nom par dfaut de la contrainte est gal au nom de la premirecolonnedelacl,avecsibesoinunsuffixe(_2,etc.)pourlunicit. Laclauseprcdentepeuttreutilisedansunordre CREATE TABLE,aprslalistedescolonnes,oudansunordre ALTER TABLE ... ADD. Exemple <$I[]CREATE TABLE;PRIMARY KEY>mysql> CREATE TABLE collection_evenement -> ( -> id_evenement INT, -> id_collection INT, -> PRIMARY KEY (id_evenement,id_collection) -> ); Query OK, 0 rows affected (0.00 sec) mysql> DESC collection_evenement; +---------------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------+---------+------+-----+---------+-------+ | id_evenement | int(11) | NO | PRI | 0 | | | id_collection | int(11) | NO | PRI | 0 | | +---------------+---------+------+-----+---------+-------+ 2 rows in set (0.01 sec)mysql> ALTER TABLE evenement ADD

ENI Editions - All rigths reserved

- 1-

-> ( -> CONSTRAINT pk_evenement PRIMARY KEY(id), -> CONSTRAINT uk_nom UNIQUE KEY(nom) -> ); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> -- Lattribut AUTO_INCREMENT peut maintenant tre mysql> -- affect la colonne "id". mysql> ALTER TABLE evenement MODIFY id INT AUTO_INCREMENT; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> DESC evenement; +------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | nom | varchar(20) | YES | UNI | NULL | | | date_debut | date | YES | | NULL | | | date_fin | date | YES | | NULL | | | code_pays | char(2) | NO | | | | +------------+-------------+------+-----+---------+----------------+ 5 rows in set (0.01 sec)mysql> ALTER TABLE auteur ADD -> UNIQUE KEY(nom,prenom); Query OK, 5 rows affected (0.01 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql> DESC auteur; +--------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | nom | varchar(40) | NO | MUL | | | | prenom | varchar(40) | NO | | | | | mail | varchar(200) | YES | | NULL | | | tel_bureau | varchar(10) | YES | | NULL | | | tel_portable | varchar(10) | YES | | NULL | | | tel_domicile | varchar(10) | YES | | NULL | | | mot_de_passe | blob | YES | | NULL | | | profil | blob | YES | | NULL | | +--------------+--------------+------+-----+---------+----------------+ 9 rows in set (0.00 sec)

ans une cl primaire ou unique dfinie sur une colonne de type chane, les espaces de fin de chane sont D ignors.Ainsi,lachaneabc estconsidrecommegalelachaneabc.

LordreSQLSHOW INDEXpermetdelisterlescls(etplusgnralementlesindex)dunetable. Syntaxe SHOW INDEX FROM nom_table [FROM nom_base] Exemple mysql> SHOW INDEXES FROM evenement; +-----------+------------+----------+--------------+------------+-----------+-------------+----------+--------+------+-----------+---------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | +-----------+------------+----------+--------------+------------+-----------+-------------+----------+--------+------+-----------+---------+ | evenement | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE

- 2-

ENI Editions - All rigths reserved

| | | evenement | 0 | uk_nom | 1 | nom | A | NULL | NULL | NULL | YES | BTREE | | +-----------+------------+----------+--------------+------------+-----------+-------------+----------+--------+------+-----------+---------+ 2 rows in set (0.00 sec) UneclprimaireouuniquepeuttresupprimeparunordreALTER TABLE ... DROP. Syntaxe ALTER TABLE nom_table DROP PRIMARY KEY ALTER TABLE nom_table DROP KEY nom_contrainte Exemple mysql> ALTER TABLE auteur DROP KEY nom; Query OK, 5 rows affected (0.04 sec) Records: 5 Duplicates: 0 Warnings: 0

2.Index
a.Dfinition
Unindexestunestructuredfiniesuruneclconstitueduneouplusieurscolonnesdunetable,etquipermetun accs rapide aux lignes de la table lors dune recherche base sur la cl de lindex. Cette structure est automatiquementmaintenueetutiliseparMySQL. Lorsquelacldelindexestcomposedeplusieurscolonnes,onparledindexcomposouconcatn. es cls primaires et uniques sont des index particuliers qui imposent une contrainte dunicit. Un accs par L uneclprimaireouuniqueestdoncperformant.

b.Gestion
Lesindexpeuventtrecrslorsdelacrationinitialedelatable(danslordreCREATE TABLE)ouultrieurement(par unordreALTER TABLEouunordreCREATE INDEX). LaclauseINDEXpermetdecrerunindexdansunordreCREATE TABLEouALTER TABLE. Syntaxe INDEX [nom_index] (nom_colonne[,...]) nom_indexestlenomattribulindex.Lenompardfautdelindexestgalaunomdelapremirecolonnedelacl, avecsibesoinunsuffixe(_2,etc.)pourlunicit. Laclauseprcdentepeuttreutilisedansunordre CREATE TABLE,aprslalistedescolonnes,oudansunordre ALTER TABLE ... ADD. Exemple mysql> ALTER TABLE rubrique ADD INDEX (id_parent); Query OK, 15 rows affected (0.01 sec) Records: 15 Duplicates: 0 Warnings: 0 mysql> DESC rubrique; +-----------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+---------+----------------+

ENI Editions - All rigths reserved

- 3-

| id | int(11) | NO | PRI | NULL | auto_increment | | titre | varchar(20) | NO | | | | | id_parent | int(11) | YES | MUL | NULL | | +-----------+-------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) LordreCREATE INDEXpermetaussidecrerunindexsurunetableexistante. Syntaxe CREATE [UNIQUE] INDEX nom_index ON nom_table(nom_cololonne[,...]) nom_indexestlenomattribulindex. Le mot cl optionnel UNIQUE permet de crer un index unique un index unique est fonctionnellement quivalent uneclunique. Un index peut tre cr sur les premiers caractres dune chane, ce qui permet dconomiser de lespace de stockage.Pourfairecela,danslasyntaxededfinitiondelindex,ilsuffitdementionnerlalongueursouhaiteentre parenthsesdernirelenomdelacolonne. Exemple mysql> CREATE INDEX ix_annee ON livre(annee_parution); Query OK, 9 rows affected (0.01 sec) Records: 9 Duplicates: 0 Warnings: 0 mysql> CREATE INDEX ix_nom_prenom ON auteur(nom,prenom); Query OK, 5 rows affected (0.01 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql> CREATE INDEX ix_mot_de_passe ON auteur(mot_de_passe(8)); Query OK, 5 rows affected (0.02 sec) Records: 5 Duplicates: 0 Warnings: 0

lnestpaspossibledecrerunindexsurlatotalitdunecolonnedetype TEXT ou BLOB.Parcontre,surde I tellescolonnes,ilestpossibledecrerunindexsurlespremierscaractreslaidedelasyntaxeprcdente. UnindexpeuttresupprimparunordreALTER TABLE ... DROPouunordreDROP INDEX. Syntaxe ALTER TABLE nom_table DROP INDEX nom_index DROP INDEX nom_index ON nom_table Exemple mysql> DROP INDEX ix_mot_de_passe ON auteur; Query OK, 5 rows affected (0.01 sec) Records: 5 Duplicates: 0 Warnings: 0

LordreSHOW INDEXprsentdanslasectionprcdentepermetdelisterlesindexdunetable.

c.Considrations
LesindexsontautomatiquementutilissparMySQLdansplusieurssituations :
q

pourtrouverrapidementleslignesquicorrespondentuneclauseWHERE pourtrouverleslignesduneautretabledansunejointure pourtrouverlesvaleursMIN()etMAX()dunecolonneindexe

- 4-

ENI Editions - All rigths reserved

pourtrierougrouperleslignesselonunecolonneindexe.

LesindexcomposssontutilisssilacolonnedettedelacldindexestprsentedanslaclauseWHERE. Ensupposantquunindexexistesurlescolonnes(nom,prenom),lesclausessuivantesutilisentlindex : WHERE nom = HEURTEL AND prenom = Olivier WHERE prenom = Olivier AND nom = HEURTEL WHERE nom = HEURTEL Parcontre,lindexprcdentnestpasutilispourlarecherchesuivante : WHERE prenom = Olivier Danscertainscas,sitouteslescolonnesutilisesdansunerequtesontprsentesdanslacldunindex,MySQLna mme pas besoin daccder la table pour traiter la requte. En supposant quun index existe sur les colonnes (nom,prenom),MySQLnapasbesoindaccderlatablepourtraiterlarequtesuivante : SELECT prenom FROM auteur WHERE nom = HEURTEL

tiliserunindexcomposamliorelaslectivitdelindex.Avecunindexcomposcrsur2colonnes,MySQL U peutextrairedirectementleslignesaveclindexlorsquelarechercheportesurlesdeuxcolonnes.Sideuxindex spars sont crs sur chaque colonne, MySQL va utiliser lindex le plus restrictif pour extraire les lignes qui rpondentaucritrecorrespondantavantdliminerensuiteleslignesquinerpondentpasaudeuximecritre. Dans une clause WHERE, appliquer une fonction une colonne indexe, ou utiliser une colonne indexe dans une expression, empche MySQL dutiliser lindex. Il en est de mme si MySQL effectue une conversion implicite de la colonneindexeversunautretypededonnes. Exemple SELECT nom,prenom,mail FROM auteur WHERE LEFT(nom,4) = HEUR; DansunerechercheavecloprateurLIKE,MySQLnepeututiliserunindexquesilaledbutdelachane.Ainsi,une clausedutypeLIKE HEUR%peututiliserunindex,maispasuneclausedutypeLIKE %TEL. Siunerequte SELECTretourneungrandpourcentagedeslignesdelatable,MySQLpeutchoisirdenepasutiliser dindexsilestimequunparcourscompletdelatableestplusperformant. ordreSQLEXPLAINpermetdafficherleplandexcutiondunerequteetdesavoirsiMySQLutiliseounonles L index.Reportezvousladocumentationpourensavoirplussurlesujet. Lesindexprsententdeuxinconvnients :
q

ilsncessitentunespacedestockagesupplmentaire ilsralentissentlesoprationsdemisejourcarchaqueindexdoitluiaussitremisjour.

3.Cltrangre
a.Dfinition
Unecontraintedecltrangrepermetdegarantirquechaquevaleurstockedansunecltrangredunetable "enfant"existebiendansunecl(gnralementprimaireouunique)prcdemmentdfiniedelatable"parent". Les contraintes de cl trangre permettent aussi de contrler ce qui se passe lorsque quune ligne de la table parentestsupprimeouquelaclprimairedunelignedelatableestmodifie. Les contraintes de cl trangre sont actuellement implmentes uniquement dans le moteur InnoDB la table rfrenceetlatableenfantdoiventtredestablesInnoDB.

ENI Editions - All rigths reserved

- 5-

b.Gestion
LaclauseCONSTRAINTpermetdedfinirunecontraintedecltrangre. Syntaxe [CONSTRAINT [nom_contrainte]] FOREIGN KEY (nom_colonne[,...]) REFERENCES nom_table_parent (nom_colonne[,...]) [ON DELETE {RESTRICT | NO ACTION | CASCADE | SET NULL }] [ON UPDATE {RESTRICT | NO ACTION | CASCADE | SET NULL }] nom_contrainteestlenomattribulacontrainte ildoittreuniquedanstoutelabasededonnes.Siaucunnom nestdfini,MySQLattribueunnompardfautlacontrainte. Laclause FOREIGN KEYpermetdedfinirlenomdescolonnesquiconstituentlacltrangre.Laclause REFERENCES permetdespcifierlaclrfrenceparlacontrainte. Lescolonnescorrespondantesdelacltrangreetdelaclrfrencedoiventtredummetype lesdeuxcls doiventtreindexes,aveclescolonnesdanslemmeordre(lindexpeutventuellementcontenirdautrescolonnes droite).Lindexsurlacltrangreestcrautomatiquementsilnexistepasdj. La cl rfrence nest pas obligatoirement primaire ou unique cest une dviation de MySQL par rapport au standardSQL.Cependant,laplupartdutemps,unecltrangrerfrenceuneclprimaire(ouventuellementune clunique). Les clauses ON DELETEet ON UPDATE permettent de dfinir ce qui se passe si une cl rfrence est supprime ou modifieetquilexisteuneouplusieurslignesquicorrespondentdanslatableenfant.MySQLpropose4options : RESTRICT, NO ACTION Lamodificationoulasuppressionestrefusesilexistedeslignesquicorrespondentdanslatableenfant.Cest loptionpardfaut. CASCADE Leslignesquicorrespondentdanslatableenfantsontmodifiesousupprimes. SET NULL LacltrangreestmiseNULL(possibleuniquementsilescolonnescorrespondantesautorisentlesNULL). Laclause CONSTRAINTpeuttreutilisedansunordre CREATE TABLE,aprslalistedescolonnes,oudansunordre ALTER TABLE ... ADD. UnordreALTER TABLEpeuttreutilispoursupprimerunecontraintedecltrangre. Syntaxe ALTER TABLE nom_table DROP FOREIGN KEY nom_contrainte Exemplecomplet mysql> -- Cration des tables "commande" et "ligne_commande". mysql> CREATE TABLE commande -> ( -> id INT PRIMARY KEY AUTO_INCREMENT, -> date_commande DATE -> ) -> ENGINE innodb; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE ligne_commande -> ( -> id_commande INT, -> numero_ligne INT, -> article VARCHAR(50), -> quantite INT, -> prix_unitaire DECIMAL(8,2), -> PRIMARY KEY(id_commande,numero_ligne) -> )

- 6-

ENI Editions - All rigths reserved

-> ENGINE innodb; Query OK, 0 rows affected (0.01 sec) mysql> -- Cration dune contrainte de cl trangre entre mysql> -- "ligne_commande" et "commande". mysql> ALTER TABLE ligne_commande ADD -> FOREIGN KEY (id_commande) -> REFERENCES commande(id); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> -- Insertion dune commande avec une ligne de commande. mysql> INSERT INTO commande(date_commande) VALUES(NOW()); Query OK, 1 row affected (0.01 sec) mysql> SET @id = LAST_INSERT_ID(); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO ligne_commande -> (id_commande,numero_ligne,article,quantite,prix_unitaire) -> VALUES -> (@id,1,PHP 5.2,1,25); Query OK, 1 row affected (0.01 sec) mysql> -- Insertion dune ligne de commande avec un identifiant mysql> -- de commande qui nexiste pas => erreur. mysql> INSERT INTO ligne_commande -> (id_commande,numero_ligne,article,quantite,prix_unitaire) -> VALUES -> (2,1,MySQL 5,1,25); ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`eni/ligne_commande`, CONSTRAINT `ligne_commande_ibfk_1` FOREIGN KEY (`id_commande`) REFERENCES `commande` (`id`)) mysql> -- Suppression de la commande => erreur (par dfaut, mysql> -- la suppression dun parent est interdite sil a des mysql> -- enfants). mysql> DELETE FROM commande WHERE id = @id; ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`eni/ligne_commande`, CONSTRAINT `ligne_commande_ibfk_1` FOREIGN KEY (`id_commande`) REFERENCES `commande` (`id`)) mysql> -- Recration de la contrainte de cl trangre pour avoir mysql> -- une suppression en cascade. mysql> ALTER TABLE ligne_commande -> DROP FOREIGN KEY ligne_commande_ibfk_1; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> ALTER TABLE ligne_commande ADD -> FOREIGN KEY (id_commande) -> REFERENCES commande(id) -> ON DELETE CASCADE; Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> -- Suppression de la commande => OK. mysql> DELETE FROM commande WHERE id = @id; Query OK, 1 row affected (0.06 sec) mysql> SELECT COUNT(*) FROM ligne_commande WHERE id_commande = @id; +----------+ | COUNT(*) | +----------+ | 0 | +----------+ 1 row in set (0.00 sec)

ENI Editions - All rigths reserved

- 7-

Utiliserdesvues
1.Dfinition
UnevueestunerequteSELECTdontladfinitioneststockeavecunnomdanslabasededonnes. La vue ne stocke pas de donnes les donnes prsentes par la vue sont drives des tables interroges par la requtedelavue. Une vue sutilise comme une table. Certaines vues peuvent tre utilises dans des ordres de mise jour ( INSERT, UPDATE, DELETE) pour modifier les donnes des tables sousjacentes. Pour quune vue puisse tre utilise en mise jour,ilfautquilyaitunerelationununentreleslignesretournesparlavueetleslignesdelatablesousjacente. Unevuenepeutpastreutiliseenmisejoursilarequtequiladfinitcontientnotammentunedesconstructions suivantes :
q

UneclauseDISTINCT Des expressions dans la clause SELECT (interdit les ordres INSERT mais pas les ordres UPDATE qui modifient uniquementlescolonnesquinesontpascalcules) Des agrgats, des unions, des sousrequtes dans la clause SELECT (cf. chapitre Techniques avances avec MySQLUtiliserdessousrequtes).

Lesvuessontutilisesprincipalementpour :
q

Faciliterlaccsauxdonnes
q

Larequteutilisepourdfinirlavuepeuttrecomplexeetcomporterparexempledesjointuresentre plusieurstables.Lesrequtesquiutilisentlavuesontalorsplussimplescrire.

Scuriserlaccsauxdonnes
q

Larequteutilisepourdfinirlavuepeutmasquerdescolonnes(colonnesnonslectionnesdansla clauseSELECT)et/oudeslignes(clauseWHEREquifiltrelesdonnes).Entermedegestiondedroit,ilest possiblededonnerundroitdelecturesurunevueunutilisateursansluidonnerledroitdelecture surlestablessousjacentes. Ainsi, un tel utilisateur ne pourra jamais voir ce quilna pas le droit de voir.

2.Gestion
LordreSQLCREATE VIEWpermetdecrerunevue. Syntaxesimplifie CREATE [OR REPLACE] VIEW nom_vue [(nom_colonne[,...])] AS requte_SELECT [WITH CHECK OPTION] nom_vueestlenomdelavue.CenomdoitrespecterlesrglesdenommagedesidentifiantsMySQL.Lestablesetles vues partagent le mme espace de nommage lintrieur dune base de donnes en consquence, une base de donnesnepeutpascontenirunetableetunevuequiportentlemmenom. Pardfaut,lesnoms(oualias)descolonnesslectionnesdanslarequteSELECTdelavuesontutilisscommenoms descolonnesdelavue.Pournommerdiffremmentlescolonnesdelavue,ilestpossibledespcifierunelistedenoms decolonnesderrirelenomdelavue cettelistedoitcomporterunnompourchaquecolonne/expressionretourne parlarequteSELECT. LaclauseoptionnelleOR REPLACEpermetderecrerlavuesielleexistedj. Toutes les clauses habituelles peuvent tre manipules dans la requte SELECT utilise pour la dfinition de la vue (WHERE, ORDER BY, jointures, etc.) une vue peut interroger dautres vues, mais elle ne peut pas contenir de sous requtedanslaclause FROM(cf.chapitreTechniquesavancesavecMySQLUtiliserdessousrequtes). La requte

ENI Editions - All rigths reserved

- 1-

peutinterrogerdestablesoudesvuesduneautrebasededonnesaveclanotationhabituelle(prfixerparlenom delabasededonnes). Exemple mysql> CREATE OR REPLACE VIEW -> liste_rubriques(rubrique,sous_rubrique) -> AS -> SELECT par.titre rubrique,enf.titre sous_rubrique -> FROM rubrique par,rubrique enf -> WHERE enf.id_parent = par.id; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM liste_rubriques; +-----------------+-----------------+ | rubrique | sous_rubrique | +-----------------+-----------------+ | Base de donnes | MySQL | | Base de donnes | Oracle | | Dveloppement | Langages | | Dveloppement | Mthode | | Internet | HTML - XML | | Internet | Conception Web | | Internet | Scurit | | Open Source | Systme | | Open Source | Langages | | Open Source | Base de donnes | +-----------------+-----------------+ 10 rows in set (0.00 sec) Pardfaut,lorsquunevueestutiliseenmisejour,ilestpossibledinsreroumodifierdeslignestraverslavuequi nerespectentpaslaclause WHEREdedfinitiondelavue leslignesainsiinsresoumodifiesnepourrontpastre interrogesparlavue !PourgarantirqueleslignesinsresoumodifiestraversunevuerespectentlaclauseWHERE de la vue et seront donc interrogeables par la vue, il faut ajouter la clause optionnelle WITH CHECK OPTION dans la dfinitiondelavue. Exemple mysql> CREATE OR REPLACE VIEW rubrique_db AS -> SELECT * FROM rubrique W H E R E i d _ p a r e n t = 1 -> W I T H C H E C K O P T I O N ; Query OK, 0 rows affected (0.01 sec) mysql> SELECT * FROM rubrique_db; +----+--------+-----------+ | id | titre | id_parent | +----+--------+-----------+ | 5 | MySQL | 1 | | 6 | Oracle | 1 | +----+--------+-----------+ 2 rows in set (0.00 sec) mysql> SELECT * FROM rubrique_db W H E R E i d _ p a r e n t = 2 ; Empty set (0.01 sec) mysql> INSERT INTO rubrique_db(titre,id_parent) VALUES(SQLite,1); Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO rubrique_db(titre,id_parent) VALUES(Langages, 4 ); ERROR 1369 (HY000): CHECK OPTION failed eni.rubrique_db Pourmodifierladfinitiondunevue,ilestpossibledutiliserlordreSQLCREATE OR REPLACE VIEWoulordreALTER VIEW. Syntaxesimplifie ALTER VIEW nom_vue [(nom_colonne[,...])] AS requte_SELECT [WITH CHECK OPTION]

- 2-

ENI Editions - All rigths reserved

LordreSQLDROP VIEWpermetdesupprimerunevue. Syntaxe DROP VIEW [IF EXISTS] nom_vue[,...]

ordreSQLSHOW CREATE VIEWpermetdafficherladfinitiondunevuesouslaformedunordre CREATE VIEW(cf. L Obtenir des informations sur les bases de donnes dans ce chapitre). LordreSQL SHOW TABLES affiche la liste destablesetdesvuesdunebasededonnes.LordreDESCpeuttreutilispourafficherlastructuredunevue.

ENI Editions - All rigths reserved

- 3-

Obtenirdesinformationssurlesbasesdedonnes
1.LacommandeSHOW
Lacommande SHOWproposedenombreusesvariantesquipermettentdafficherdesinformationssurlesbasesdedonnes,lestables,les vues,etc. Variante1:afficherunelistedobjets SHOW DATABASES [ condition ]SHOW TABLES [FROM nom_base] [ condition ]SHOW TRIGGERS [FROM nom_base] [ condition ] Variante2:afficherlalistedescolonnesoudesindexdunetable SHOW COLUMNS FROM nom_table [FROM nom_base] [ condition ]SHOW INDEX FROM nom_table [FROM nom_base] Variante3:afficherlordredecrationdunobjet SHOW SHOW SHOW SHOW SHOW SHOW CREATE CREATE CREATE CREATE CREATE CREATE {DATABASE | SCHEMA} nom_base FUNCTION nom_fonction PROCEDURE nom_procdure TABLE nom_table TRIGGER nom_trigger VIEW nom_vue

Variante4:afficherunelistedobjetsavecquelquescaractristiques SHOW FUNCTION STATUS [ condition ]SHOW PROCEDURE STATUS [ condition ]SHOW TABLE STATUS [FROM nom_base] [ condition ] Avec condition = LIKE modle | WHERE expression LersultatdelacommandeSHOWestaffichsouslaformedelignesetdecolonnes,commelersultatdunerequteSELECT.Laplupartdes langagesquiaccdentMySQLpermettentdetraiterlersultatdelacommande SHOWdelammemanirequelersultatdunerequte SELECT. La clause optionnelle condition permet de filtrer le rsultat de la commande SHOW, soit laide dune expression LIKE qui sapplique implicitementaunomdelobjet,soitlaideduneclauseWHEREquipeutsappliquernimportequellecolonnedursultat. Exemple mysql> SHOW COLUMNS FROM collection; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | nom | varchar(25) | NO | UNI | | | | prix_ht | decimal(5,2) | YES | | 20.00 | | | frais_ht | decimal(5,2) | YES | | NULL | | +----------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) mysql> SHOW CREATE TABLE collection; +------------+-----------------------------------------------------+ | Table | Create Table | +------------+-----------------------------------------------------+ | collection | CREATE TABLE `collection` ( | | | `id` int(11) NOT NULL auto_increment, | | | `nom` varchar(25) NOT NULL , | | | `prix_ht` decimal(5,2) default 20.00, | | | `frais_ht` decimal(5,2) default NULL, | | | PRIMARY KEY (`id`), | | | UNIQUE KEY `nom` (`nom`) | | | ) ENGINE=MyISAM AUTO_INCREMENT=9 | | | DEFAULT CHARSET=latin1 | +------------+-----------------------------------------------------+ 1 row in set (0.01 sec)

2.LabasededonnesINFORMATION_SCHEMA
Depuislaversion5,unserveurMySQLmaintientunebasededonnesnomme INFORMATION_SCHEMAquicontientunensembledetablesqui permettent dobtenir des informations sur les objets (tables, index, vues, etc.) contenus dans les diffrentes bases de donnes (ou "schmas"pourreprendrelanouvelleterminologiedelaversion5).Cettebasedinformationsestparfoisappele"dictionnairededonnes" ou "catalogue systme". Il faut noter que la base de donnes INFORMATION_SCHEMA nest pas une "vraie" base de donnes elle na ni

ENI Editions - All rigths reserved

- 1-

rpertoirenifichiersurleserveur. Lestablesdelabasedonnes INFORMATION_SCHEMApeuventtreinterrogescommenimportequelletablepourobtenirdesinformations surlesobjetsstocksdanslesdiffrentesbasesdedonnes.Lestablessuivantespermettentdobtenirdesinformationssurlesprincipaux objetsdunebasededonnes : COLUMNS Informationssurlescolonnesdestables. COLUMN_PRIVILEGES Informationssurlesprivilgesdeniveaucolonnedesutilisateurs. KEY_COLUMN_USAGE Informationssurlescolonnesdestablesquisontimpliquesdansdescontraintes. ROUTINES Informationssurlesprogrammesstocks(cf.chapitreTechniquesavancesavecMySQLDvelopperdesprogrammesstocks). SCHEMATA Informationssurlesbasesdedonnes. SCHEMA_PRIVILEGES Informationssurlesprivilgesdeniveauschma(basededonnes)desutilisateurs. TABLES Informationssurlestables. TABLE_CONSTRAINTS Informationssurlescontraintesdestables. TABLE_PRIVILEGES Informationssurlesprivilgesdeniveauobjetdesutilisateurs. TRIGGERS Informationssurlestriggers(cf.chapitreTechniquesavancesavecMySQLDvelopperdestriggers). USER_PRIVILEGES Informationssurlesprivilgesglobauxdesutilisateurs. VIEWS Informationssurlesvues. esdiffrentestablesdelabasededonnes INFORMATION_SCHEMAsontdcritesendtaildansladocumentationMySQL.Lesordres L SHOW TABLES, SHOW COLUMNS, DESC peuvent tre utiliss pour afficher des informations sur les tables de la base de donnes INFORMATION_SCHEMA.

Exemple mysql> SELECT -> column_name, -> data_type, -> column_default, -> is_nullable, -> column_key -> FROM -> information_schema.columns -> WHERE -> table_schema = eni -> AND table_name = collection -> ORDER BY -> ordinal_position; +-------------+-----------+----------------+-------------+------------+ | column_name | data_type | column_default | is_nullable | column_key | +-------------+-----------+----------------+-------------+------------+ | id | int | NULL | NO | PRI | | nom | varchar | NULL | NO | UNI |

- 2-

ENI Editions - All rigths reserved

| prix_ht | decimal | 20.00 | YES | | | frais_ht | decimal | NULL | YES | | +-------------+-----------+----------------+-------------+------------+ 4 rows in set (0.01 sec)

ENI Editions - All rigths reserved

- 3-

Exporteretimporterunebasededonnes
LapplicationclientemysqldumppermetdexporterunebasededonnesMySQL,souslaformedunfichier("dump")contenantlesordrespermettantderecrerlabasededonnes.Cestundesmoyensquipeuttreutilispoursauvegarderunebasededonnes. Syntaxe mysqldump [-h hte] [-u utilisateur ] [-p[ mot_de_passe ]] nom_base Avec -h hte Hteauquelilfautseconnecter(machinelocalepardfaut). -u utilisateur Nomdutilisateurpourlaconnexion(nomdelutilisateurcourantdusystmedexploitationpardfaut). -p[mot_de_passe] Motdepassepourlaconnexion(aucunmotdepassepardfaut).Silnestpasdonnsurlalignedecommande,ilserademanddemanireinteractive,ensaisiemasque.Silemotdepasseestspcifidanslalignedecommande(cequinestpasconseillpourlascurit),ilnedoitpasyavoirdespaceaprsloption-p. nom_base Nomdelabasededonnesexporter. mysqldumpaffichelersultatsurlasortiestandard pourrcuprercersultatdansunfichier,ilfaututiliserunecommandederedirection(> fichier). Exemple [root@xampp ~]# mysqldump -u eniadm -psecret eni > dump-base-eni.sql Rsultat(extraitsdufichierdump-base-eni.sql) -- MySQL dump 10.11 --- Host: localhost Database: eni -- ------------------------------------------------------- Server version 5.0.45 ... --- Table structure for table `rubrique` -DROP TABLE IF EXISTS `rubrique`; CREATE TABLE `rubrique` ( `id` int(11) NOT NULL auto_increment, `titre` varchar(20) NOT NULL, `id_parent` int(11) default NULL, PRIMARY KEY (`id`), KEY `id_parent` (`id_parent`) ) ENGINE=MyISAM AUTO_INCREMENT=18 DEFAULT CHARSET=latin1; --- Dumping data for table `rubrique` -LOCK TABLES `rubrique` WRITE; /*!40000 ALTER TABLE `rubrique` DISABLE KEYS */; INSERT INTO `rubrique` VALUES (1,Base de donnes,NULL),(2,Dveloppement,NULL),(3,Internet,NULL),(4,Open Source,NULL),(5,MySQL,1),(6,Oracle,1),(7,Langages,2),(8,Mthode,2),(9,HTML - XML,3),(10,Conception Web,3),(11,Scurit,3),(12,Systme,4),(13,Langages,4),(14,Base de donnes,4),(16,Certification,NULL,(17,SQLite,1); /*!40000 ALTER TABLE `rubrique` ENABLE KEYS */; UNLOCK TABLES; ... -- Dump completed on 2008-01-25 10:52:59

Attentionsilyadesmisesjourpendantlasauvegarde !Lasauvegarderisquedenepastrecohrentedupointdevueapplicatif. Unfichierdexportpeuttreimportedansunebasededonnesquiexistedjaveclapplicationclientemysqlsoiteninteractif(commandesourcecf.chapitreIntroductionMySQLTravailleravecMySQL)soitenbatch,enutilisantuneredirectiondelentrestandard :mysql ... < fichier. Exemple [root@xampp ~]# mysql -u root biblio < d u m p - b a s e - e n i . s q l [root@xampp ~]# mysql -u root biblio Welcome to the MySQL monitor. Commands end with ; or \g. ... mysql> SELECT nom,prix_ht FROM collection; +--------------------------+---------+ | nom | prix_ht | +--------------------------+---------+ | Ressources Informatiques | 24.44 | | TechNote | 10.48 | | Les TP Informatiques | 25.59 | | Coffret Technique | 46.45 | | Solutions Informatiques | 36.97 | | ExpertIT | 20.00 | +--------------------------+---------+ 6 rows in set (0.01 sec)

ENI Editions - All rigths reserved

- 1-

Grouperlesdonnes
Parfois,vouspouvezavoirbesoindecalculerunevaleurpourunniveauderegroupement :
q

Chiffredaffairescumulparrgion Salairemoyenpardpartement

Pour ce genre dinterrogation, vous allez pouvoir utiliser des fonctions dagrgat ( SUM, AVG, etc.) et regrouper les donnesgrcelaclause GROUP BY encomplment,lersultatfinal,aprsregroupement,peuttrerestreintavecla clauseHAVING. Syntaxe : SELECT expression[,...] | * FROM nom_table [WHERE conditions]GROUP BY expression [ASC | DESC] [,...][HAVING conditions] [ORDER BY expression [ASC | DESC][,...]] [LIMIT [offset,] nombre_lignes] LaclauseGROUP BYsintercaleentrelesclauses WHEREet ORDER BY(siellessontprsentes).Ellespcifielesexpressions utilisespoureffectuerleregroupement. expressionpeuttre :
q

Unecolonne Uneexpressionbasesurdescolonnes Unaliasdecolonne UnnumrocorrespondantlapositionduneexpressiondelaclauseSELECT(syntaxedconseilleetobsolte)

Pardfaut,lersultatdelarequteesttrienordrecroissantsurlesdiffrentesexpressionsdelaclause GROUP BY lordre du tri de chaque niveau de regroupement peut tre dfini explicitement avec les options ASC et DESC. Un tri compltementdiffrentpeuttrespcifigrcelaclauseORDER BY. Laplupartdutemps,vousmettrezdanslaclauseGROUP BYtouteslesexpressionsdelaclauseSELECTquinecomportent pasdefonctiondagrgat.CestlefonctionnementhabituelpourrespecterleSQLstandard. Exemple mysql> -- Nombre de livres par collection. mysql> SELECT id_collection,COUNT(*) -> FROM livre -> GROUP BY id_collection; +---------------+----------+ | id_collection | COUNT(*) | +---------------+----------+ | 1 | 4 | | 2 | 3 | | 3 | 1 | | 4 | 1 | +---------------+----------+ 4 rows in set (0.00 sec) mysql> mysql> mysql> -> -> -> -> -> -> -- Nombre de livres et nombre moyen de pages par collection -- (avec le nom de la collection au lieu de lidentifiant). SELECT col.nom collection, COUNT(liv.id) nb_livres, ROUND(AVG(liv.nombre_pages)) nb_pages_moy FROM livre liv JOIN collection col ON (liv.id_collection = col.id)
ENI Editions - All rigths reserved - 1-

-> GROUP BY -> col.nom -> ORDER BY -> nb_livres; -- tri sur le nombre de livres +--------------------------+-----------+--------------+ | collection | nb_livres | nb_pages_moy | +--------------------------+-----------+--------------+ | Les TP Informatiques | 1 | 272 | | Coffret Technique | 1 | 972 | | TechNote | 3 | 182 | | Ressources Informatiques | 4 | 486 | +--------------------------+-----------+--------------+ 4 rows in set (0.00 sec) mysql> -- Nombre de livres par tranche danne et collection. mysql> SELECT -> CASE -> WHEN annee_parution IN (2004,2005) -> THEN 2004-2005 -> WHEN annee_parution IN (2006,2007) -> THEN 2006-2007 -> END tranche_annee, -> col.nom collection, -> COUNT(liv.id) nb_livres -> FROM -> livre liv JOIN collection col -> ON (liv.id_collection = col.id) -> GROUP BY -- utilisation des alias de colonne -> tranche_annee, -> collection; +---------------+--------------------------+-----------+ | tranche_annee | collection | nb_livres | +---------------+--------------------------+-----------+ | 2004-2005 | Les TP Informatiques | 1 | | 2004-2005 | Ressources Informatiques | 2 | | 2004-2005 | TechNote | 2 | | 2006-2007 | Coffret Technique | 1 | | 2006-2007 | Ressources Informatiques | 2 | | 2006-2007 | TechNote | 1 | +---------------+--------------------------+-----------+ 6 rows in set (0.01 sec) AvecMySQL,vouspouvezavoirdanslaclause SELECTdesexpressionsquinutilisentpasdefonctiondagrgatetquine sontpasreprisesdanslaclauseGROUP BY. Exemple : mysql> SELECT -> col.nom collection, -- non prsent dans le GROUP BY -> col.prix_ht, -- non prsent dans le GROUP BY -> COUNT(liv.id) nb_livres -> FROM -> livre liv JOIN collection col -> ON (liv.id_collection = col.id) -> GROUP BY -> col.id; +--------------------------+---------+-----------+ | collection | prix_ht | nb_livres | +--------------------------+---------+-----------+ | Ressources Informatiques | 24.44 | 4 | | TechNote | 10.48 | 3 | | Les TP Informatiques | 25.59 | 1 | | Coffret Technique | 46.45 | 1 | +--------------------------+---------+-----------+ 4 rows in set (0.00 sec) Cette possibilit de MySQL est intressante et permet de simplifier lcriture de la requte et damliorer les performanceslorsquelexpressionconcerneestuniquepourchaquegroupe(cestlecassurlexempleprcdentole nometleprixdelacollectionsontuniquespourchaqueidentifiantdecollection).Parcontre,ilestdconseilldutiliser

- 2-

ENI Editions - All rigths reserved

cettepossibilitsilexpressionconcernenestpasuniquedanslegroupe MySQLvaretournernimportequellevaleur pourlegroupeetlersultatobtenunaengnralpasvraimentdesens. Exemple mysql> SELECT -> col.nom collection, -> liv.annee_parution, -- p a s u n i q u e d a n s l e g r o u p e ! -> COUNT(liv.id) nb_livres -> FROM -> livre liv JOIN collection col -> ON (liv.id_collection = col.id) -> GROUP BY -> col.nom; +--------------------------+----------------+-----------+ | collection | annee_parution | nb_livres | +--------------------------+----------------+-----------+ | Coffret Technique | 2006 | 1 | | Les TP Informatiques | 2004 | 1 | | Ressources Informatiques | 2007 | 4 | | TechNote | 2006 | 3 | +--------------------------+----------------+-----------+ 4 rows in set (0.00 sec) Danscegenredesituation,ilpeuttreintressantdutiliserlesfonctions MINou MAXpourobtenirunevaleurspcifique "contrle"delexpression("leplusgrand","lepluspetit","lepremier","ledernier",etc.). Exemple mysql> SELECT -> col.nom collection, -> MIN(liv.annee_parution) premiere_parution, -> COUNT(liv.id) nb_livres -> FROM -> livre liv JOIN collection col -> ON (liv.id_collection = col.id) -> GROUP BY -> col.nom; +--------------------------+-------------------+-----------+ | collection | premiere_parution | nb_livres | +--------------------------+-------------------+-----------+ | Coffret Technique | 2006 | 1 | | Les TP Informatiques | 2004 | 1 | | Ressources Informatiques | 2004 | 4 | | TechNote | 2005 | 3 | +--------------------------+-------------------+-----------+ 4 rows in set (0.00 sec) Pour restreindre le rsultat final, avec des conditions utilisant les fonctions dagrgat, vous devez utiliser la clause HAVING.Eneffet,uneclauseWHEREnepeutpascomporterdeconditionquiutiliseunefonctiondagrgat :cesttrop"tt" dansletraitementdelarequte lesgroupesnontpasencoretconstitus. LesconditionsduneclauseHAVINGsontsemblablescellesduneclauseWHEREaveclesparticularitssuivantes :
q

ellespeuventutiliserdesfonctionsdagrgat ellespeuventutiliserlesaliasdfinisdanslaclauseSELECT.

Exemple : mysql> mysql> mysql> -> -> -> -> -> -- Afficher uniquement les collections qui ont -- au moins deux livres. SELECT col.nom collection, COUNT(liv.id) nb_livres, ROUND(AVG(liv.nombre_pages)) nb_pages_moy FROM livre liv JOIN collection col

ENI Editions - All rigths reserved

- 3-

-> ON (liv.id_collection = col.id) -> GROUP BY -> col.nom -> HAVING -> COUNT(liv.id) > 1; +--------------------------+-----------+--------------+ | collection | nb_livres | nb_pages_moy | +--------------------------+-----------+--------------+ | Ressources Informatiques | 4 | 486 | | TechNote | 3 | 182 | +--------------------------+-----------+--------------+ 2 rows in set (0.01 sec) mysql> -- Afficher uniquement les collections qui ont mysql> -- au moins deux livres et plus de 400 pages. mysql> SELECT -> col.nom collection, -> COUNT(liv.id) nb_livres, -> ROUND(AVG(liv.nombre_pages)) nb_pages_moy -> FROM -> livre liv JOIN collection col -> ON (liv.id_collection = col.id) -> GROUP BY -> col.nom -> HAVING -- utilisation des alias -> nb_livres > 1 -> AND nb_pages_moy > 400; +--------------------------+-----------+--------------+ | collection | nb_livres | nb_pages_moy | +--------------------------+-----------+--------------+ | Ressources Informatiques | 4 | 486 | +--------------------------+-----------+--------------+ 1 row in set (0.00 sec) Pourdesraisonsdeperformance,laclauseHAVINGnedoitpastreutilisepourfiltrerdesdonnesquipourraientltre danslaclauseWHERE.

- 4-

ENI Editions - All rigths reserved

Utiliserdessousrequtes
1.Introduction
Depuislaversion4.1,MySQLsupportelutilisationdesousrequtes. UnesousrequteestunerequteSELECTquiestutiliselintrieurduneautrerequte. Unesousrequtepeuttreutilise :
q

danslaclauseWHEREdunerequteSELECT,UPDATEouDELETE danslaclauseSELECTdunerequteSELECT danslaclauseFROMdunerequteSELECT commevaleuraffecteunecolonnedansunerequteINSERTouUPDATE commesourcededonnesdunerequteINSERT,laplacedelaclauseVALUES.

Lasousrequteesttoujourscriteentreparenthses. Sauf dans le cas de lutilisation dans la clause FROM dune requte SELECT, la sousrequte ne doit pas contenir de clause ORDER BY elle peut par contre contenir des jointures, ainsi que des clauses WHERE, GROUP BY, etc. Une sous requtepeutaussiellemmecontenirdessousrequtes !

2.Sousrequtescalaire
Unesousrequtequiretourneuneseulecolonneetauplusuneseuleligneestappelesousrequtescalaire. Unetellesousrequtepeuttreutilisepartoutounevaleur(unoprande)estattendu :
q

danslaclauseWHEREdunerequteSELECT,INSERT,UPDATEouDELETE danslaclauseSELECTdunerequteSELECT commevaleuraffecteunecolonnedansunerequteINSERTouUPDATE commeoprandedunefonctionouduneexpression.

Exemple mysql> -- Ecart entre le prix de la collection 1 et le prix moyen mysql> -- des collections. mysql> SELECT -> ROUND(prix_ht - (SELECT AVG(prix_ht) FROM collection),2) -> FROM -> collection -> WHERE -> id = 1; +----------------------------------------------------------+ | ROUND(prix_ht - (SELECT AVG(prix_ht) FROM collection),2) | +----------------------------------------------------------+ | -2.88 | +----------------------------------------------------------+ 1 row in set (0.00 sec) mysql> -- Prix TTC catalogue de larticle de code "RI410GORAA". mysql> SELECT prix_ttc FROM catalogue WHERE code = RI410GORAA; +----------+
ENI Editions - All rigths reserved - 1-

| prix_ttc | +----------+ | 35.00 | +----------+ 1 row in set (0.01 sec) mysql> -- Affecter le prix TTC de la collection larticle mysql> -- du catalogue ayant le code "RI410GORAA". mysql> UPDATE catalogue -> SET prix_ttc = -> (SELECT prix_ht+ROUND(prix_ht*5.5/100) -> FROM collection WHERE id = 1) -- sous-requte -> WHERE code = RI410GORAA; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> -- Vrifier. mysql> SELECT prix_ttc FROM catalogue WHERE code = RI410GORAA; +----------+ | prix_ttc | +----------+ | 25.44 | +----------+ 1 row in set (0.00 sec)

ne sousrequte scalaire utilise dans une clause WHERE est un cas particulier de lutilisation plus gnrale U dunesousrequtedansunecomparaison(cf.Comparaisonavecunesousrequte).

3.Comparaisonavecunesousrequte
UnesousrequtepeuttreutilisecommeexpressiondanslaclauseWHEREduneautrerequte : {expression | sous-requte} oprateur {expression | sous-requte} Lesoprateurshabituelspeuventtreutiliss :=, <, <=,>, >=,!=, IN, NOT IN,etc.Unoprateurspcial, EXISTS(et NOT EXISTS),peutaussitreutilis. Dans le cas des oprateurs scalaires ( =, <, <=, >, >=, !=), la sousrequte doit retourner exactement une ligne le nombredexpressionsretournesdoitdeplustregalaunombredexpressionsprsentesdanslautremembredela comparaison. Exemple mysql> -- Collection la plus chre. mysql> SELECT nom,prix_ht FROM collection -> WHERE prix_ht = (SELECT MAX(prix_ht) FROM collection); +-------------------+---------+ | nom | prix_ht | +-------------------+---------+ | Coffret Technique | 46.45 | +-------------------+---------+ 1 row in set (0.01 sec) mysql> -- Collections dont le prix est infrieur la moyenne mysql> -- du prix des collections. mysql> SELECT nom,prix_ht FROM collection -> WHERE prix_ht <= (SELECT AVG(prix_ht) FROM collection); +--------------------------+---------+ | nom | prix_ht | +--------------------------+---------+ | Ressources Informatiques | 24.44 | | TechNote | 10.48 | | Les TP Informatiques | 25.59 | | ExpertIT | 20.00 | +--------------------------+---------+

- 2-

ENI Editions - All rigths reserved

4 rows in set (0.00 sec) Danslecasdesoprateurs IN, NOT IN, EXISTS et NOT EXISTS,lasousrequtepeutretournerunnombrequelconque delignes(aveclammerglesurlenombredexpressions). LefonctionnementdesoprateursINetNOT INestlemmequavecunelisteexplicitedevaleurs. Exemple mysql> -- Titre des ouvrages des collections qui mysql> -- nont quun ouvrage. mysql> SELECT titre,id_collection -> FROM livre -> WHERE id_collection IN -> -- La sous-requte donne la liste des identifiants -> -- des collections qui nont quun ouvrage. -> (SELECT id_collection FROM livre -> GROUP BY id_collection HAVING COUNT(*) = 1); +--------------------------------+---------------+ | titre | id_collection | +--------------------------------+---------------+ | PHP et MySQL (versions 4 et 5) | 3 | | MySQL 5 et PHP 5 | 4 | +--------------------------------+---------------+ 2 rows in set (0.01 sec) Loprateur EXISTStestesimplementlexistencedunrsultatdanslasousrequte laconditionestvalue TRUEsi la sousrequte retourne au moins une ligne, et FALSE sinon. Loprateur NOT EXISTS teste simplement la non existencedunrsultatdanslasousrequte laconditionestvalue TRUEsilasousrequteneretourneaucune ligne,etFALSEsinon. Lesoprateurs EXISTSet NOT EXISTSsontgnralementutilissavecdessousrequtescorrles(cf.Sousrequte corrle). Ilestpossibledutiliserlesoprateursscalaires(=,<,<=,>,>=, !=)avecunesousrequtequiretourneplusieurslignes en les combinant avec les oprateurs ANY (ou son synonyme SOME) ou ALL. Ces oprateurs permettent de faire des interrogationsdutype"suprieurunedesvaleursdelasousrequte"ou"infrieurtouteslesvaleursdelasous requte". Exemple mysql> -- Livres dont le nombre de pages est suprieur au nombre mysql> -- de pages dau moins un livre de la collection 1. mysql> SELECT titre,nombre_pages,id_collection FROM livre -> WHERE nombre_pages > ANY -> (SELECT nombre_pages FROM livre WHERE id_collection = 1); +-------------------+--------------+---------------+ | titre | nombre_pages | id_collection | +-------------------+--------------+---------------+ | PHP 5.2 | 518 | 1 | | Oracle 10g | 489 | 1 | | BusinessObjects 6 | 470 | 1 | | MySQL 5 et PHP 5 | 972 | 4 | +-------------------+--------------+---------------+ 4 rows in set (0.00 sec) mysql> -- Livres dont le nombre de pages est suprieur au nombre mysql> -- de pages de tous les livres de la collection 1. mysql> SELECT titre,nombre_pages,id_collection FROM livre -> WHERE nombre_pages > ALL -> (SELECT nombre_pages FROM livre WHERE id_collection = 1); +------------------+--------------+---------------+ | titre | nombre_pages | id_collection | +------------------+--------------+---------------+ | MySQL 5 et PHP 5 | 972 | 4 | +------------------+--------------+---------------+ 1 row in set (0.01 sec) Pourensavoirplussurcettesyntaxe,consultezladocumentationMySQL.

ENI Editions - All rigths reserved

- 3-

ttentionlutilisationdecertainsoprateurs(NOT INou > ALLparexemple)lorsquelasousrequteretourne A unevaleurNULL lersultatestvide.

4.Sousrequtecorrle
Unesousrequteestditecorrlesiellefaitrfrenceunecolonnedunetabledelarequteparent.Danscecas,la sousrequteestexcuteetvaluepourchaquelignedelarequteparent,carlacolonnerfrencedanslatable delarequteparentestsusceptibledechangerchaqueligne. Danslecasdunesousrequte"simple"(noncorrle),lasousrequteestexcuteuneseulefoisetsonrsultat estcomparavecchaquelignedelarequteparent. Lessousrequtes corrles peuvent tre utilises dans la clause WHEREdune requte SELECT, UPDATEou DELETE,ou danslaclauseSETdunerequteUPDATE(danscecas,lasousrequtedoitaussitrescalaire). Exemple mysql> -- Livres qui ont plus dun auteur (requte EXISTS). mysql> SELECT liv.titre FROM l i v r e l i v -> WHERE EXISTS -> (SELECT 1 FROM a u t e u r _ l i v r e a u l W H E R E a u l . i d _ l i v r e = l i v . i d -> GROUP BY aul.id_livre HAVING COUNT(*) > 1); +------------------+ | titre | +------------------+ | MySQL 5 et PHP 5 | +------------------+ 1 row in set (0.01 sec) mysql> -- Livres qui ont plus dun auteur (comparaison avec une mysql> -- sous-requte scalaire). mysql> SELECT liv.titre FROM l i v r e l i v -> WHERE -> (SELECT COUNT(*) FROM a u t e u r _ l i v r e a u l -> WHERE a u l . i d _ l i v r e = l i v . i d ) > 1; +------------------+ | titre | +------------------+ | MySQL 5 et PHP 5 | +------------------+ 1 row in set (0.00 sec) mysql> -- Sous-rubriques de la rubrique 2 qui nont mysql> -- pas de livre affect. mysql> SELECT rub.titre FROM r u b r i q u e r u b -> WHERE -> rub.id_parent = 2 -> AND NOT EXISTS -> (SELECT 1 FROM r u b r i q u e _ l i v r e r u l -> WHERE r u l . i d _ r u b r i q u e = r u b . i d ); +---------+ | titre | +---------+ | Mthode | +---------+ 1 row in set (0.00 sec) mysql> -- Supprimer les sous-rubriques de la rubrique 2 mysql> -- qui nont pas de livre affect. mysql> DELETE FROM r u b r i q u e -> WHERE -> id_parent = 2 -> AND NOT EXISTS -> (SELECT 1 FROM r u b r i q u e _ l i v r e r u l -> WHERE r u l . i d _ r u b r i q u e = r u b r i q u e . i d ); Query OK, 1 row affected (0.00 sec)

- 4-

ENI Editions - All rigths reserved

mysql> -- Collections qui ont au moins un livre de plus mysql> -- de 500 pages. mysql> SELECT id,nom,frais_ht FROM c o l l e c t i o n c o l -> WHERE EXISTS -> (SELECT 1 FROM l i v r e l i v -> WHERE l i v . i d _ c o l l e c t i o n = c o l . i d -> AND liv.nombre_pages > 500); +----+--------------------------+----------+ | id | nom | frais_ht | +----+--------------------------+----------+ | 1 | Ressources Informatiques | 1.50 | | 4 | Coffret Technique | 2.00 | +----+--------------------------+----------+ 2 rows in set (0.00 sec) mysql> -- Augmenter de 25 centimes les frais pour les mysql> -- collections qui ont au moins un livre de plus mysql> -- de 500 pages. mysql> UPDATE c o l l e c t i o n c o l SET col.frais_ht = col.frais_ht + 0.25 -> WHERE EXISTS -> (SELECT 1 FROM l i v r e l i v -> WHERE l i v . i d _ c o l l e c t i o n = c o l . i d -> AND liv.nombre_pages > 500); Query OK, 2 rows affected (0.00 sec) Rows matched: 2 Changed: 2 Warnings: 0 mysql> -- Vrifier. mysql> SELECT id,nom,frais_ht FROM collection WHERE id IN (1,4); +----+--------------------------+----------+ | id | nom | frais_ht | +----+--------------------------+----------+ | 1 | Ressources Informatiques | 1.75 | | 4 | Coffret Technique | 2.25 | +----+--------------------------+----------+ 2 rows in set (0.00 sec) mysql> -- Collections qui nont pas de frais. mysql> SELECT * FROM collection WHERE frais_ht IS NULL; +----+----------+---------+----------+ | id | nom | prix_ht | frais_ht | +----+----------+---------+----------+ | 2 | TechNote | 10.48 | NULL | | 6 | ExpertIT | 20.00 | NULL | +----+----------+---------+----------+ 2 rows in set (0.00 sec) mysql> -- Calculer les frais des collections qui nen ont pas. mysql> -- Formule = 0,4 centime x le nombre de pages moyen des mysql> -livres de la collection mysql> UPDATE collection col -> SET col.frais_ht = -> (SELECT ROUND(AVG(nombre_pages)/250,2) FROM l i v r e l i v -> WHERE l i v . i d _ c o l l e c t i o n = c o l . i d ) -> WHERE col.frais_ht IS NULL; Query OK, 1 row affected, 1 warning (0.00 sec) Rows matched: 2 Changed: 1 Warnings: 0 mysql> -- Vrifier (la collection 6 na pas de livre, donc mysql> -- les frais sont inchangs). mysql> SELECT * FROM collection WHERE id IN (2,6); +----+----------+---------+----------+ | id | nom | prix_ht | frais_ht | +----+----------+---------+----------+ | 2 | TechNote | 10.48 | 0.73 | | 6 | ExpertIT | 20.00 | NULL | +----+----------+---------+----------+ 2 rows in set (0.00 sec) Dansunerequte DELETE,lenomdetablespcifidanslaclause FROMnepeutpascomporterdalias.Pourrfrencer

ENI Editions - All rigths reserved

- 5-

unecolonnedelatablesupprimedanslasousrequtecorrle,ilfaututiliserlenomdelatable. Unerequte UPDATEou DELETEavecsousrequtecorrlepeuttrssouventtreremplaceparunerequte UPDATE ouDELETEmultitables.

5.SousrequtedanslaclauseFROM
Unesousrequteplacedanslaclause FROMdunerequte SELECTestutilisecommesourcededonnes onparle parfoisde"tabledrive"oude"vueenligne". Syntaxe (sous-requte) [AS] alias Une sousrequte utilise en clause FROM doit obligatoirement avoir un alias pour "nommer" la sousrequte. Par ailleurs, les expressions slectionnes dans la sousrequte doivent avoir des noms diffrents. Enfin, une sous requteutiliseenclauseFROMpeutavoiruneclauseORDER BY. Exemple mysql> -- Afficher le nom de la collection et le premier livre mysql> -- de la collection (ordre alphabtique du titre). mysql> SELECT col.nom,liv.titre -> FROM -> collection col -> JOIN -> (-- premier titre de la collection (ordre alphabtique) -> SELECT id_collection,MIN(titre) titre -> FROM livre GROUP BY id_collection -> ) liv -> ON (col.id = liv.id_collection); +--------------------------+--------------------------------+ | nom | titre | +--------------------------+--------------------------------+ | Ressources Informatiques | BusinessObjects 6 | | TechNote | Oracle 10g | | Les TP Informatiques | PHP et MySQL (versions 4 et 5) | | Coffret Technique | MySQL 5 et PHP 5 | +--------------------------+--------------------------------+ 4 rows in set (0.00 sec)

6.Insrerdesligneslaidedunesousrequte
Unesousrequtepeuttreutilisecommesourcededonnesdansunerequtedinsertion. Syntaxe INSERT [IGNORE] [INTO] nom_table [(nom_colonne,...)] sous-requte [ ON DUPLICATE KEY UPDATE nom_colonne=expression, ... ] LasousrequteremplacelaclauseVALUES lerestedelasyntaxeestinchang.Lasousrequtedoitretournerautant dexpressionsquilyadecolonnesinsrer. Exemple Crationdunenouvelletabledestinestockerdesinformationsstatistiquessurlescollections : mysql> CREATE TABLE statistique_collection -> ( -> collection VARCHAR(30) PRIMARY KEY, -> nombre_livres INT, -> premiere_parution YEAR(4) -> ); Query OK, 0 rows affected (0.05 sec)

- 6-

ENI Editions - All rigths reserved

Alimentationdelatable : mysql> INSERT INTO statistique_collection -> (collection,nombre_livres,premiere_parution) -> SELECT -> col.nom,COUNT(liv.id),MIN(liv.annee_parution) -> FROM -> livre liv JOIN collection col -> ON (liv.id_collection = col.id) -> GROUP BY -> col.nom -> ON DUPLICATE KEY UPDATE -> nombre_livres = VALUES(nombre_livres), -> premiere_parution = VALUES(premiere_parution); Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM statistique_collection; +--------------------------+---------------+-------------------+ | collection | nombre_livres | premiere_parution | +--------------------------+---------------+-------------------+ | Coffret Technique | 1 | 2006 | | Les TP Informatiques | 1 | 2004 | | Ressources Informatiques | 4 | 2004 | | TechNote | 3 | 2005 | +--------------------------+---------------+-------------------+ 4 rows in set (0.01 sec)

ENI Editions - All rigths reserved

- 7-

Runirlersultatdeplusieursrequtes
Depuis la version 4, MySQL supporte lutilisation de loprateur ensembliste UNION qui permet de runir le rsultat de plusieursrequtes. Syntaxe requte_SELECTUNION [ALL | DISTINCT] requte_SELECT [UNION ...] [ORDER BY tri] Les ordres SELECT doivent avoir le mme nombre dexpressions et les expressions correspondantes doivent normalementavoirlemmetype(selonladocumentation).Danslapratique,silesexpressionscorrespondantesnesont pasdummetype,ilsemblequellessontconvertiesenchanedecaractrespourfairelunion. Letitredescolonnesdursultatfinalestdfiniparlapremirerequte. Par dfaut, toutes les lignes retournes sont distinctes le mme rsultat est obtenu en utilisant loption DISTINCT. LutilisationdeloptionALLpermetdeconservertoutesleslignes,mmecellesdupliques. LesordresSELECTnedoiventpascontenirdeclause ORDER BY ilspeuventparcontrecontenirdesjointures,dessous requtes,ainsiquedesclauses WHERE,GROUP BY,etc.Pourrenforcerlalisibilitdelarequte,lesordres SELECTpeuvent tremisentreparenthse. LersultatfinaldelunionpeuttretriparuneclauseORDER BY,aveclammesyntaxequepourunordreSELECTsimple (cf.chapitreIntroductionMySQLExcuterdesrequtesSQLsimples). Exemples mysql> SELECT titre FROM catalogue -> UNION -> SELECT IFNULL(CONCAT(titre, - ,sous_titre),titre) -> FROM livre WHERE id_collection = 1; +------------------------------------------------------------------------+ | titre | +------------------------------------------------------------------------+ | Oracle 10g - Administration | | PHP 5 - Laccs aux donnes | | PHP 5.2 - Dvelopper un site Web dynamique et interactif | | BusinessObjects 6 | | MySQL 5 - Installation, mise en uvre, administration et programmation | +------------------------------------------------------------------------+ 5 rows in set (0.00 sec) mysql> SELECT titre FROM catalogue -> UNION A L L -> SELECT IFNULL(CONCAT(titre, - ,sous_titre),titre) -> FROM livre WHERE id_collection = 1; +------------------------------------------------------------------------+ | titre | +------------------------------------------------------------------------+ | Oracle 10g - Administration | PHP 5 - Laccs aux donnes | | PHP 5.2 - Dvelopper un site Web dynamique et interactif | | Oracle 10g - Administration | BusinessObjects 6 | | MySQL 5 - Installation, mise en uvre, administration et programmation | +------------------------------------------------------------------------+ 6 rows in set (0.00 sec) mysql> SELECT titre FROM catalogue -> UNION -> SELECT IFNULL(CONCAT(titre, - ,sous_titre),titre) -> FROM livre WHERE id_collection = 1 -> ORDER BY titre; +------------------------------------------------------------------------+ | titre | +------------------------------------------------------------------------+

ENI Editions - All rigths reserved

- 1-

| BusinessObjects 6 | | MySQL 5 - Installation, mise en uvre, administration et programmation | | Oracle 10g - Administration | | PHP 5 - Laccs aux donnes | | PHP 5.2 - Dvelopper un site Web dynamique et interactif | +------------------------------------------------------------------------+ 5 rows in set (0.00 sec)

- 2-

ENI Editions - All rigths reserved

Grerlestransactionsetlesaccsconcurrents
1.Dfinition
Danslaterminologiedesbasesdedonnesrelationnelles,unetransactionestunensembledordresdemisejourqui formeuntoutindissociabledupointdevuedelalogiqueapplicative.Lesordresdemisejourdunetransactionne peuventtredfinitivementenregistrsdanslabasededonnesquesilssesonttousexcutssanserreur siun desordresdemisejourchoue,touteslesmodificationsdjeffectuesdanslatransactiondoiventtreannules. la fin dune transaction, la base de donnes est toujours dans un tat cohrent du point de vue de la logique applicative. titre dexemple, considrons une transaction de virement bancaire qui serait constitue de trois ordres de mise jour :
q

unpremierUPDATEpourdbiterlepremiercompte undeuximeUPDATEpourcrditerledeuximecompte unINSERTpourenregistrerloprationdansunjournal.

Siledeuxime UPDATEchouepouruneraisonoupouruneautre,ilfautannulerlepremier UPDATEetnepaseffectuer lordreINSERT.

2.Grerlestransactions
Par dfaut, MySQL fonctionne dans un mode validation automatique (option AUTOCOMMIT gale 1) : chaque modificationeffectueestimmdiatementetdfinitivementenregistredanslabasededonnes,cequinepermetpas degrercorrectementlestransactions. Parailleurs,lagestiondestransactionsestsupporteuniquementpourlestypesdetableInnoDBetBDB. partirdumomentovousutilisezunetablequisupportelestransactions,vouspouvezgrerlestransactionslaide desinstructionssuivantes : START TRANSACTION | BEGIN [WORK] SET AUTOCOMMIT = { 0 | 1 } COMMIT [WORK] ROLLBACK [WORK] Lesinstructions START TRANSACTION ou BEGIN(WORKestoptionnel)permettentdedmarrerexplicitementunenouvelle transaction.Ilestconseilldutiliserdeprfrencelinstruction START TRANSACTIONquiestconformeaustandardSQL. Lorsquunetransactionestdmarreexplicitementdecettemanire,lavalidationautomatiqueestdsactiveletemps delatransaction lafindelatransaction,lavalidationautomatiquerevientdanssonttatprcdent. Linstruction SET AUTOCOMMIT permet dactiver (1) ou de dsactiver (0) la validation automatique pour la connexion courante. partirdumomentolavalidationautomatiqueestdsactive,ilnestpasncessairededmarrerexplicitementles transactions unenouvelletransactionestimplicitementdmarrelafindechaquetransaction. Linstruction COMMIT valide la transaction courante et enregistre dfinitivement les modifications dans la base de donnes.LinstructionROLLBACKannulelatransactioncouranteettouteslesmodificationseffectuesparlatransaction. Danslesdeuxcas,lemotclWORKestoptionnel. Pour illustrer le fonctionnement des transactions, nous allons travailler avec les tables commande et ligne_commande cresdanslachapitreConstruireunebasededonnesdansMySQLlaidedesordresSQLsuivants : CREATE TABLE commande ( id INT PRIMARY KEY AUTO_INCREMENT, date_commande DATE

ENI Editions - All rigths reserved

- 1-

) ENGINE innodb; CREATE TABLE ligne_commande ( id_commande INT, numero_ligne INT, article VARCHAR(50), quantite INT, prix_unitaire DECIMAL(8,2), PRIMARY KEY(id_commande,numero_ligne) ) ENGINE innodb; Cet exemple utilise des tables InnoDB. Pour permettre lutilisation des tables InnoDB, noubliez pas de mettre en commentaireleparamtreskip-innodbdanslefichierdeconfigurationdeMySQL. Exempledetransactionannule mysql> S T A R T T R A N S A C T I O N ; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO commande(date_commande) VALUES(NOW()); Query OK, 1 row affected (0.01 sec) mysql> SET @id = LAST_INSERT_ID(); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO ligne_commande -> (id_commande,numero_ligne,article,quantite,prix_unitaire) -> VALUES -> (@id,1,PHP 5.2,1,25); Query OK, 1 row affected (0.00 sec) mysql> R O L L B A C K ; Query OK, 0 rows affected (0.01 sec) mysql> SELECT * FROM commande; Empty set (0.01 sec) mysql> SELECT * FROM ligne_commande; Empty set (0.01 sec) Exempledetransactionvalide mysql> S T A R T T R A N S A C T I O N ; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO commande(date_commande) VALUES(NOW()); Query OK, 1 row affected (0.01 sec) mysql> SET @id = LAST_INSERT_ID(); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO ligne_commande -> (id_commande,numero_ligne,article,quantite,prix_unitaire) -> VALUES -> (@id,1,PHP 5.2,1,25); Query OK, 1 row affected (0.00 sec) mysql> C O M M I T ; Query OK, 0 rows affected (0.01 sec) mysql> SELECT * FROM commande; +----+---------------+ | id | date_commande | +----+---------------+ | 3 | 2008-01-25 | +----+---------------+ 1 row in set (0.00 sec)

- 2-

ENI Editions - All rigths reserved

mysql> SELECT * FROM ligne_commande; +-------------+--------------+---------+----------+---------------+ | id_commande | numero_ligne | article | quantite | prix_unitaire | +-------------+--------------+---------+----------+---------------+ | 3 | 1 | PHP 5.2 | 1 | 25.00 | +-------------+--------------+---------+----------+---------------+ 1 row in set (0.00 sec)

es ordres du langage de dfinition de donnes (LDD Data Definition Language en anglais), comme CREATE, L ALTER, DROP,nepeuventpastreannuls.Parailleurs,cesordresvalidentimplicitementlatransactionencours. Demme,activerlavalidationautomatique(SET AUTOCOMMIT = 1)oudmarrerunetransaction(START TRANSACTION) valideimplicitementlatransactionencours.

3.Annulerunepartiedunetransaction
Danscertainestransactionscomportantplusieursordresdemisejour,ilpeuttrencessairedannuleruniquement lesderniresmodifications. Vouspouvezannulerlesderniresmodificationsdunetransactionlaidedesinstructionssuivantes : SAVEPOINT nom ROLLBACK [WORK] TO [SAVEPOINT] nom RELEASE SAVEPOINT nom Linstruction SAVEPOINTpermetdedfinirunpointderetournommdanslasquencedesordresdemisejourdela transaction. Si un point de retour portant le mme nom tait dj dfini dans la transaction, il est remplac par le nouveau. Linstruction ROLLBACK TO(lesmotscls WORKet SAVEPOINTsontoptionnels)permetdannulertouteslesmodifications ralises depuis le point de retour indiqu. Les points de retour dfinis aprs le point de retour spcifi dans le ROLLBACK TOsontsupprims lepointderetourspcifidansle ROLLBACK TO estparcontreconserv.Latransaction en ellemme est toujours ouverte et toutes les modifications ralises avant le point de retour indiqu sont en attente. LinstructionRELEASE SAVEPOINTpermetdesupprimerunpointderetour. Touslespointsderetourdunetransactionsontsupprimslorsquelatransactionsetermine(COMMITouROLLBACK). Exemple mysql> S T A R T T R A N S A C T I O N ; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO commande(date_commande) VALUES(NOW()); Query OK, 1 row affected (0.01 sec) mysql> SET @id = LAST_INSERT_ID(); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO ligne_commande -> (id_commande,numero_ligne,article,quantite,prix_unitaire) -> VALUES -> (@id,1,MySQL 5,1,25); Query OK, 1 row affected (0.00 sec) mysql> S A V E P O I N T p 1 ; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO ligne_commande -> (id_commande,numero_ligne,article,quantite,prix_unitaire) -> VALUES -> (@id,2,PHP 7,1,25); Query OK, 1 row affected (0.00 sec)

ENI Editions - All rigths reserved

- 3-

mysql> R O L L B A C K T O S A V E P O I N T p 1 ; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO ligne_commande -> (id_commande,numero_ligne,article,quantite,prix_unitaire) -> VALUES -> (@id,2,PHP 5.2,1,25); Query OK, 1 row affected (0.00 sec) mysql> C O M M I T ; Query OK, 0 rows affected (0.01 sec) mysql> SELECT * FROM commande WHERE id = @id; +----+---------------+ | id | date_commande | +----+---------------+ | 4 | 2008-01-25 | +----+---------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM ligne_commande WHERE id_commande = @id; +-------------+--------------+---------+----------+---------------+ | id_commande | numero_ligne | article | quantite | prix_unitaire | +-------------+--------------+---------+----------+---------------+ | 4 | 1 | MySQL 5 | 1 | 25.00 | | 4 | 2 | PHP 5.2 | 1 | 25.00 | +-------------+--------------+---------+----------+---------------+ 2 rows in set (0.00 sec)

4.Concurrencedaccsetverrouillage
a.Concurrencedaccs
AucoursdunetransactionmettantjourdestablesInnoDB,MySQLposedesverrouspourviterdesmisesjour concurrentesquiseraientincorrectes. Lorsquune session effectue un UPDATE ou un DELETE sur une table InnoDB au cours dune transaction, deux cas peuventseproduire :
q

Lordre utilise un index pour trouver les lignes modifier ou supprimer dans ce cas, MySQL va poser un verrou exclusif de niveau ligne sur les lignes concernes. Dans ce cas, les autres sessions attendent lors dunetentativedemodificationoudesuppressiondeslignesverrouilles parcontre,ellespeuventmodifier ousupprimerdautreslignesnonverrouilles,oueninsrerdenouvelles(saufcasparticulier). Lordrenutilisepasdindexpourtrouverleslignesmodifierousupprimer danscecas,MySQLvaposerun verrou exclusif sur toutes les lignes de la table. Dans ce cas, les autres sessions attendent lors de toute tentativedemisejoursurlatable(INSERT,UPDATEouDELETE).

Danslesdeuxcas,lesautressessionspeuventinterrogerlatableavecunordre SELECT,maisellesnevoientpasles modifications non valides des autres sessions (pour plus de dtails voir ciaprs les explications sur le niveau disolation). Ilestpossibledeposerunverrousurdesligneslorsdelalectureenajoutantlaclause FOR UPDATElafindelordre SELECT. Si une ligne slectionne est dj verrouille par une autre transaction, le SELECT FOR UPDATE est mis en attente ilnesexcuteraetverrouilleraleslignesquelorsquelatransactionsetermine.Aupassage,leSELECT FOR UPDATEpermetdegarantirquelaligneretourneestbienladernirelignemisejourdanslabasededonneset quaucune mise jour non valide nest en cours sur cette ligne. Il faut noter que le SELECT FOR UPDATEverrouille toutesleslignesdelatablesilnepeutpasutiliserdindexpourslectionnerleslignes. tiliser linstruction SELECT FOR UPDATE est gnralement conseill pour grer proprement les situations o U deux utilisateurs sont susceptibles de modifier simultanment la mme ligne (notion de verrouillage "pessimiste"). Exemple1

- 4-

ENI Editions - All rigths reserved

Session1 mysql> -- pas de COMMIT automatique mysql> SET AUTOCOMMIT = 0; Query OK, 0 rows affected (0.00 sec) mysql> UPDATE ligne_commande -> S E T q u a n t i t e = 2 -> WHERE id_commande = 3; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> C O M M I T ; Query OK, 0 rows affected (0.02 sec) Session2 mysql> -- pas de COMMIT automatique mysql> SET AUTOCOMMIT = 0; Query OK, 0 rows affected (0.00 sec) mysql> SELECT quantite -> FROM ligne_commande -> WHERE id_commande = 3; +----------+ | quantite | +----------+ | 1 | +----------+ 1 row in set (0.01 sec) mysql> UPDATE ligne_commande -> SET quantite = 3 -> WHERE id_commande = 3; blocage ... ... au bout de quelques secondes ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> UPDATE ligne_commande -> SET quantite = 3 -> WHERE id_commande = 3; blocage ... Query OK, 1 row affected (3.42 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> COMMIT; Query OK, 0 rows affected (0.01 sec) Comme le montre lexemple cidessus, il y a un dlai dattente maximum lorsquun ordre est bloqu par un verrou posparuneautretransaction lorsqueledlaiestcouletquelordreesttoujoursbloqu,MySQLannulelordre enattenteetretourneunmessagederreur : ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction Exemple2 Session1 mysql> UPDATE ligne_commande -> S E T q u a n t i t e = 4 -> WHERE id_commande = 3; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> COMMIT; Query OK, 0 rows affected (0.00 sec)

ENI Editions - All rigths reserved

- 5-

mysql> SELECT quantite -> FROM ligne_commande -> WHERE id_commande = 3 -> FOR UPDATE; blocage ... ... au bout de quelques secondes ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction Session2 mysql> SELECT quantite -> FROM ligne_commande -> WHERE id_commande = 3 -> FOR UPDATE; blocage ... +----------+ | quantite | +----------+ | 2 | +----------+ 1 row in set (1.92 sec) Entermedeniveaudisolationdestransactions,lestablesInnoDBfonctionnentdanslemode REPEATABLE READ.Ce mode garantit que les SELECT excuts au cours de la transaction seront cohrents les modifications, mme valides,desautrestransactionseffectuesaprslapremirelectureseserontpasvues. En cas de besoin, le niveau disolationdune transaction peut tre modifi laide de linstruction SET TRANSACTION ISOLATION LEVEL(voirladocumentationMySQLsurlestablesInnoDBpourplusdinformations).

b.Verrouillerdestables
Danscertainessituations,ilpeuttreintressantdeverrouillerdestablespourlimiterlaccsdautresutilisateurs cestables. Unverroupeuttreobtenuenlectureouencriture. Unverrouen lecturepermetlasessionquiaposleverrouettouteautresessiondelirelatable parcontre, aucunesession(ycompriscellequiaposleverrou)nepeutcriredanslatable. Unverrouen criturepermetlasessionquiaposleverroudelireetdcriredanslatable lesautressessionsne peuventnilire,nicrire. VerrouilleretdverrouillerdestablesseffectuelaidedesinstructionsLOCK TABLESetUNLOCK TABLES. Syntaxe LOCK TABLES nom_table [AS alias] {READ|WRITE}[,...] UNLOCK TABLES QuandvousutilisezLOCK TABLES,vousdevezverrouillertouteslestablesquevousallezutiliser.Sivousutilisezdes alias dans linstruction LOCK TABLES, vous devez utiliser ces alias dans vos requtes. Si vous utilisez une table plusieursreprisesavecdesaliasdiffrents,vousdevezverrouillerplusieursfoislatableenmentionnantchaquealias. Sidesverroussontdjposspardautressessions,linstruction LOCK TABLESattendraquelesverrousenquestion soientlibrs. LesverrouspossparLOCK TABLESsontlibrsdanslescassuivants :
q

linstructionUNLOCK TABLESestexcute unenouvelleinstructionLOCK TABLEestexcute unetransactionestdmarre lasessionsetermine.

Normalement,vousnavezpasbesoindeverrouillerlestables.Lesdeuxcasprincipauxdutilisationduverrouillagede
- 6 ENI Editions - All rigths reserved

tablessontlessuivants :
q

pour amliorer les performances lorsque beaucoup de mises jour sont effectues sur plusieurs tables MyISAM (la raison en est que la mise jour des index sur disque est retarde jusquau dverrouillage des tables) poursimulerunetransactionlorsdelamisejourdetablesquinesupportentpaslestransactions.

Leverrouillagedetabledoittreutilisavecparcimoniecarillimitefortementlaconcurrencedaccs.

c.Verroumortel
MySQLsaitdtecterlessituationsdeverroumortelodeuxsessionssebloquentmutuellement danscecas,MySQL annulelordreloriginedelapparitionduverroumorteletretourneuneerreur : ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

ENI Editions - All rigths reserved

- 7-

Effectuerdesrechercheslaidedesexpressionsrgulires
MySQL permet de faire des recherches laide dexpressions rgulires. Les expressions rgulires permettent de spcifierdesmodlescomplexespourlarecherchesurleschanes. MySQL propose deux oprateurs de comparaison pour effectuer des recherches laide dexpressions rgulires : REGEXPetRLIKE(synonymedeREGEXP). Syntaxe expression [NOT] REGEXP modle expression [NOT] RLIKE modle modleestuneexpressionrgulirequidcritlastructuredelachanerecherche. Uneexpressionrgulirepeuttrespcifielaidedessymbolessuivants(conformelanormePOSIX) : Caractrespcial Signification Si^estprsentcommepremiercaractredumodle, indiquequelachanedoitcommencerparcequi suit :^abc :doitcommencerparabc. Si$estprsentcommederniercaractredumodle, indiquequelachanedoitterminerparcequiprcde : xyz$ :doitterminerparxyz. $ ^abcxyz$ :doitcommencerparabcxyzetseterminer parabcxyz(breftregalabcxyz !). Unmodlenecomportantni^ni$indiquequele modleestrecherchnimporteolintrieurdela chane :abc :contientabc. Indiquequelecaractrequiprcde,oulasquence quiprcde(voirciaprs),peuttreprsentezro, uneouplusieursfois :ab*caccepteac,abc,abbc... Indiquequelecaractrequiprcde,oulasquence quiprcde(voirciaprs),doittreprsenteuneou plusieursfois :ab+caccepteabc,abbc...,maisrefuse ac. Indiquequelecaractrequiprcde,oulasquence quiprcde(voirciaprs),peuttreprsentezroou unefois:ab?caccepteacetabcmaisrefuseabbc, abbbc... Indiquequelecaractrequiprcde,oulasquence quiprcde(voirciaprs),doittreprsente exactementxfois({x})ouauminimumxfois({x,})ou entrexetyfois({x,y}) : ab{2}cnacceptequeabbc. {x} {x,}{x,y} ab{2,4}caccepteabbc,abbbc,etabbbbcmaisrefuse abc(manqueunb)ouabbbbbc(unbdetrop). ab{2,}caccepteabbc,abbbc,abbbbc,...maisrefuseabc (manqueunb). Permetdemarquerunesquencerecherche, typiquementaveclessymbolesrelatifsaunombre doccurrences :a(bc)*dacceptead,abcd,abcbcd... maisrefuseabdouacd(lasquencebcnestpas trouve). Recherchedexoudey(gnralementutilisavecles

(...)

ENI Editions - All rigths reserved

- 1-

x|y

parenthsespourvitertouteconfusion) :a(b|c)*d acceptead,abd,acd,abcd,abbcd,accbd...(enclairun nombrequelconquedeboudecsitusdansnimporte quelordreentreunaetund). Permetdespcifierunesriedecaractresaccepts soitsouslaformec1c2...cnpourunelisteexhaustive prcise,soitsouslaformec1-c2pouruneplagede caractres,soitenmlangeantlesdeux : [abcd] accepteuncaractreparmiabcd(quivalent (a|b|c|d)). [a-z]accepteuncaractrecomprisentreaetz. [123a-zA-z]accepteuncaractrecomprisentreaetz oucomprisenAetZougal1ou2ou3.

[...]

[a-zA-z0-9]accepteuncaractrecomprisentreaetz ouentreAetZouentre0et9. Uneexclusionpeuttrespcifieenmettantun^en premiercaractrelintrieurdescrochets : [^0-9]refusetoutcaractrecomprisentre 0-9. [^abc]refuselescaractresa,betc. Comptetenudesasignificationparticulire,lesigne-, silestrecherchentantquetel,doitfigureren premierouendernierentrelescrochets. Indiqueuncaractrequelconque : a.bacceptetoutesquencecomportantunasuivi dexactementuncaractrequelconquesuividunb : axb,ayb,maispasabniaxyb. a.{0,2}bacceptetoutesquencecomportantuna suividezrodeuxcaractresquelconquessuividun b : ab,axb,,axyb,maispasaxyzb. Permetdchapperlescaractresspciaux( ^.[$()|*+? {\)lorsqueceuxcisontrecherchsentantquetel, sauflorsquilssontmentionnsentrecrochets :

a\*{2,4}bpermetderechercherlessquences commenantparunasuivide24toilessuiviesdun b(notezle\*). a[$*+]{2,4}bpermetderechercherlessquences commenantparunasuivide24caractrespris parmi$,*et+suivisdunb(pasbesoinde\)

[::] Lesclassesdecaractressontlessuivantes : [:alnum:] Caractresalphanumriques [:alpha:] Caractresalphabtiques [:blank:] Caractresblancs [:cntrl:]

Classedecaractres(voircidessous).

- 2-

ENI Editions - All rigths reserved

Caractresdecontrle [:digit:] Chiffres [:graph:] Caractresgraphiques [:lower:] Caractresalphabtiquesminuscules [:print:] Caractresgraphiquesoublancs [:punct:] Caractresdeponctuation [:space:] Espace,tabulation,nouvelleligne,retourchariot [:upper:] Caractresalphabtiquesmajuscules [:xdigit:] Caractresdeschiffreshexadcimaux Exemples mysql> -- Titres qui contiennent "php". mysql> SELECT titre FROM livre -> WHERE titre REGEXP php; +--------------------------------+ | titre | +--------------------------------+ | PHP 5.2 | | PHP 5 | | PHP et MySQL (versions 4 et 5) | | MySQL 5 et PHP 5 | +--------------------------------+ 4 rows in set (0.01 sec) mysql> -- Titres qui commencent par "php". mysql> SELECT titre FROM livre -> WHERE titre REGEXP ^php; +--------------------------------+ | titre | +--------------------------------+ | PHP 5.2 | | PHP 5 | | PHP et MySQL (versions 4 et 5) | +--------------------------------+ 3 rows in set (0.00 sec) mysql> -- Titres qui commencent par "php" suivi mysql> -- dun espace et dun chiffre. mysql> SELECT titre FROM livre -> WHERE titre REGEXP ^php [1-9]; +---------+ | titre | +---------+

ENI Editions - All rigths reserved

- 3-

| PHP 5.2 | | PHP 5 | +---------+ 2 rows in set (0.00 sec) mysql> -- Titres qui commencent par "php" suivi mysql> -- dun espace et dun numro de version mysql> -- sous la forme x.y. mysql> SELECT titre FROM livre -> WHERE titre REGEXP ^php [1-9]\.[0-9]; +---------+ | titre | +---------+ | PHP 5.2 | +---------+ 1 row in set (0.00 sec) mysql> -- Titres qui contiennent "mysql" et "php" mysql> -- dans nimporte quel ordre. mysql> SELECT titre FROM livre -> WHERE titre REGEXP ((mysql).*(php))|((php).*(mysql)); +--------------------------------+ | titre | +--------------------------------+ | PHP et MySQL (versions 4 et 5) | | MySQL 5 et PHP 5 | +--------------------------------+ 2 rows in set (0.00 sec)

L esrecherchesaveclesexpressionsrguliressontsensibleslacasseuniquementavecleschanesbinaires.

- 4-

ENI Editions - All rigths reserved

Effectuerdesrecherchesentexteintgral
1.Principes
MySQLpermetdeffectuerdesrecherchesdemotssurlensembleduntexte(oudeplusieurstextes). Pourutilisercettefonctionnalit,ilfaut :
q

crerunindexspcial,detypeFULLTEXT utiliserlafonctionMATCH AGAINSTdanslesrecherches.

Les index FULLTEXT peuvent tre crs sur des colonnes de type CHAR, VARCHAR ou TEXT, mais uniquement sur des tablesMyISAM.

2.CrationdelindexFULLTEXT
Les index FULLTEXT peuvent tre crs lors de la cration initiale de la table (dans lordre CREATE ultrieurement(parunordreALTER TABLEouunordreCREATE FULLTEXT INDEX). TABLE) ou

PourcrerunindexFULLTEXTdansunordreCREATE TABLEouALTER TABLE,ilfaututiliseruneclauseFULLTEXTsimilaire la clause INDEX prsente dans le chapitre Construire une base de donnes dans MySQL. Lordre CREATE FULLTEXT INDEX est une variante de lordre CREATE INDEX prsent dans le chapitre Construire une base de donnes dans MySQL. Syntaxe CREATE TABLE nom_table ( spcification_colonnes, FULLTEXT(nom_colonne[,...]) ) ALTER TABLE nom_table ADD F U L L T E X T ( n o m _ c o l o n n e [ , . . . ] ) CREATE F U L L T E X T INDEX nom_index ON nom_table(nom_colonne[,...]) Exemple mysql> CREATE FULLTEXT INDEX ix_texte -> ON livre(titre,sous_titre,description); Query OK, 9 rows affected (0.01 sec) Records: 9 Duplicates: 0 Warnings: 0

3.Effectuerunerechercheentexteintgral
a.Rechercheclassique
LafonctionMATCH AGAINSTpermetdeffectuerdesrecherchesentexteintgral. Syntaxe MATCH(nom_colonne[,...]) AGAINST (expression [IN BOOLEAN MODE | WITH QUERY EXPANSION]) La clause MATCH liste les colonnes dans lesquelles effectuer la recherche les colonnes spcifies doivent correspondreexactementlalistedescolonnesdunindexFULLTEXT. LaclauseAGAINSTpermetdespcifierlexpressionrecherche.

ENI Editions - All rigths reserved

- 1-

LesoptionsIN BOOLEAN MODEetWITH QUERY EXPANSIONsontprsentesparlasuite. Larechercheestinsensiblelacasse,mmeavecdeschanesbinaires. Lafonction MATCH AGAINSTretourneunnombrepositifquidonneleniveaudepertinencedelenregistrementvisvis delexpressionrecherche lafonctionretourne0silnyapasdesimilarit. Lorsque la fonction MATCH AGAINSTestutilisecommeconditiondansuneclause WHERE,seulesleslignesayantune pertinence diffrente de zro sont retournes, et les lignes retournes sont tries par dfaut par pertinence dcroissante(ligneslespluspertinentesenpremier). Lafonction MATCH AGAINSTpeuttreprsentedanslaclause SELECTafindevoirle"score"depertinencedechaque ligne. Lexpressionrecherchepeuttreunsimplemot,ouunelistedemots.Pardfaut,lesmotsde3lettresoumoins sontignors.Demme,ilexisteunelisteprdfiniedemotsexcluscarconsidrscommetropcommuns. Lapertinenceestbasesur:
q

lenombredemotsdanslaligne, lenombredemotsdistinctsdanslaligne, lenombretotaldemotsdanslaliste, lenombredelignesquicontiennentunmotenparticulier.

Un mot recherch prsent dans de nombreuses lignes aura un poids faible ou nul linverse, un mot recherch prsent dans peu de lignes aura un poids fort. Si un mot recherch est prsent dans plus de la moiti (50%) des enregistrementstrouvs,ilestexclu. Danslapratique,lesrsultatssontdautantpluspertinentsquelatablecontientungrandnombredelignes.Sila tablecontientpeudelignes,ladistributionstatistiquedesmotsnestsansdoutepaspertinente,etlesrecherches risquentdedonnerdesrsultatstranges. Exemple mysql> SELECT CONCAT(titre,\n ,sous_titre) titre FROM livre -> WHERE MATCH(titre,sous_titre,description) -> AGAINST(mysql); +------------------------------------------------------------------+ | titre | +------------------------------------------------------------------+ | MySQL 5 et PHP 5 Matrisez les sites web dynamiques | | MySQL 5 Installation, mise en uvre, administration et programmation | | PHP 5 Laccs aux donnes (MySQL, Oracle, SQL Server, SQLite...) | | PHP et MySQL (versions 4 et 5) Entranez-vous crer des applications professionnelles | +------------------------------------------------------------------+ 4 rows in set (0.01 sec) mysql> SELECT CONCAT(titre,\n ,sous_titre) titre FROM livre -> WHERE MATCH(titre,sous_titre,description) -> AGAINST(mysql,oracle) -> AND id_collection = 1; +------------------------------------------------------------------+ | titre | +------------------------------------------------------------------+ | Oracle 10g Administration | | MySQL 5 Installation, mise en uvre, administration et programmation | +------------------------------------------------------------------+ 2 rows in set (0.00 sec) mysql> SELECT CONCAT(titre,\n ,sous_titre) titre FROM livre -> WHERE MATCH(titre,sous_titre,description)

- 2-

ENI Editions - All rigths reserved

-> AGAINST(mysql,oracle,installation) -> AND id_collection = 1; +------------------------------------------------------------------+ | titre | +------------------------------------------------------------------+ | MySQL 5 Installation, mise en uvre, administration et programmation | | Oracle 10g Administration | +------------------------------------------------------------------+ 2 rows in set (0.00 sec)

b.Rechercheenmodeboolen
DanslaclauseAGAINST,loptionIN BOOLEAN MODEpermetdeffectuerunerechercheenmodeboolen. Danscecas,lexpressionrecherchepeutcontenirlesoprateurssuivants : + Indiquequelemotquisuitdoittreprsentdanslaligneretourne. - Indiquequelemotquisuitnedoitpastreprsentdanslaligneretourne. < Diminuelapertinencedumotquisuit. > Augmentelapertinencedumotquisuit. ~ Indiquequelemotquisuitauraunecontributionngativelapertinence(diminuelapertinencedelalignemaisne lexclutpascommeavecloprateur-). () Regroupeunelistedemots. * Caractrejoker(doitapparatrelafindumot). "" Recherchelaphraseentreguillemetstellequelle. Silexpressionnecontientaucunoprateur,lalignedoitconteniraumoinsundesmotsrecherchs lapertinencede laligneestdautantpluslevequellecontientplusdemotsrecherchs. Lesrechercheseffectuesdanslemodeboolennutilisentpasleseuilde50%etnetrientpasautomatiquementle rsultatparordredcroissantdepertinence.Deplus,cesrecherchespeuventfonctionnersansindex FULLTEXT,mais sont alors moins performantes. Les colonnes spcifies dans la clause MATCH nont pas besoin de correspondre exactementlalistedecolonnesdunindexFULLTEXT. Exemple mysql> -- MySQL et Oracle. mysql> SELECT CONCAT(titre,\n ,sous_titre) titre FROM livre -> WHERE MATCH(titre,sous_titre,description) -> AGAINST(+mysql +oracle IN BOOLEAN MODE); +------------------------------------------------------------------+ | titre | +------------------------------------------------------------------+

ENI Editions - All rigths reserved

- 3-

| PHP 5 Laccs aux donnes (MySQL, Oracle, SQL Server, SQLite...) | +------------------------------------------------------------------+ 1 row in set (0.01 sec) mysql> -- MySQL mais pas Oracle. mysql> SELECT CONCAT(titre,\n ,sous_titre) titre FROM livre -> WHERE MATCH(titre,sous_titre,description) -> AGAINST(+mysql -oracle IN BOOLEAN MODE); +------------------------------------------------------------------+ | titre | +------------------------------------------------------------------+ | MySQL 5 Installation, mise en uvre, administration et programmation | | PHP et MySQL (versions 4 et 5) Entranez-vous crer des applications professionnelles | | MySQL 5 et PHP 5 Matrisez les sites web dynamiques | +------------------------------------------------------------------+ 3 rows in set (0.00 sec) mysql> -- Installation de MySQL ou dOracle. mysql> SELECT CONCAT(titre,\n ,sous_titre) titre FROM livre -> WHERE MATCH(titre,sous_titre,description) -> AGAINST(+installation +(oracle,mysql) IN BOOLEAN MODE); +------------------------------------------------------------------+ | titre | +------------------------------------------------------------------+ | Oracle 10g Installation du serveur sous Windows/Linux - Oracle Net | | MySQL 5 Installation, mise en uvre, administration et programmation | +------------------------------------------------------------------+ 2 rows in set (0.00 sec)

c.Rechercheavecextensionderequte
DanslaclauseAGAINST,loptionWITH QUERY EXPANSIONpermetdeffectuerunerechercheavecextensionderequte. Danscemode,larechercheseffectueen2passes :
q

Lapremirepasseeffectuelarecherchedelexpressionetidentifielesmotslesplusfrquentsdursultat. Ladeuximepasserecherchealorslesmotslesplusfrquentstrouvsdanslersultatdelapremirepasse.

Cemodepermetdtendrelarechercheenaveugledestermesquisavrenttretrssouventassocisunmot recherch. Cemodederecherchedoitplutttrerservdesrecherchesquiportentsuruneexpressioncourte. Exemple mysql> SELECT CONCAT(titre,\n ,sous_titre) titre FROM livre -> WHERE MATCH(titre,sous_titre,description) -> AGAINST(sauvegarde); +------------------------------------------------------------------+ | titre | +------------------------------------------------------------------+ | Oracle 10g Sauvegarde et restauration de la base de donnes avec RMAN | +------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT CONCAT(titre,\n ,sous_titre) titre FROM livre -> WHERE MATCH(titre,sous_titre,description) -> AGAINST(sauvegarde W I T H Q U E R Y E X P A N S I O N ); +------------------------------------------------------------------+ | titre |

- 4-

ENI Editions - All rigths reserved

+------------------------------------------------------------------+ | Oracle 10g Sauvegarde et restauration de la base de donnes avec RMAN | | PHP 5 Laccs aux donnes (MySQL, Oracle, SQL Server, SQLite...) | | Oracle 10g Installation du serveur sous Windows/Linux - Oracle Net | | Oracle 10g Administration | +------------------------------------------------------------------+ 4 rows in set (0.00 sec) Sur cet exemple, MySQL a trouv le titre qui contient le mot "sauvegarde" puis a tendu la recherche aux mots associs,notamment"oracle".

4.Rglagedelarechercheentexteintgral
PlusieursvariablespeuventtredfiniesdanslefichierdeconfigurationdeMySQLafinderglerlefonctionnementde larechercheentexteintgral. La taille minimale et maximale des mots indexer sont dfinies dans les variables systmes ft_min_word_len (4 par dfaut)etft_max_word_len(84pardfaut). La liste prdfinie de mots exclus peut tre gre par lintermdiaire de la variable ft_stopword_file. Dans cette variable,vouspouvezindiquerlechemindunfichierquicontientvotrelistedemotsinterditspourlesrecherchesen texteintgral.Danscefichier,vouspouvezsaisirvotrelistedemotscommevouslesouhaitezenutilisantuncaractre nonalphanumriquecommedlimiteur(espace,virgule,retourlaligne).Pourdsactiverlefiltredemotsexclus,vous pouvezaffecterunechanevidelavariableft_stopword_file. Si vous le souhaitez, vous pouvez modifier une ou plusieurs des variables prcdentes avant de crer vos index FULLTEXT.Siunindex FULLTEXTadjtcr,ilfautlereconstruirepourquilprenneencomptelesnouvellesvaleurs. VouspouvezreconstruirelesindexdunetableaveclordreSQLsuivant : REPAIR TABLE nom_table QUICK

ENI Editions - All rigths reserved

- 5-

Dvelopperdesprogrammesstocks
1.Introduction
Lesprocduresstockesetlesfonctionssontunedesprincipalesnouveautsdelaversion5deMySQL. UnprogrammestockestunensembledordresSQLetdinstructionsprocdurales(structuresdecontrle,dclaration de variables, etc.) qui ralise une tche spcifique et qui est enregistr avec un nom dans la base de donnes. Le programmestockpeutensuitetreappelpartirdediffrentsenvironnementsdedveloppementpourexcuterla tcheenquestion. Utiliserdesprogrammesstocksoffreplusieursavantages :
q

Amliorerlesperformances
q

Lecodeeststockdanslabasededonnesetilyamoinsdchangeentreleclientetleserveur.

Rutiliserducode
q

Le code stock peut tre appel par dautres programmes qui nont pas besoin dimplmenter de nouveaulalogiqueapplicative.

Renforcerlintgritdesdonnes
q

Les rgles de gestion peuvent tre codes un seul endroit, dans les programmes stocks. Si les applications clientes nont pas le droit daccder directement aux tables mais doivent passer par les programmesstocks,lintgritdesdonnesestgarantie.

Ilexistedeuxtypesdeprogrammesstocks :
q

lesprocdures lesfonctions.

esprogrammesstocksrequirentlatableprocdanslabasemysql.Encasdemigrationpartirduneversion L antrieure la 5, pensez mettre jour vos tables de droit (voir la documentation MySQL pour le mode opratoire).

2.Gestiondesdroits
Lesprivilgessuivantssontncessairespourgrerlesprogrammesstocks :
q

CREATE ROUTINEpourcrerunprogrammestock ALTER ROUTINEpourmodifierousupprimerunprogrammestock(automatiquementattribuaucrateurdun programmestock).

Par ailleurs, pour crer un programme stock, il faut avoir les privilges adapts sur les objets (tables, vues, etc.) manipulsparleprogramme. Pour excuter un programme stock, lutilisateur doit disposer du privilge EXECUTE sur le programme en question (attribuautomatiquementaucrateurduprogramme). Pardfaut,unprogrammestocksexcute avec les droits du propritaire du programme stock. Cela signifie quun utilisateurquialedroitdexcuterunprogrammestocknapasbesoindavoirdesdroitssurlesobjets(tables,vues, etc.)manipulsparleprogramme.Cefonctionnementestintressantentermesdegestiondedroit :pouraccderaux objetsmanipulsparleprogrammestock,lutilisateurestobligdepasserparlexcutionduprogrammestockqui peutimplmentertouteslesrglesdegestionoudescuritadquates.

ENI Editions - All rigths reserved

- 1-

3.Gestiondesprogrammesstocks
Les ordres SQL CREATE PROCEDURE et CREATE FUNCTION permettent de crer une procdure stocke ou une fonction stocke. Syntaxe CREATE PROCEDURE [nom_base.]nom_programme ([ spcification_paramtre[,...]]) BEGIN instructions; END; CREATE FUNCTION [nom_base.]nom_programme ([ spcification_paramtre[,...]]) RETURNS type BEGIN instructions; END; spcification_paramtre = [ IN | OUT | INOUT ] nom_paramtre type nom_basedsignelabasededonnesdanslaquelleleprogrammestockdoittredfini.Pardfaut,leprogrammeest stockdanslabasededonnescourante. nom_programmespcifielenomduprogrammestock.CenomdoitrespecterlesrglesdenommagedesobjetsMySQL. typedsignetouttypededonnesMySQLvalide. La dfinition dunefonctioncomporteuneclause RETURNSquipermetdespcifierletypededonnesretournparla fonction. Le code de la fonction contient aussi obligatoirement une instruction RETURN qui permet de dfinir la valeur retourneparlafonction.LaclauseRETURNSetlinstructionRETURNnesontpasautorisspouruneprocdurestocke. Derrire le nom du programme, il est possible de dfinir une liste de paramtres. Si le programme nutilise pas de paramtres,unelistevide()doittrespcifie. Unparamtreestdfiniparunmodedepassationoptionnel,unnom,etuntypededonnes. LesmodesdepassationautorisssontIN(valeurpardfaut),OUTetINOUT : IN Paramtreenentre.UnparamtreINpermetauprogrammeappelantdepasserunevaleurauprogrammestock. Pourdonnerunevaleurauparamtre,leprogrammeappelantpeututilisernimportequelleexpression(variable, expressionlittrale,etc.).Sileprogrammestockmodifielavaleurduparamtre,lamodificationnestpasvisibledans leprogrammeappelant. OUT Paramtreensortie.UnparamtreOUTpermetauprogrammestockderetournerunevaleurauprogrammeappelant. Leprogrammeappelantdoitobligatoirementutiliserunevariablelorsdelappelpourrcuprerlavaleurretourne.La valeurinitialedunparamtreOUTlintrieurduprogrammestockesttoujoursNULL. INOUT Paramtreenentre/sortie.UnparamtreINOUTestinitialisparlappelantavecunevaleurvisibleparleprogramme stock.Cedernierpeutmodifierlavaleurduparamtreetlavaleurmodifieestretourneauprogrammeappelant.Le programmeappelantdoitobligatoirementutiliserunevariablelorsdelappelpourrcuprerlavaleurretourne. euls les paramtres IN sont autoriss pour les fonctions stockes, et le mode de passation ne doit pastre S indiqu(mmemettreINgnreuneerreur).

Les instructions qui composent le code du programme sont incluses entre les mots cls BEGIN et END. Si le code du programme ne comporte quune seule instruction (cas assez rare !), les mots cls BEGIN et END peuvent tre omis. Chaque instruction doit se terminer par un pointvirgule. Le code du programme peut contenir des dclarations (variable, gestionnaire derreur), des affectations de valeurs des variables, des structures de contrle (boucle, conditions)etdesordresSQL.

- 2-

ENI Editions - All rigths reserved

Lorsqueleprogrammestockestcraveclinterprteurlignedecommande mysql,ilnefautpasquelepointvirgule utilis pour marquer la fin des instructions du code du programme soit interprt par mysql. Avant de soumettre la dfinition de la procdure, il est ncessaire dutiliser la commande delimiter afin de modifier le dlimiteur de fin dinstructionutilisparleclientMySQL. Exemplessimples mysql> delimiter // mysql> mysql> CREATE PROCEDURE ps_creer_rubrique -> ( -> -- Titre de la nouvelle rubrique. -> IN p_titre VARCHAR(20), -> -- Identifiant de la rubrique parent. -> IN p_id_parent INT, -> -- Identifiant de la nouvelle rubrique. -> OUT p_id INT -> ) -> BEGIN -> /* -> ** Insrer la nouvelle rubrique et -> ** rcuprer lidentifiant affect. -> */ -> INSERT INTO rubrique (titre,id_parent) -> VALUES (p_titre,p_id_parent); -> SET p_id = LAST_INSERT_ID(); -> END; -> // Query OK, 0 rows affected (0.00 sec) mysql> CREATE FUNCTION fs_titre_long -> ( -> p_titre VARCHAR(100), -> p_sous_titre VARCHAR(100) -> ) -> RETURNS VARCHAR(210) -> BEGIN -> RETURN CONCAT(p_titre, - ,p_sous_titre); -> END; -> // Query OK, 0 rows affected (0.01 sec) mysql> delimiter ; mysql> LesdiffrentesvariantesdelordreSQL SHOW(cf.chapitreConstruireunebasededonnesdansMySQLObtenirdes informationssurlesbasesdedonnes)permettentdafficherdesinformationssurlesprogrammesstocks. Syntaxe SHOW CREATE {PROCEDURE | FUNCTION} nom_programme SHOW {PROCEDURE | FUNCTION} STATUS [ condition ] LesprogrammesstockspeuventtresupprimslaidedunordreSQLDROP. Syntaxe DROP {PROCEDURE | FUNCTION} [IF EXISTS] nom_programme

4.Excuterunprogrammestock
LordreSQLCALLpermetdexcuteruneprocdurestocke. Syntaxe CALL [nom_base.]nom_procdure[([expression,[...]])]

ENI Editions - All rigths reserved

- 3-

Silaprocdurestockenecomportepasdeparamtre,ellepeuttreappelesansparenthse. LeprogrammeappelantdoitutiliserdesvariablespourlepassagedesparamtresOUouINOUT. LordreCALLestutilisabledansunprogrammestockpourappeleruneprocdurestocke. Exemple mysql> CALL ps_creer_rubrique(Systme et rseau,NULL, @ i d ); Query OK, 1 row affected (0.01 sec) mysql> SELECT * FROM rubrique WHERE id = @ i d ; +----+-------------------+-----------+ | id | titre | id_parent | +----+-------------------+-----------+ | 18 | Systme et rseau | NULL | +----+-------------------+-----------+ 1 row in set (0.00 sec) Unefonctionstockepeuttreappeledansuneexpressioncommeunefonctionprdfinie. Exemple mysql> SELECT fs_titre_long(titre,sous_titre) FROM livre LIMIT 1; +----------------------------------------------------------+ | fs_titre_long(titre,sous_titre) | +----------------------------------------------------------+ | PHP 5.2 - Dvelopper un site Web dynamique et interactif | +----------------------------------------------------------+ 1 row in set (0.00 sec) Unprogrammestockappartientunebasededonnes.Pourtreappelpartirduneautrebasededonnes,le nomduprogrammedoittreprfixparlenomdelabasededonnesdanslaquelleileststock.Parailleurs,lorsque leprogrammestockestappel,ileffectueunchangementdebasededonnesimplicite,poursepositionnerdansla basededonnesdanslaquelleilestdfini labasededonnesdorigineestautomatiquementrestaurelafinde lexcution.

5.Structuredulangage
a.BlocBEGINEND
LesmotsclsBEGINetENDpermettentderegrouperdesinstructions. Syntaxe [label:] BEGIN instructions; END [label] lintrieurdubloc,chaqueinstructiondoitseterminerparunpointvirgule.Unbloc BEGIN ENDpeuttrevideetne conteniraucuneinstruction ! UnblocBEGIN ENDpeutcontenirdautresblocsBEGIN END danscecas,leblocimbriqudoitseterminerparunpoint virgulecommesilsagissaitduneinstruction. Exemple BEGIN INSERT INTO rubrique (titre,id_parent) VALUES (p_titre,p_id_parent); SET p_id = LAST_INSERT_ID(); END; Unbloc BEGIN ENDpeuttre"nomm"laidedunlabelsitudevantlemotclBEGINetsuffixparlecaractredeux points danscecas,lelabeldoittrerepris(sanslecaractredeuxpoint)surleENDfinaldubloc. LinstructionLEAVEpeuttreutilisepoursortirprmaturmentdunbloc.

- 4-

ENI Editions - All rigths reserved

Syntaxe LEAVE label PourpouvoirutiliserlinstructionLEAVElintrieurdunblocBEGIN END,cedernierdoittrenommlaidedunlabel.

b.Lesvariables
lintrieurdunbloc,lesvariableslocalesutilisesparleprogrammedoiventtredclareslaidedelinstruction DECLARE. Syntaxe DECLARE nom_variable[,...] type [DEFAULT expression] nom_variableestlenomdonnlavariable cenomdoitrespecterlesrglesdenommagedeMySQL. typeestletypededonnesdelavariable touttypededonnesMySQLvalidepeuttreutilis. Laclauseoptionnelle DEFAULTpermetdedonnerunevaleurpardfaut(initiale)lavariable touteexpressionvalide peuttreutilise.Silaclauseestabsente,lavariableestinitialiseNULL. Linstruction DECLARE peut comporter plusieurs noms de variables pour dclarer en une seule instruction plusieurs variablesquiaurontlemmetypededonnesetserontinitialisesaveclammevaleur. UnblocpeutcontenirplusieursinstructionsDECLARE. Unevariabledclaredansunblocpeuttreutilisdanscebloc,etdanslesblocsimbriqusdubloc.Linversenest pasvrai :unevariabledclaredansunblocimbriqunepeutpastreutilisedansleblocparent. Unblocparentetunblocimbriqupeuventdclarerunevariableportantlemmenommaiscesontdeuxvariables diffrentes. Dans le bloc imbriqu, la variable du bloc parent ne peut pas tre utilise (elle nest pas "visible" car "masque"parlavariabledemmenomdfiniedansleblocimbriqu).Dclarerainsideuxvariablesportantlemme nomnestdetoutefaonpasunebonneidedeprogrammation. Pouraffecterunevaleurunevariable,linstructionSETpeuttreutilise. Syntaxe SET nom_variable = expression [, nom_variable = expression ] [, ...] Ilestpossibledaffecterdesvaleursplusieursvariables(mmedetypesdiffrents)enuneseuleinstructionSET. Exemple BEGIN DECLARE v_id INT DEFAULT 0; DECLARE v_titre VARCHAR(20); DECLARE v_date DATE; SET v_date = CURRENT_DATE(); END; UnevaleurpeutaussitreaffecteunevariablelaidedelordreSQLSELECT INTO(voirciaprs).

c.IntgrationdordresSQL
PratiquementtouslesordresSQLdulangagepeuventtreintgrsdanslecodedunprogrammestock. LesordresSQLsuivantssontinterditsdanslesprogrammesstocks(procduresoufonctions) :
q

{LOCK | UNLOCK} TABLES LOAD DATAetLOAD TABLE USE

Encomplment,pourlesfonctions,lesordresSQLsuivantssontinterdits :

ENI Editions - All rigths reserved

- 5-

instructionsquifontexplicitementouimplicitementunCOMMITouunROLLBACK instructionsquiretournentunrsultatdirectementauclient(SELECTsansINTO,SHOW,etc.) modifierlatableutiliseparlordrequiadclenchlappeldelafonction appeleruneprocdurequiutiliseunordreinterditdanslesfonctions.

Un programme stock ne peut pas utiliser linstruction USE pour changer de base de donnes. Par contre, il peut rfrencerlesobjets(tables,vues,programmesstocks,etc.)duneautrebasededonnesenprfixantlenomdes objetsparlenomdelabasededonnesdanslaquelleilssontdfinis. LesordresSQLimbriqusdanslecodedunprogrammestockrespectentlasyntaxehabituelleetpeuventutiliserles paramtresetvariableslocalesduprogramme. Lorsquun ordre SQL SELECT est utilis tel quel lintrieur dune procdure stocke, le rsultat de la requte est envoy directement au programme appelant. Si la procdure contient plusieurs ordres SELECT de ce type, le programmeappelantdoitsupporterlarcuprationdeplusieursensemblesdersultats. Lutilisation directe dunordreSQL SELECT(oudetoutordrequiretourneunrsultatcomme SHOWparexemple)est interditpourunefonctionstocke. lintrieurdunprogrammestock,lordreSQLSELECT INTOpeuttreutilispourrcuprerlersultatdelarequte dansdesvariables. Syntaxe SELECT expression[,...] INTO nom_variable[,...] FROM ... LaclauseINTOdoitcontenirautantdevariablesquilyadexpressionsdansleSELECT. Aveccettesyntaxe,larequte SELECTdoitretournerauplusuneligne.Touteslesclauseshabituellesdelarequte SELECTpeuventtreutilises. Exemple CREATE PROCEDURE ps_creer_rubrique ( -- Titre de la nouvelle rubrique. IN p_titre VARCHAR(20), -- Titre de la rubrique parent. IN p_titre_parent VARCHAR(20), -- Identifiant de la nouvelle rubrique. OUT p_id INT ) BEGIN -- Identifiant de la rubrique parent. DECLARE v_id_parent INT; -- Lire lidentifiant de la rubrique parent. SELECT id INTO v_id_parent FROM rubrique WHERE titre = p_titre_parent; -- Insrer la nouvelle rubrique. INSERT INTO rubrique (titre,id_parent) VALUES (p_titre,v_id_parent); -- Lire lidentifiant de la nouvelle rubrique. SET p_id = LAST_INSERT_ID(); END;

d.Lesstructuresdecontrle
MySQLsupporteplusieursstructuresdecontrle :
q

Contrleconditionnel :IFetCASE Contrleitratif :LOOP,WHILEetREPEAT

Dans les descriptions de syntaxe qui suivent, instructions dsigne une ou plusieurs instructions, ou un bloc
- 6 ENI Editions - All rigths reserved

dinstructions. Lesstructuresdecontrlepeuventtreimbriques. IF Syntaxe IF condition THEN instructions [ELSEIF condition THEN instructions] ... [ELSE instructions] END IF Lesconditionsdesclauses IFet ELSEIFsonttestessquentiellement.Silaconditionestvraiealorslesinstructions associes de la clause THEN sont excutes si aucune des conditions nest vraie, les instructions dfinies dans la clauseELSEsontexcutes. Exemple CREATE PROCEDURE ps_calculer_frais_collection(p_id INT) BEGIN -- Prix de la collection. DECLARE v_prix_ht INT; -- Frais de la collection. DECLARE v_frais_ht INT; -- Lire le prix de la collection. SELECT prix_ht INTO v_prix_ht FROM collection WHERE id = p_id; -- Calculer les frais de la collection. IF v_prix_ht <= 15 THEN SET v_frais_ht = 1; ELSEIF v_prix_ht <= 40 THEN SET v_frais_ht = 1.5; ELSE SET v_frais_ht = 2; END IF; -- Mettre jour les frais dans la table. UPDATE collection SET frais_ht = v_frais_ht WHERE id = p_id; END;

CASE Syntaxe1 CASE expression_test WHEN expression THEN instructions [WHEN expression THEN instructions] ... [ELSE instructions] END CASE Syntaxe2 CASE WHEN condition THEN instructions [WHEN condition THEN instructions] ... [ELSE instructions] END CASE Dans la premire syntaxe, expression_test est une expression qui est value une fois et dont la valeur est comparesquentiellementaveclesexpressionsdesclauses WHEN.Si expression_testestgalelexpressiondela clause WHEN, alors les instructions associes de la clause THENsontexcutes siaucunegalitnest trouve, les

ENI Editions - All rigths reserved

- 7-

instructionsdfiniesdanslaclauseELSEsontexcutes. Dans la deuxime syntaxe, les conditions des clauses WHEN sont testes squentiellement. Si la condition est vraie alors les instructions associes de la clause THEN sont excutes si aucune des conditions nest vraie, les instructionsdfiniesdanslaclauseELSEsontexcutes. Dans les deux cas, la clause ELSE est optionnelle mais si cette clause est omise et quaucune galit ou condition nestvraie,uneerreurestleve : ERROR 1339 (20000): Case not found for CASE statement Pourvitercetteerreur,vouspouvezdfiniruneclauseELSEquinefaitriengrceunblocBEGIN ENDvide. Exemple BEGIN ... -- Calculer les frais de la collection. CASE WHEN v_prix_ht <= 15 THEN SET v_frais_ht = 1; WHEN v_prix_ht <= 40 THEN SET v_frais_ht = 1.5; ELSE SET v_frais_ht = 2; END CASE; ... END;

LOOP Syntaxe [label:] LOOP instructions END LOOP [label] Lastructure LOOPimplmenteunesimplebouclequipermetlexcutionrpteduneoudeplusieursinstructions.Un label peut tre utilis pour nommer la boucle dans ce cas, le label doit tre repris dans le END LOOP. Nommer la boucleavecunlabelestobligatoirepourpouvoirutiliserlesinstructionsLEAVEetITERATE(voircidessous). Poursortirdelaboucle,ilfaututiliserlinstructionLEAVEprsenteprcdemment. Exemple BEGIN DECLARE v_indice INT DEFAULT 0; boucle: LOOP SET v_indice = v_indice + 1; IF v_indice = 10 THEN LEAVE boucle; END IF; END LOOP boucle; END;

ttention aux conditions NULL. Une condition NULL (rsultant par exemple dun test sur une variable non A initialise)nestpasTRUE.SilaconditiontestedansleIFnedevientjamaisvraie,labouclesexcutesansfin.

LinstructionITERATEpeuttreutilisepourpasserimmdiatementlitrationsuivante. Syntaxe ITERATE label

- 8-

ENI Editions - All rigths reserved

REPEAT Syntaxe [label:] REPEAT instructions UNTIL condition END REPEAT [label] Les instructions lintrieur de la boucle sont excutes jusqu ce que la condition de la clause UNTIL soit vraie (TRUE).Unlabelpeuttreutilispournommerlaboucle danscecas,lelabeldoittrereprisdansleENDREPEAT. Exemple BEGIN DECLARE v_indice INT DEFAULT 0; REPEAT SET v_indice = v_indice + 1; UNTIL v_indice = 10 END REPEAT; END; LesinstructionsLEAVEetITERATEpeuventtreutiliseslintrieurdelaboucle,quidoitdanscecastreforcment nommelaidedunlabel. SilaconditiondelaclauseUNTILnedevientjamaisvraie(resteFALSEouNULL),labouclesexcutesansfin.

WHILE Syntaxe [label:] WHILE condition DO instructions END WHILE [label] Lesinstructionslintrieurdelabouclesontexcutestantquelaconditiondelaclause WHILEestvraie.Unlabel peuttreutilispournommerlaboucle danscecas,lelabeldoittrereprisdansleEND WHILE. Exemple BEGIN DECLARE v_indice INT DEFAULT 0; WHILE v_indice < 10 DO SET v_indice = v_indice + 1; END WHILE; END; LesinstructionsLEAVEetITERATEpeuventtreutiliseslintrieurdelaboucle,quidoitdanscecastreforcment nommelaidedunlabel. SilaconditiondelaclauseWHILEestNULL,labouclenesexcutepas.

e.Lagestiondeserreurs
Lagestiondeserreursdexcutionseffectuelaidedeconditionsetdegestionnaires( handler). Uneconditionestenfaitunmoyendenommerdeserreursspcifiques.Uneconditionpeuttredclarelaidede linstructionDECLARE. Syntaxe DECLARE nom_condition CONDITION FOR code_erreur_mysql | SQLSTATE [VALUE] code_erreur_sql

ENI Editions - All rigths reserved

- 9-

nom_conditionestlenomdonnlacondition. UneconditionpeuttreassocieuncodederreurMySQLouuncodederreurSQL(clauseSQLSTATE). Les codes derreurs SQL et MySQL sont dcrits dans la documentation MySQL. Dans linterface ligne de commande mysql,leserreurssontaffichesdelamaniresuivante : ERROR code_erreur_mysql (code_erreur_sql) : message LecodederreurMySQLestunnombre lecodederreurSQLestunechanede5caractres. Ungestionnairepermetdedfinirlesinstructionsexcuterlorsquuneerreurseproduit.Ungestionnairepeuttre dclarlaidedelinstructionDECLARE. Syntaxe DECLARE {CONTINUE|EXIT} HANDLER FOR condition [,...] instructions condition = SQLSTATE code_erreur_sql | code_erreur_mysql | SQLWARNING | NOT FOUND | SQLEXCEPTION | nom_condition instructions spcifie les instructions excuter lorsque la condition derreur se produit. Il peut sagir dune instruction unique ou dun bloc dinstructions (dlimit par les mots cls BEGIN et END). Un gestionnaire peut tre associplusieursconditionsderreur. Lesvaleurspossiblespourlaconditionderreursontlessuivantes : SQLSTATE code_erreur_sql UncodederreurSQL. code_erreur_mysql UncodederreurMySQL. SQLWARNING UncodederreurSQLquicommencepar01. NOT FOUND UncodederreurSQLquicommencepar02. SQLEXCEPTION UncodederreurSQLquinecommencenipar01nipar02. nom_condition UneconditionderreurdfinieaupralableaveclinstructionDECLARE... CONDITION. Les mots cls CONTINUE et EXIT permettent de dfinir ce qui se passe aprs lexcution des instructions du gestionnaire. Avec CONTINUE, lexcution du programme se poursuit. Avec EXIT, lexcution du bloc BEGIN END qui contientladclarationdugestionnairesetermine sileblocestimbriqudansunblocparent,lexcutionpeutpar contresepoursuivredansleblocparent(ilnyaplusderreur,puisquelleatintercepte). Siuneerreurseproduitetquaucungestionnairenatdfinipourcetteerreur,lactionpardfautestEXIT. Uneerreurpeuttreignoreenutilisantunblocvidedanslegestionnaire : DECLARE ... HANDLER FOR ... B E G I N E N D Lorsdelutilisationdeblocsimbriqus,leserreurssepropagentdelamaniresuivante :
q

Si une erreur se produit dans un bloc imbriqu et que cette erreur est gre (intercepte) dans le bloc
ENI Editions - All rigths reserved

- 10 -

imbriqu,lexcutionpeutsepoursuivresoitdansleblocimbrique(gestionnaire CONTINE)soitdanslebloc parent(gestionnaireEXIT).


q

Si une erreur se produit dans un bloc imbriqu et que cette erreur nest pas gre dans le bloc imbriqu, lexcution du bloc imbriqu se termine (EXIT par dfaut) et MySQL recherche un gestionnaire pour lerreur dansleblocparent.Silnyenapas,lexcutiondublocparentsetermineaussi(EXITpardfaut) silyena un, il est excut et lexcution se poursuit ou non dans le bloc parent selon la nature du gestionnaire (CONTINUEouEXIT).

Exemple mysql> CREATE PROCEDURE ps_creer_rubrique -> ( -> -- Titre de la nouvelle rubrique. -> IN p_titre VARCHAR(20), -> -- Titre de la rubrique parent. -> IN p_titre_parent VARCHAR(20), -> -- Identifiant de la nouvelle rubrique. -> OUT p_id INT -> ) -> BEGIN -> -- Identifiant de la rubrique parent. -> DECLARE v_id_parent INT; -> -- Indicateur dexistence de la rubrique parent. -> DECLARE v_parent_existe BOOLEAN; -> -- Lire lidentifiant de la rubrique parent -> -- (si le titre de la rubrique parent pass en -> -- paramtre est non vide). -> IF p_titre_parent IS NOT NULL -> THEN -> -- Utiliser un bloc imbriqu avec un -> -- gestionnaire derreur. -> -- Si le parent nest pas trouv, positionner -> -- lindicateur FALSE et quitter le sous-bloc. -> BEGIN -> DECLARE EXIT HANDLER FOR NOT FOUND -> SET v_parent_existe = FALSE; -> SELECT id INTO v_id_parent -> FROM rubrique WHERE titre = p_titre_parent; -> SET v_parent_existe = TRUE; -- cest bon ! -> END; -> ELSE -> -- Pas de rubrique parent pass en paramtre. -> -- Considrer que le parent existe. -> SET v_parent_existe = TRUE; -> END IF; -> -- Si le parent existe -> IF v_parent_existe -> THEN -> -- Insrer la nouvelle rubrique. -> INSERT INTO rubrique (titre,id_parent) -> VALUES (p_titre,v_id_parent); -> -- Lire lidentifiant de la nouvelle rubrique. -> SET p_id = LAST_INSERT_ID(); -> ELSE -> -- La rubrique parent nexiste pas, retourner -1. -> SET p_id = -1; -> END IF; -> END; -> // Query OK, 0 rows affected (0.01 sec) mysql> delimiter ; mysql> mysql> -- Crer une rubrique parent. mysql> CALL ps_creer_rubrique(Bureautique,NULL,@id); Query OK, 1 row affected (0.00 sec)

ENI Editions - All rigths reserved

- 11 -

mysql> SELECT * FROM rubrique WHERE id = @id; +----+-------------+-----------+ | id | titre | id_parent | +----+-------------+-----------+ | 19 | Bureautique | NULL | +----+-------------+-----------+ 1 row in set (0.00 sec) mysql> -- Crer une sous-rubrique de la rubrique "Bureautique". mysql> CALL ps_creer_rubrique(Tableur,Bureautique,@id); Query OK, 1 row affected (0.01 sec) mysql> SELECT * FROM rubrique WHERE id = @id; +----+---------+-----------+ | id | titre | id_parent | +----+---------+-----------+ | 20 | Tableur | 19 | +----+---------+-----------+ 1 row in set (0.00 sec) mysql> -- Crer une sous-rubrique pour une rubrique parent mysql> -- qui nexiste pas. mysql> CALL ps_creer_rubrique(Suite, B u r o t i k ,@id); Query OK, 0 rows affected (0.00 sec) mysql> SELECT @id; +------+ | @id | +------+ | -1 | +------+ 1 row in set (0.00 sec)

f.Lescurseurs
UncurseurestuneconstructiondulangagequipermetdeparcourirlersultatdunerequteSELECT. Lutilisation dun curseur est similaire au parcours dun fichier squentiel. Lutilisation dun curseur ncessite 4 tapes :
q

dclarerlecurseur ouvrirlecurseur lirelalignecourantedansdesvariables fermerlecurseur.

UncurseurpeuttredclarlaidedelinstructionDECLARE. Syntaxe DECLARE nom_curseur CURSOR FOR ordre_SELECT nom_curseurestlenomdonnaucurseur. ordre_SELECT dfinit la requte SQL du curseur. Toutes les clauses habituelles dune requte SELECT (sauf INTO) peuventtreutilises.Larequtenestpasexcutecestade. Unprogrammepeututiliserplusieurscurseurs(avecdesnomsdiffrents). L escurseursdoiventtredclarsaprslesvariablesetlesconditionsmaisavantlesgestionnaires. LinstructionOPENpermetdouvriruncurseurdfiniaupralable. Syntaxe

- 12 -

ENI Editions - All rigths reserved

OPEN nom_curseur Lorsdelouvertureducurseur,larequteestexcuteetunpointeurinterneestpositionnsurlapremirelignedu rsultat aucunrsultatnestretourn. Linstruction FETCH permet de lire la ligne courante du curseur dans des variables et de faire avancer le pointeur internesurlalignesuivante. Syntaxe FETCH nom_curseur INTO nom_variable[,...] LaclauseINTOdoitcontenirautantdevariablesquilyadexpressionsdansleSELECTducurseur. Silnyaplusaucunelignelire,linstructionFETCHlvelerreur"Nodata" : ERROR 1329 (02000): No data - zero rows fetched, selected, or processed UngestionnaireassocilaconditionNOT FOUNDpeuttrecritpourdtectercetteerreur(voirciaprs). LinstructionCLOSEpermetdefermeruncurseurouvertaupralable. Syntaxe CLOSE nom_curseur Laplupartdutemps,leprogrammedoitlireetextrairetoutesleslignesducurseur.Pourfairecela,linstructionFETCH estcritedansunestructuredecontrleitrativeetungestionnaireassocilaconditionNOT FOUNDestcritpour dtecterlafinducurseuretpermettreunesortiedebouclepropre(sanserreur). Exemple mysql> delimiter // mysql> mysql> CREATE FUNCTION fs_rubriques_livre -> ( -> p_id_livre INT -- identifiant dun livre -> ) -> RETURNS TEXT -> BEGIN -> -- Titre dune rubrique. -> DECLARE v_titre VARCHAR(20); -> -- Rsultat de la fonction. -> DECLARE v_resultat TEXT DEFAULT ; -> -- Indicateur de fin de parcours du curseur. -> DECLARE v_fin BOOLEAN DEFAULT FALSE; -> -- Curseur qui slectionne les rubriques (parents) -> -- dun livre. -> DECLARE cur_rubriques CURSOR FOR -> SELECT -> rub.titre -> FROM -> rubrique rub -- rubrique parent -> JOIN -> rubrique sru -- sous-rubrique -> ON (rub.id = sru.id_parent) -> JOIN -> rubrique_livre rul -- (sous-)rubrique dun livre -> ON (sru.id = rul.id_rubrique) -> WHERE rul.id_livre = p_id_livre; -> -- Gestionnaire de dtection de la fin du curseur. -> DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_fin = TRUE; -> -- Ouvrir le curseur. -> OPEN cur_rubriques; -> -- Boucle permettant de parcourir le rsultat du curseur. -> curseur: LOOP -> -- Lire la ligne courante du curseur. -> FETCH cur_rubriques INTO v_titre; -> -- Quitter la boucle si tout a t lu.

ENI Editions - All rigths reserved

- 13 -

-> IF v_fin -> THEN -> LEAVE curseur; -> END IF; -> -- Ajouter la rubrique dans la liste. -> SET v_resultat = CONCAT(v_resultat,,,v_titre); -> END LOOP curseur; -> -- Fermer le curseur. -> CLOSE cur_rubriques; -> -- Retourner le rsultat (enlever la virgule de tte). -> RETURN TRIM(, FROM v_resultat); -> END; -> // Query OK, 0 rows affected (0.00 sec) mysql> delimiter ; mysql> mysql> -- Test de la fonction. mysql> SELECT titre,fs_rubriques_livre(id) rubriques -> FROM livre LIMIT 1 ; +---------+------------------------------------+ | titre | rubriques | +---------+------------------------------------+ | PHP 5.2 | Dveloppement,Internet,Open Source | +---------+------------------------------------+ 1 row in set (0.00 sec)

g.Rcursivit
Les procdures rcursives (procdure qui sappelleellemme) sont autorises sous rserve de donner une valeur diffrentedezrolavariablesystmemax_sp_recursion_depth(maximumautoris=255). Lesfonctionsrcursivessontinterdites.

- 14 -

ENI Editions - All rigths reserved

Dvelopperdestriggers
1.Dfinition
Un trigger (dclencheur en franais) est un programme stock associ une table et qui se dclenche automatiquementlorsquunvnementdemisejour(INSERT,UPDATEouDELETE)survientsurlatable.Untriggernest jamaisexplicitementexcutparunautreprogramme. Lestriggerspermettentdimplmenterdesrglesdegestionctserveur.Lesprincipalesutilisationsdestriggerssont lessuivantes :
q

Calculer automatiquement la valeur dune colonne : par exemple, un trigger peut tre utilis pour calculer automatiquementunprixTTCpartirdunprixHTetduntauxdeTVA. Auditer les mises jour effectues dans la base de donnes : par exemple, chaque fois quun article est supprim,untriggergardelatracedelasuppression(qui,quand,quoi)dansunetabledaudit.

LestriggerssontsupportsdansMySQLdepuislaversion5.0.2.

2.Gestiondestriggers
LordreSQLCREATE TRIGGERpermetdecreruntrigger. Syntaxe : CREATE TRIGGER [nom_base.]nom_trigger {BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON nom_table FOR EACH ROW BEGIN instructions; END; nom_base dsigne la base de donnes dans laquelle le trigger doit tre dfini. Par dfaut, le programme est stock danslabasededonnescourante. nom_triggerspcifielenomdutrigger.CenomdoitrespecterlesrglesdenommagedesobjetsMySQL. nom_tablespcifielatablelaquelleletriggerestassoci latableetletriggerdoiventtrestocksdanslamme basededonnes. Laclause BEFOREou AFTERpermetdindiquerquelmomentletriggersedclenche :justeavantquelamisejourse produise(BEFORE)oujusteaprs( AFTER). LemotclINSERT,UPDATEouDELETEindiquesurquelordreSQLdemisejourletriggerdoitsedclencher.Ilfautnoter que linstruction LOAD DATA dclenche les triggers INSERT linverse les instructions DROP TABLE et TRUNCATE ne dclenchentpaslestriggersDELETE. La clause FOR EACH ROW indique que le trigger se dclenche pour chaque ligne mise jour (trigger de niveau ligne). MySQL ne supporte pas (encore ?) les triggers de niveau instruction qui ne se dclencheraient quune fois pour la totalitdelordre,indpendammentdunombredelignesmisesjour. Ilnepeutpasyavoirdeuxtriggersdfinissurunemmetableaveclesmmesconditionsdedclenchement. LesinstructionsquicomposentlecodedutriggersontinclusesentrelesmotsclsBEGINetEND.Silecodedutriggerne comportequuneseuleinstruction,lesmotsclsBEGINetENDpeuventtreomis.Lecodeduntriggerutiliselesmmes constructions et les mmes rgles de syntaxe que les programmes stocks. Les programmes stocks peuvent tre appelsdanslecodeduntrigger. Dans le code du trigger, il est possible de faire rfrence ligne en cours de mise jour grce aux identifiants prdfinisOLDetNEW. Syntaxe OLD.nom_colonneNEW.nom_colonne

ENI Editions - All rigths reserved

- 1-

OLD.nom_colonnedonnelanciennevaleurdelacolonne(avantlamisejour) OLD.nom_colonnenepeutpastreutilis dansuntriggerINSERT(pasdanciennevaleur). NEW.nom_colonne donne la nouvelle valeur de la colonne (aprs la mise jour) NEW.nom_colonne ne peut pas tre utilisdansuntriggerDELETE(pasdenouvellevaleur). Dans un trigger BEFORE, il est possible de modifier les nouvelles valeurs des colonnes en modifiant les identifiants NEW.nom_colonnelaideduneinstructionSET. EW.nom_colonnenepeutpastremodifidansuntrigger AFTER.Parailleurs, OLD.nom_colonnenepeutjamais N tremodifi. La lecture de NEW.nom_colonne ou OLD.nom_colonne ncessite le privilge SELECT sur la table la modification de NEW.nom_colonnencessiteleprivilgeUPDATEsurlatable. Dansuntrigger BEFORE,lavaleurdescolonnes AUTO_INCREMENTestdtermineaprslexcutiondestriggers BEFORE pourunecolonneAUTO_INCREMENT,dansuntriggerBEFORE,NEW.nom_colonnevauttoujours0. Exemple mysql> delimiter // mysql> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> CREATE TRIGGER tr_calculer_frais_collection BEFORE INSERT ON collection FOR EACH ROW BEGIN -- Calculer les frais de la collection sils sont -- vides ou gaux zro. IF IFNULL(NEW.frais_ht,0) = 0 THEN -- Le montant des frais dpend du prix de vente H.T. CASE WHEN NEW.prix_ht <= 15 THEN SET NEW.frais_ht = 1; WHEN NEW.prix_ht <= 40 THEN SET NEW.frais_ht = 1.5; ELSE SET NEW.frais_ht = 2; END CASE; END IF; END; //

mysql> delimiter ; mysql> -- Insrer une nouvelle collection sans mentionner les frais. mysql> INSERT INTO collection(nom,prix_ht) -> VALUES(Epsilon,48.63); Query OK, 1 row affected (0.01 sec) mysql> -- Vrifier le rsultat. mysql> SELECT * FROM collection WHERE id = LAST_INSERT_ID(); +----+---------+---------+----------+ | id | nom | prix_ht | frais_ht | +----+---------+---------+----------+ | 9 | Epsilon | 48.63 | 2.00 | +----+---------+---------+----------+ 1 row in set (0.01 sec) LesdiffrentesvariantesdelordreSQL SHOW(cf.chapitreConstruireunebasededonnesdansMySQLObtenirdes informationssurlesbasesdedonnes)permettentdafficherdesinformationssurlestriggers. Syntaxe SHOW CREATE TRIGGER nom_triggerSHOW TRIGGERS [FROM nom_base] [ condition ]

- 2-

ENI Editions - All rigths reserved

UntriggerpeuttresupprimlaidedelordreDROP TRIGGER. Syntaxe DROP TRIGGER [IF EXISTS] [nom_base.]nom_trigger Lorsdelasuppressiondunetable,lestriggersassocissontsupprims.

3.Considrationssurlutilisationdestriggers
a.Restrictions
LesrestrictionssurlesordresSQLutilisablesdansuntriggersontlesmmesquepourlesfonctions :
q

InstructionsquifontexplicitementouimplicitementunCOMMITouunROLLBACK Instructionsquiretournentunrsultatdirectementauclient(SELECTsansINTO,SHOW,etc.) Modifierlatableutiliseparlordrequiadclenchletrigger Appeleruneprocdurequiutiliseunordreinterditdanslestriggers.

Deplus,linstruction RETURNestinterditedanslecodeduntrigger parcontre,linstruction LEAVEpeuttreutilise pourquitterimmdiatementuntrigger. Lestriggersnesontpasdclenchsparlessuppressionsencascadedesclstrangres.

b.Rsultatencasderreur
Le rsultat obtenu en cas dchec du trigger ou de lordre lorigine du dclenchement du trigger dpend de la naturedelatable. Tablenontransactionnelle Siuntrigger BEFOREchouepouruneligne,lamisejournestpasexcutesurlaligneconcerneetlinstruction loriginedudclenchementdutriggersarrte parcontre,leslignesdjmisesjouretlesoprationsventuelles effectuesparletriggersontconserves. SiuntriggerAFTERchouepouruneligne,lamisejour(dj)effectuesurlaligneconcernenestpasannuleet linstructionloriginedudclenchementdutriggersarrte parcontre,leslignesdjmisesjouretlesoprations ventuelleseffectuesparletriggersontconserves. Si la mise jour choue pour une ligne, les triggers AFTER ne sont pas excuts pour la ligne en question par contre,lestriggersBEFOREontdjtsexcutspourlaligneenquestion.Danslesdeuxcas,leslignesdjmises jouretlesoprationsventuelleseffectuesparlestriggerssontconserves. Tabletransactionnelle Pour une table transactionnelle, cest plus simple : en cas derreur (dans un trigger ou dans la mise jour dune ligne),toutcequiateffectudepuisledbutdelordreestannul.

ENI Editions - All rigths reserved

- 3-

QuestcequePHP ?
PHPestunlangagedescriptquisexcutectserveur,lecodePHPtantinclusdansunepageHTMLclassique.Ilpeut donctrecompardautreslangagesdescriptquifonctionnentsurlemmeprincipe :ASP(ActiveServerPages)ouJSP (JavaServerPages). ladiffrencedunlangagecommeleJavaScript,olecodeestexcutctclient(danslenavigateur),lecodePHPest excutctserveur.LersultatdecetteexcutionestintgrdanslapageHTMLquiestenvoyeaunavigateur.Ce derniernaaucuneconnaissancedelexistencedutraitementquisestdroulsurleserveur. Cette technique permet de raliser des pages Web dynamiques dont le contenu peut tre compltement ou partiellement gnr au moment de lappel de la page, grce des informations rcupres dans un formulaire ou extraitesdunebasededonnes. ExemplesimpledepagePHP : <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Exemple de page PHP</title> </head> <body> <?php echo <p>Bonjour Olivier !</p>; ?> </body> </html> LapartieengrasestducodePHPinclusdanslapageHTMLlintrieurdesbalises<?phpet?>.Surcetexemplesimple, le code PHP se contente dafficher un texte statique Bonjour Olivier ! grce la fonction echo dans un vrai programmePHP,ilestprobablequecetexteseraitgnrdynamiquementenfonctiondelidentificationdelutilisateur. Pour indiquer au serveur Web quune page HTML contient du code PHP excuter, il suffit de donner au fichier une extensionparticulire :.php(saufconfigurationparticulireduserveur). LeschmasuivantexpliquecommentesttraitunfichierPHPparleserveurWeb.

ENI Editions - All rigths reserved

- 1-

LorsquunfichierPHPestdemandauserveurWeb,lecodePHPinclusdanslapageHTMLestdabordexcutsurle serveur. Le rsultat de cette excution est insr dans la page la place du code PHP et la page est renvoye au navigateur. Dautreslangages,commelePERL(PracticalExtractionandReportLanguage)ouleC,permettentdcriredesscriptsCGI (CommonGatewayInterface)danslebutdobtenirlemmersultat.Ceslangagessontsouventconsidrscommemoins pratiques et moins lisibles que PHP pour raliser une page Web dynamique. En effet, le programme doit gnrer lintgralitdelapageHTMLalorsquenPHP,seulelapartierellementdynamiqueseracodelintrieurdelapage. Deplus,PHPatcritspcialementpourleWebetpossdedesfonctionnalitsparfaitementadaptescetypede dveloppement,cequinestlecasnidePERLniduC(quisontparailleursdexcellentslangages).

- 2-

ENI Editions - All rigths reserved

StructuredebasedunepagePHP
1.LesbalisesPHP
Comme nous lavons vu prcdemment, le code PHP est inclus dans une page HTML lintrieur de balises (aussi appelestags). PHPacceptequatresyntaxespourlesbalises :
q

<?php ... ?> <script language="php"> ... </script> <? ... ?> <% ... %>

Lapremiresyntaxeestlasyntaxehabituelle,recommande. Ladeuximesyntaxe,pluslourde,utiliselabalisestandard script ellepeuttreutilesivotrediteurHTMLinterprte mallesautressyntaxes. LatroisimesyntaxenestenvisageablequesielleatautorisedanslefichierdeparamtragedePHP( php.ini)en mettantleparamtreshort_open_tagon. LaquatrimesyntaxepermetdemployerlabaliseASPmaiselleestutilisableuniquementsielleatautorisedansle fichierdeparamtragedePHPenmettantleparamtreasp_tagson.

2.Lafonctionecho
La fonction echo est la fonction de base de toute page PHP. Elle permet dafficher une ou plusieurs chanes et donc dincluredutextedanslapageHTMLenvoyeaunavigateur. Syntaxe : echo(chane texte) echo chane texte[,...] texte Texteafficher. Lapremiresyntaxenacceptequunparamtrealorsqueladeuximeenaccepteplusieurs. Exemple : <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Exemple de page PHP</title> </head> <body> <p> <?php echo(Bonjour Olivier !); ?> <br /> <?php echo Bonjour ,Valrie ,!; ?> </p> </body> </html>

ENI Editions - All rigths reserved

- 1-

Rsultat : Bonjour Olivier ! Bonjour Valrie ! Il ny pas de saut de ligne automatique dans le rsultat de lexcution du code PHP. En cas de besoin, il est donc ncessairedinsrer la balise HTML <br /> qui provoque un saut de ligne dans la page HTML finale (voir lexempleci dessus). Letextepassenparamtrelafonction echopeuttrecritsurplusieurslignesdanslesourcemaisilestaffichsur uneseuledanslersultat.

3.Sparateurdinstruction
EnPHP,touteslesinstructionsdoiventseterminerparunpointvirgule. Exemple : <?php echo Bonjour ; echo Olivier !; ?> Rsultat : Bonjour Olivier ! En cas domission, une erreur est gnre. La seule exception concerne linstruction qui prcde la balise de fin pour laquellelepointvirgulepeuttreomis. Plusieurs instructions peuvent tre crites sur la mme ligne du moment quelles sont spares par un pointvirgule. Nanmoins,cettecriturenuitparfoislalisibilitducode. Exemple : <?php echo Bonjour ; echo Olivier !; ?>

4.Commentaire
PHPproposedeuxsyntaxes :
q

//ou#pourinsrerducommentairejusqulafindelaligne /* ... */pourinsrerducommentairesurplusieurslignes

Exemple : <?php // commentaire sur une seule ligne # commentaire sur une seule ligne /* commentaire sur plusieur lignes */ echo Bonjour ; / / c o m m e n t a i r e j u s q u l a f i n d e l a l i g n e echo Olivier !; # c o m m e n t a i r e j u s q u l a f i n d e l a l i g n e ?>

Lescommentaires/* ... */nedoiventpastreimbriqus.

- 2-

ENI Editions - All rigths reserved

5.MixerduPHPetdelHTML
IlexistedenombreusesapprochespourmixerduPHPetdelHTML. Cesdiffrentesapprochesreposentnanmoinssurdeuxprincipestrssimples :
q

Lapagepeutconteniruneouplusieursinclusion(s)decodePHP. Le code PHP gnre du texte qui est intgr dans la page HTML envoye au navigateur. Tout texte comprhensibleparlenavigateurpeutdonctregnrparlecodePHP :dutextesimple,ducodeHTML,du codeJavaScript, ...

Les exemples qui suivent utilisent des variables et des fonctions PHP (rcupration de la date et de lheure). Ces notionsserontprsentesplusendtaildanslasuitedecetouvrage. ExempledepagecontenantducodePHPenplusieursendroits : <?php // Dclaration de variables qui seront utilises plus loin. // Cette section de code PHP ne gnre par de sortie dans la // page HTML (pas dappel echo). $nom = Olivier; // nom de lutilisateur $titre_page = Les ditions ENI prsentent ...; // titre de la page $aujourdhui = date("d/m/Y"); // date du jour $heure = date("H:i:s"); // heure ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> <?php /* affichage du titre */ echo $titre_page; ?> </title> </head> <body> <p> <?php /* Affichage du nom de lutilisateur. ** Les tags de mise en gras du nom (<b>) et de retour ** la ligne (<br />) sont inclus dans la chane envoye ** par le echo. */ echo "Bonjour <b>$nom</b> !<br />"; // Affichage de la date et de lheure. echo "Nous sommes le $aujourdhui ; il est $heure."; ?> </p> </body> </html> Rsultat : Bonjour O l i v i e r ! Nous sommes le 27/01/2008 ; il est 10:48:52. Sourcedelapagedanslenavigateur(leslmentsgnrsparPHPsontengras) : <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> Les ditions ENI prsentent ... </title> </head> <body> <p> Bonjour <b>Olivier</b> !<br />Nous sommes le 27/01/2008 ; il est 10:48:52.

</p>

ENI Editions - All rigths reserved

- 3-

</body> </html> ExempledepagegnreentirementparducodePHP(suivantleprincipeCGI) : <?php // Dclaration de variables qui sont utilises plus loin. $nom = Olivier; // nom de lutilisateur $titre_page = Les ditions ENI prsentent ...; // titre de la page $aujourdhui = date("d/m/Y"); // date du jour $heure = date("H:i:s"); // heure // Gnration des balises douverture du document HTML. echo <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" , "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">; echo <html xmlns="http://www.w3.org/1999/xhtml">; echo <head>; echo "<title>$titre_page</title>"; echo </head>; echo <body>; echo <p>; /* Affichage du nom de lutilisateur. ** Les tags de mise en gras du nom (<b>) et de retour la ligne ** (<br />) sont inclus dans la chane envoye par le echo. */ echo "Bonjour <b>$nom</b> !<br />"; // Affichage de la date et de lheure. echo "Nous sommes le $aujourdhui ; il est $heure."; echo </p>; echo </body>; echo </html>; ?> Rsultat : Bonjour O l i v i e r ! Nous sommes le 27/01/2008 ; il est 11:03:27. Sourcedelapagedanslenavigateur(toutestsuruneligne) : <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Les ditions ENI prsentent ...</title></head><body><p>Bonjour <b>Olivier</b> !<br />Nous sommes le 27/01/2008 ; il est 11:03:27.</p></body></html> IlnyapasderglepourmixerduPHPetdelHTML.Uneapprochecourammentemployeparlesdveloppeursconsiste utiliser PHP uniquement pour gnrer la partie rellement dynamique de la page le reste est directement crit en HTMLdanslefichier.Cettetechniquerendlecodemoinslourdetpermetdevoirtoutdesuiteosetrouvelalogique applicative. LedocumentHTMLenvoyaunavigateurdoittrevalideetsipossibleconformeauxstandardsHTMLouXHTMLduW3C (World Wide Web Consortium). Si besoin, nhsitez pas utiliser le service de validation du W3C (http://validator.w3.org/). Danscetouvrage,lesexemplesrespectentaumaximumlarecommandationXHTML1.0.Nanmoins,pourdesraisonsde place,lesexemplesnintgrentpassystmatiquementlesdclarationsinitiales : <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> ...

6.Rglesdenommage
TouteentitPHPnomme(variable,constante,fonction, ...)doitavoirunnomquirespectelesrglessuivantes :

- 4-

ENI Editions - All rigths reserved

commencerparunelettreouunsoulign(_) comporterensuitedeslettres,deschiffresoulecaractresoulign.

Danscettedfinition,unelettrereprsentetoutelettreminusculeoumajusculecompriseentre aet z (a zet A Z) ainsiquetoutcaractredecodeASCIIcomprisentre127et255.Lescaractresaccentussontdoncautoriss,mais paslescaractresdutype#$%&quiontunesignificationspcialedanslelangagePHP.

ENI Editions - All rigths reserved

- 5-

ConfigurationdePHP
1.Lefichierdeconfigurationphp.ini
Toutaulongdecetouvrage,nousrencontreronsplusieursdirectivesdeconfigurationquipeuventtreutilisespour modifierlecomportementdePHP. CesdirectivesdeconfigurationsontsaisiesdanslefichierdeparamtragedePHP( php.ini). PHPfournitdeuxexemplesdefichierphp.ini : php.ini-distetphp.ini-recommended. Lefichierphp.ini-distestunexempledefichierdeconfiguration,pluttdestintreutilisdansunenvironnement de dveloppement. linverse, le fichier php.ini-recommended est plutt destin tre employ dans un environnementdexploitation ilcontientdesrglagesquirendentPHPplusscuriset/ouperformant. Ces deux fichiers comportent beaucoup de commentaires qui expliquent le rle de chaque directive et donnent des conseilssurleurusage. Pourutiliserundecesfichiers,copiezlelemplacementapproprisurvotreplateformeetrenommezleen php.ini. Lefichierphp.iniestnotammentrecherchdanslesendroitssuivants(danscetordre) :
q

unendroitspcifiqueauserveurWeb(parexemple,ladirectivePHPIniDirdApache2) unendroitdfiniparlavariabledenvironnementPHPRC ledossier/usr/local/libsousLinux/Unixetc:\windowsouc:\winntsousWindows.

Danscetouvrage,etsaufindicationcontraire,noussupposeronsquedeuxdirectivesrelativeslagestiondeserreurs sontpositionnesdelamaniresuivante : <$I[]display_errors>display_errors = on Leserreurssontaffiches. <$I[]error_reporting>error_reporting = E_ALL & ~E_NOTICE Toutesleserreurssontaffiches,saufleserreursdeniveauE_NOTICE(simplesinformations,parexemplelorsde lutilisationdunevariablenoninitialise). LagestiondeserreursestprsenteendtaildanslechapitreGrerleserreursdansunscriptPHP.

2.Informationssurlaconfiguration
PHPproposedeuxfonctionsparticulirementutilespourobtenirdesinformationssurlaconfiguration : phpversionet phpinfo. La fonction phpversion retourne le numro de version de PHP et la fonction phpinfo affiche une grande quantit dinformations sur la configuration de PHP et son environnement. Le numro de version est aussi disponible via la constanteprdfiniePHP_VERSION. Syntaxe chane phpversion( chane extension) entier phpinfo([ entier quoi]) Avec extension Siceparamtreestspcifi,lafonctionretournelaversiondelextensionportantcenom(ou FALSEsilaversionest inconnueousilextensionnestpasdisponible). quoi

ENI Editions - All rigths reserved

- 1-

Nature de linformation dsire. Utilisez une ou plusieurs (somme) des constantes suivantes : INFO_GENERAL (1) : informations gnrales (version, emplacement du fichier php.ini, systme dexploitation, etc.). INFO_CREDITS (2) : informations sur les auteurs. INFO_CONFIGURATION (4) : informations sur la configuration (valeurs des directives). INFO_MODULES (8) :informationssurlesmoduleschargs,avecleurconfigurationrespective. INFO_ENVIRONMENT (16) : informations sur lenvironnement (voir la variable $_ENV en annexe). INFO_VARIABLES (32) : valeurs de toutes les variables prdfinies (voir lannexe). INFO_LICENSE (64) : informations sur la licence. INFO_ALL (-1) : toutes les informations(valeurpardfaut). phpinforetourneTRUEencasdesuccsetFALSEencasderreur. Exemple1 : <?php echo phpversion(); ?> Rsultat : 5.2.4 Exemple2 : <?php // informations gnrales et informations // de licence phpinfo(INFO_GENERAL+INFO_LICENSE); ?> Rsultat :

- 2-

ENI Editions - All rigths reserved

ENI Editions - All rigths reserved

- 3-

Exemple3 : <?php // toutes les informations phpinfo(); ?>

oir aussi les fonctions ini_get_all, ini_get et get_loaded_extensions qui permettent dobtenir des V informationssurlesdirectivesdecompilationetlesextensionscharges.

- 4-

ENI Editions - All rigths reserved

LesbasesdulangagePHP
1.Constantes
a.Dfinition
Lafonctiondefinepermetdedfiniruneconstante. Syntaxe boolen define( chane nom, mixte valeur[, boolen sensible_casse) nom Nomdelaconstante(cf.danscechapitreStructuredebasedunepagePHPRglesdenommage). valeur Valeurdelaconstante. sensible_casse Indiquesilenomdelaconstanteestsensiblelacasse( TRUEvaleurpardfaut)ounon(FALSE). LafonctiondefineretourneTRUEencasdesuccsetFALSEencasderreur. Touttypededonnesscalaire(cf.danscechapitreLesbasesdulangagePHPTypesdedonnes)peuttreutiliscommetype dedonnesduneconstante. Lenomduneconstantenedoitpascommencerparun$carceprfixeestrservaunomdesvariables(cf.danscechapitreLes basesdulangagePHPVariables).Ilfautnoterquedfiniruneconstantedontlenomcommencepasun$negnrepasderreur (defineretourneTRUE !),mais,lutilisation,laconstanteseravuecommeunevariablenoninitialise. Unefoisdfinie,uneconstantenestplusmodifiableparlasuite,niparunnouvelappel define(retourneFALSEetlaisselavaleur delaconstanteinchange)niparuneaffectationdirecte(gnreuneerreurdanalyseduscript). Exemples <?php // Dfinir une constante (dont le nom est par dfaut // sensible la casse). define(CONSTANTE,valeur de CONSTANTE); // Afficher la valeur de CONSTANTE (=> OK). echo CONSTANTE = ,CONSTANTE,<br />; // Afficher la valeur de constante (=> vide) echo constante = ,constante; echo => interprt en littral<br />; ?> Rsultat CONSTANTE = valeur de CONSTANTE constante = constante => interprt en littral Traditionnellement,lesnomsdesconstantessontdfinisenmajuscules. Utiliseruneconstantenondfinie(ouunevariablenoninitialise)outenterderedfiniruneconstantedjdfiniegnrentune erreurdeniveau E_NOTICE.LeniveauderreureffectivementsignalparPHPdpenddedirectivesdeconfigurationdanslefichier php.ini(cf.chapitreGrerleserreursdansunscriptPHP).Lersultatprcdentcorresponduneconfigurationdanslaquelleles erreursdeniveauE_NOTICEnesontpasaffiches.

b.Porte
Laporteduneconstanteestlescriptdanslequelelleestdfinie.Uneconstantepeutdonctredfiniedansunepremiresection decodePHPetutilisedansuneautresectiondecodePHPdummescript. Exemple <?php // Dfinir une constante. define(NOM,Olivier); ?>

ENI Editions - All rigths reserved

- 1-

<html> <body> <p>Bonjour <b>< ? p h p e c h o N O M ; ? ></b> !</p> </body> </html> Rsultat Bonjour O l i v i e r !

2.Variables
Unevariableestunezonemmoireidentifieparunnomquicontientunevaleurlisibleoumodifiabledansleprogramme.

a.Initialisationetaffectation
EnPHPlesvariablessontidentifiesparleprfixe$suividunnomquirespectelesrglesdenommageprsentesprcdemment (cf.danscechapitreStructuredebasedunepagePHPRglesdenommage). Lenomdesvariablesestsensiblelacasse : $nomet$NomsontvuesparPHPcommedeuxvariablesdiffrentes.Cecomportement estdangereuxcar,encasdutilisationdunmauvaisnom,unenouvellevariablevideestcreavecunesimpleerreurdeniveau E_NOTICE qui nestpasforcmentaffiche(cf.chapitreGrerleserreursdansunscriptPHP).Ilestdoncprimordialdadopterune conventiondenommageetdelarespecter.Quelquessuggestions :
q

toutenminuscule($nom) premirelettreenmajusculeetleresteenminuscule($Nom) premirelettredechaquemotenmajusculeetleresteenminuscule($NomDeFamille).

LesvariablesPHPsontautomatiquementdfinieslorsdeleurpremireutilisation.Ilnyapasdinstructionspcifiquepourcrerune variable. De plus, les variables PHP sont types automatiquement lors de chaque affectation dune valeur une variable, le type de la variableestautomatiquementdfiniouredfini(cf.danscechapitreLesbasesdulangagePHPTypesdedonnes). Unevaleurpeuttreaffecteunevariablegrceloprateurdaffectation=(cf.danscechapitreLesbasesdulangagePHP Oprateurs). Exemples <?php // Initialiser une variable $nom. $nom = Olivier; // Afficher la variable $nom. echo $nom = ,$nom,<br />; // Afficher la variable $ N om. echo $<b>N</b>om = ,$ N om; echo => vide (c\est une autre variable)<br />; // Modifier la valeur (et le type) de la variable $nom. $nom = 123; // Afficher la variable $nom. echo $nom = ,$nom,<br />; ?> Rsultat(leserreursdeniveauE_NOTICEnesontpasaffiches) $nom = Olivier $ N om = => vide (cest une autre variable) $nom = 123

out au long de cet ouvrage, nous aurons loccasion de rencontrer des variables automatiquement dfinies par PHP et T contenantdesvaleursrelativeslenvironnement,PHP,auxformulaires,auxcookies,etc.

b.Porteetduredevie
Laportedunevariableestlescriptdanslequelelleestdfinie.Unevariablepeutdonctredfiniedansunepremiresectionde codePHPetutilisedansuneautresectiondecodePHPdummescript. Laduredeviedunevariableestletempsdelexcutionduscript.Lorsquelescriptsetermine,lesvariablessontsupprimes.Sile

- 2-

ENI Editions - All rigths reserved

mmescriptestappelplustard,denouvellesvariablessontdfinies. Exemple <?php // Afficher le contenu de la variable $nom. echo $nom = ,$nom,<br />; // Initialiser la variable $nom. $nom = Olivier; // Afficher de nouveau le contenu de la variable $nom. echo $nom = ,$nom,<br />; ?> Rsultatdupremierappelduscript $nom = $nom = Olivier Rsultatdudeuximeappelduscript $nom = $nom = Olivier Entrelesdeuxappels,lavariableatsupprime.Audbutdudeuximeappel,ellenecontientpluslavaleurquelleavaitlafin dupremierappel(cenestpluslammevariable). ousverronsdansleschapitreGrerlesliensetlesformulairesavecPHPetGrerlessessionscommentconserverlavaleur N dunevariableaudeldelexcutionduscriptoucommenttransmettrelavaleurdunevariabledunscriptunautre.

c.Variabledynamique(ouvariablevariable)
PHPproposeunefonctionnalitdevariabledynamique(aussiappelevariablevariable)utiledanscertainessituations. Le principe consiste un utiliser une variable qui stocke le nom dune autre variable et dutiliser ensuite une notation du type $$variableou${$variable}.Aveccettenotationle$variable"intrieur"estremplacparlavaleurdelavariable$variable(valeur parexemple)quiestalorsutiliscommenomdevariableparle$"extrieur"(soit$valeursurnotreexemple). Exemple <?php $une_variable = 10; $nom_variable = une_variable; echo $une_variable = ,$une_variable,<br />; echo $nom_variable = ,$nom_variable,<br />; echo $$nom_variable = ,$$nom_variable,<br />; ?> Rsultat $une_variable = 10 $nom_variable = une_variable $$nom_variable = 10

3.Typesdedonnes
a.Typesdisponibles
PHP propose quatre types de donnes scalaires (ne pouvant contenir quune valeur), deux types composs (pouvant contenir plusieursvaleurs)etdeuxtypesspciaux :
s

Typesscalaires :
q

nombreentier nombrevirguleflottante chanedecaractres

ENI Editions - All rigths reserved

- 3-

boolen.

Typescomposs :
q

tableau(cf.4Tableaux) objet(cf.chapitre8).

Typesspciaux :
q

NULL ressource.

b.Typesdedonnesscalaires
Entier Letypeentier(integer)permetdestockerunnombreentiersignsur32bits,soitdesvaleurscomprisesentre2147483648( 2^31)et+2147483647(+2^311). Encasdedpassementdecapacitdansuncalcul,lersultatestautomatiquementconvertiennombrevirguleflottante. Nombrevirguleflottante Letypenombrevirguleflottante(float)permetdestockerunnombredcimalsuruneplagedevaleursdpendantedelaplate forme(gnralementdelordrede10308 10+308 ). Untelnombrepeuttreexprimennotationdcimale x.y (par exemple 123.456)ouennotationscientifique x.yEzou x.yez(par exemple1.23456E2). Encasdeconversiondunnombrevirguleflottanteenentier,lenombreesttronqu(pasarrondi)lentierinfrieur(1.9donne1 parexemple).Encasdedpassementdecapacit,aucunmessagenestaffich,maislavaleurlarrivestindfinie. eslibrairiesparticulires(aussiappelesbibliothques)sontproposesparPHPpourtraiterlesnombresdegrandetaille D (librairiesBCouGMP).

Chanedecaractres Letypechanedecaractres( string)permetdestockertoutesquencedecaractressurunoctet(codeASCIIcomprisentre0et 255),sanslimitedetaille. Une expression littrale de type chane de caractres peut tre spcifie entre guillemets ( "ceci est une chane") ou entre apostrophes( ceci aussi est une chane)avecdesdiffrencesdecomportementtrsimportantesquisontexposesciaprs. Lesguillemetsprsentsdansunechanedlimitepardesguillemetsoulesapostrophesprsentsdansunechanedlimitepar desapostrophesdoiventtre"chapps",cestdireprcdsducaractreantislash(\).Encomplment,unantislashprsent enfindechane,justeavantleguillemetoulapostrophefinal,doitluiaussitrechappparunantislash. Exemple <?php echo C\est l\t.<br />; echo "Je dis \"bonjour\".<br />"; ?> Rsultat Cest lt. Je dis "bonjour". Unechanepeuttresaisiesurplusieurslignesmaiscelleciestaffichesuruneseulelignedanslenavigateur.Pourafficherune chanesurplusieurslignesdanslenavigateur,ilfautinsrerunebalise<br />. <?php $chane = <p>Je m\appelle Olivier et j\habite en France.</p>; echo $chane; $chane = <p>Je m\appelle Olivier < b r / > et j\habite en France.</p>; echo $chane; ?>

- 4-

ENI Editions - All rigths reserved

Rsultat Je mappelle Olivier et jhabite en France. Je mappelle Olivier et jhabite en France. Lorsquunechaneestdlimitepardesguillemets,toutesquencedecaractrescommenantparlesigne$estinterprtcomme une variable et remplace par la valeur de la variable : cest le mcanisme de substitution des variables par leur valeur. Cette fonctionnalit,trspratique,nemarchepasavecleschanesdlimitespardesapostrophes(premirediffrenceentrelesdeux typesdechane).Pourannulercecomportement,ilsuffitdchapperlesigne$aveclantislash(\)pourquilsecomportecommeun $. Exemple <?php $nom = Olivier; echo "Je mappelle $ n o m .<br />"; echo Je m\appelle $ n o m .<br />; // ne marche pas echo " \ $ n o m = $ n o m "; // chappement du $ ?> Rsultat Je mappelle Olivier. Je mappelle $nom. $nom = Olivier Silenomdelavariableestimmdiatementsuivipardautrescaractres,ilfaututiliserlasyntaxe {$variable}ou ${variable}pour que la substitution seffectue correctement. Avec cette syntaxe, pour que laccolade soit conserve, il faut la doubler ({{$variable}}). Exemple <?php $fruit = pomme; echo "Une $fruit ne cote pas cher.<br />"; echo "Deux $fruit s cotent deux fois plus cher.<br />"; // ! echo "Deux {$fruit} s cotent deux fois plus cher.<br />"; echo "{\$fruit} = {{$fruit}}.<br />"; ?> Rsultat Une pomme ne cote pas cher. Deux cotent deux fois plus cher. Deux pommes cotent deux fois plus cher. {$fruit} = {pomme}.

lnyapasdemcanismedesubstitutionquivalentpourlesconstantes cestuneraisonvalablepourutiliserdesvariables I enlieuetplacedevraiesconstantes. Encomplment,dautressquencesdchappementpeuventtreutilisesdansleschanesdlimitespardesguillemets,maispas danscellesdlimitespardesapostrophes(deuximediffrenceentrelesdeuxtypesdechane). Squence \n \r \t \\ \$ \nnn Valeur Sautdeligne(=LF=codeASCII10) Retourchariot(=CR=codeASCII13) Tabulation(=HT=codeASCII9) \(djabord) $(djabord) LecaractredsignparlecodeASCIInnnexprimenoctal LecaractredsignparlecodeASCIInnexprimen hexadcimal

\xnn

ENI Editions - All rigths reserved

- 5-

Exemple <?php echo "Je mappelle Olivier.<br /> \ n " ; echo "Je mappelle \117\154\151\166\151\145\162."; ?> Rsultat Je mappelle Olivier. Je mappelle Olivier.

appel :unsautdelignedanslesourcedelapageenvoyeaunavigateurneprovoquepasdesautdelignedanslapage R affiche.Cestlecasdelasquence"\n"utilisedansnotreexemple.Ici,labalise<br />provoqueleretourlalignedans lapageaffiche. Ilestpossibledaccderaunimecaractredunechanegrcelanotation $x[i], $xdsignantlavariabledetypechaneetile numro du caractre (le premier caractre portant le numro 0). Les accolades peuvent aussi tre utilises, mais cette syntaxe deviendraobsoltedansuneprochaineversion. Exemple <?php $nom = Olivier; echo $nom[0],$nom{6}; ?> Rsultat Or PHPestcapabledeconvertirunechaneennombre(entieroudcimal)laidedesrglessuivantes :
q

Silepremiercaractrenon"blanc"(autrequeespace,tabulation,LF,CR)nestniunchiffre,niunpoint,nilesigne"moins", lachaneestvalue0(entier). Danslecascontraire,PHPextraittouslescaractresnon"blancs"dudbutdechanejusqurencontreruncaractrenon numrique (non compris entre 1 et 9, diffrent du point, du signe "moins" et du symbole scientifique "e" ou "E") la squenceainsiobtenueestconvertieenentier(pasdepointnidesymbolescientifique)ouendcimal(encasdeprsence dunpointoudusymbolescientifique).

Exemple <?php echo 1 echo 1 echo 1 echo 1 echo 1 echo 1 echo 1 echo 1 echo 1 echo 1 echo 1 ?> Rsultat 1 1 1 1 1 1 1 1 1 1 1 + + + + + + + + + + + "1" = 2 "1.5" = 2.5 "1.5E2" = 151 "1e3" = 1001 1abc = 2 "1.5abcd" = 2.5 "1.5 abcd" = 2.5 ".5" = 1.5 "-5" = -4 " \t\n\r 5" = 6 "abc1" = 1

+ + + + + + + + + + +

"1" = ,(1 + "1"),<br />; "1.5" = ,(1 + "1.5"),<br />; "1.5E2" = ,(1 + "1.5E2"),<br />; "1e3" = ,(1 + "1e3"),<br />; 1abc = ,(1 + "1abc"),<br />; "1.5abcd" = ,(1 + "1.5abcd"),<br />; "1.5 abcd" = ,(1 + "1.5 abcd"),<br />; ".5" = ,(1 + ".5"),<br />; "-5" = ,(1 + "-5"),<br />; " \t\n\r 5" = ,(1 + " \t\n\r 5"),<br />; "abc1" = ,(1 + "abc1"),<br />;

Ledernierexemplemontrequunechanequinecommencepasparuncaractrenumriqueestconvertieenentiergal0.

- 6-

ENI Editions - All rigths reserved

Boolen Letypeboolen( boolean)comportedeuxvaleurs:TRUE(outrue)etFALSE(oufalse). Cetypededonnesestprincipalementutilisdanslesstructuresdecontrlepourtesterunecondition(cf.danscechapitreLes basesdulangagePHPStructuresdecontrle). PHPestcapabledeconvertirtouttypededonnesenboolenselonlesrglessuivantes : Valeur nombreentier0 nombredcimal0.000... chanevide("") chanegale0(" 0") tableauvide objetvide constanteNULL(cf.letypeNULL) toutlereste TRUE FALSE Convertien

U nevaleurgale1estconvertieenTRUEavecPHP.

Inversement,PHPestcapabledoprerlesconversionssuivantes : TRUE Boolen Nombre Boolen Chane 1 "1"

FALSE
0 ""(chanevide)

Compte tenu de la logique de conversion indique prcdemment, toute variable peut tre teste en tant que boolen (PHP se chargeant de la conversion). Ce fonctionnement est souvent pratique mais peut facilement conduire des erreurs dlicates dceler.

c.Typesdedonnesspciaux
Le type NULL Cetypeestunpeuparticulieretcorrespondautypedunevariableutilisesansjamaisavoirtinitialise.Ilpossdeuneseule valeur,lavaleurNULLdfinieparlaconstanteNULL(ounull). Encasdeconversionenboolen,lavaleurNULLestconvertieenFALSE. Letyperessource( Cetypegnriqueestunpeuparticulier,etcorrespondunerfrenceversuneressourceexterne :fichierouvert,connexionde basededonnes,etc. plusieursreprisesdanscetouvrage,nousauronsloccasiondeprsenterdesfonctionsquipermettentdemanipulercesdonnes detyperessource.

4.Tableaux
a.Dfinition
EnPHP,untableauestunecollection(listedlments)ordonnedecouplescl/valeur. Laclpeuttredetypeentieroudetypechane.Danslepremiercas,letableauestditnumriqueetlaclestdsigneparle termeindice.Dansledeuximecasletableauestditassociatif.Lesclsnesontpasforcmentconscutivesniordonnesetun tableaupeutcomporterdesclsentiresetdesclsdetypechane. La valeur associe la cl peut tre de nimporte quel type, et notamment de type tableau dans ce cas, le tableau est dit multidimensionnel. Exemple

ENI Editions - All rigths reserved

- 7-

Tableaunumrique(indicesordonnsconscutifs)

Cl/Indice 0 1 2 3

Valeur zro un deux trois

Tableaunumrique(indicesnonordonns,nonconscutifs)

Cl/Indice 20 30 10

Valeur vingt trente dix

Tableaumixte

Cl/Indice 0 zro un 1 deux 2 trois 3

Valeur zro 0 1 un 2 deux 3 trois

Tableaumultidimensionnel(listedevillesparpays)

Cl/Indice FRANCE

Valeur Cl/Indice 0 1 2 Valeur Paris Lyon Nantes Valeur Rome Venise

ITALIE

Cl/Indice 0 1

- 8-

ENI Editions - All rigths reserved

b.Cration
Unevariabledetypetableaupeuttredfinieexplicitementgrcelafonctionarray()ouimplicitementenutilisantunenotation crochet([]). Notationcrochet( Unevariableutilisepourlapremirefoisavecunenotationdelaforme$variable[...],estautomatiquementcreavecletype tableau. Lammeoprationeffectuesurunevariabledjdfinieavecuntypescalaireprovoqueunmessagederreur. Lecontenuduntableaupeuttreainsidfiniparplusieursaffectationsdutype$tableau[...] = valeur. Avecuneaffectationdutype $tableau[] = valeur,PHPrechercheleplusgrandindiceentierutilisetassocielavaleurlindice immdiatementsuprieur.Siletableauestvide,llmentestplaclindice0. Avecuneaffectationdutype $tableau[cl] = valeur,PHPassocielavaleurlaclindique(quipeuttredetypeentieroude typechane). Lesdeuxnotationspeuventtremlangesdansunesquencedaffectation Exemple <?php $nombres[] = zro; // => indice 0 $nombres[] = un; // => indice max (0) + 1 = 1 $nombres[] = deux; // => indice max (1) + 1 = 2 $nombres[] = trois; // => indice max (2) + 1 = 3 $nombres[5] = cinq; // => indice 5 $nombres[] = six; // => indice max (5) + 1 = 6 $nombres[un] = 1; // indice un $nombres[] = sept; // => indice max (6) + 1 = 7 $nombres[-1] = moins un; // => -1 ?> Rsultat Cl/Indice 0 1 2 3 5 6 un 7 1 Valeur zro un deux trois cinq six 1 sept moinsun

Ces notations peuvent tre utilises pour construire un tableau multidimensionnel, sous la forme $tableau[...] = $tableau_intrieurou $tableau[...][...] = valeur. La premire notation permet de stocker un tableau dans un emplacement dunautretableauetladeuximenotation,destockerunevaleurdirectementdansunemplacementsitulintrieurdunautre tableau. Exemple
q

Premiremthode :

<?php // Cration dun tableau contenant les villes de France $villes_france[] = Paris; $villes_france[] = Lyon; $villes_france[] = Nantes; // Stockage du tableau des villes de France dans le tableau // des villes. $villes[FRANCE] = $villes_france;

ENI Editions - All rigths reserved

- 9-

// Idem avec les villes dItalie $villes_italie[] = Rome; $villes_italie[] = Venise; $villes[ITALIE] = $villes_italie; ?>
q

Deuximemthode :

<?php // Stockage direct des villes dans le tableau // - pour la France $villes[FRANCE][] = Paris; $villes[FRANCE][] = Lyon; $villes[FRANCE][] = Nantes; // - pour lItalie $villes[ITALIE][] = Rome; $villes[ITALIE][] = Venise; ?> Rsultat(danslesdeuxcas) Cl/Indice FRANCE Valeur Cl/Indice 0 1 2 ITALIE Cl/Indice 0 1 Lafonctionarray Lafonctionarraypermetdecreruntableaupartirdunelistedlments. Syntaxe tableau array([ mixte valeur[, ...]]) ou tableau array([{ chane | entier } cl => mixte valeur[, ...]]) valeur lmentdutableau. cl Valeurdelacl. Danslapremiresyntaxe,lescls/indicesnesontpasspcifisetcestuntableaunumriqueindicesconscutifscommenant0 quiestcr:lepremierargumentdelafonctiontantstocklindice0,ledeuximelindice1,etc. Dans la deuxime syntaxe, lindice ou la cl est spcifi(e) par un entier ou par une chane et une valeur lui est associe par loprateur=>. Lesdeuxsyntaxespeuventtremlanges.Danscecas,lorsquelindiceoulaclnestpasspcifi(e),PHPrechercheleplusgrand indiceentierutilisetassocielavaleurlindiceimmdiatementsuprieur silnexisteaucunindiceentier,llmentestplac lindice0. Lafonctionarray,appelesansargument,creuntableauvide. Exemple <?php $nombres = array(zro,un,deux,trois, 5 => cinq,six,un => 1,sept,-1 => moins un); ?> Rsultat Valeur Paris Lyon Nantes Valeur Rome Venise

- 10 -

ENI Editions - All rigths reserved

Cl/Indice 0 1 2 3 5 6 un 7 1

Valeur zro un deux trois cinq six 1 sept moinsun

La fonction array accepte en argument les donnes de type tableau (soit une variable, soit un appel imbriqu array) ce qui permetdeconstruireuntableaumultidimensionnel. Exemple <?php // Cration dun tableau contenant les villes de France et // dItalie // Le tableau des villes de France est cr au pralable. $villes_france = array(Paris,Lyon,Nantes); // Celui des villes dItalie est cr par un appel imbriqu // array(). $villes = array(FRANCE => $villes_france, ITALIE => array(Rome,Venise)); ?> Rsultat Cl/Indice FRANCE Valeur Cl/Indice 0 1 2 ITALIE Cl/Indice 0 1 Valeur Paris Lyon Nantes Valeur Rome Venise

c.Manipulation
Deuxbesoinscourantsexistent,relatifslamanipulationduntableau :
q

accderunlmentindividueldutableau parcourirletableau.

Accderunlmentindividueldutableau Lanotationcrochetsestutilisepouraccder,enlectureouencriture,unlmentindividueldutableau :

ENI Editions - All rigths reserved

- 11 -

$tableau[{ chane | entier } cl] $tableau Tableauconcern. cl Valeurdelacl/indice. Pourlestableauxmultidimensionnels,plusieurssriesdecrochetsdoiventtreutiliss. Exemple <?php $nombres = array(zro,un,deux,trois, 5 => cinq,six,un => 1,sept,-1 => moins un); echo $nombres[1],<br />; echo $nombres[un],<br />; $villes = array(FRANCE => array(Paris,Lyon,Nantes), ITALIE => array(Rome,Venise)); echo $villes[FRANCE][0],<br />; echo $villes[ITALIE][1],<br />; ?> Rsultat un 1 Paris Venise Leprincipedesubstitutiondesvariablesdansleschanesdlimitespardesguillemetsfonctionneaveclestableaux.Desaccolades sontncessairespourdlimiterlexpressiondansdeuxcas :
q

Pourspcifierunecldetypechaneexprimesouslaformedunlittral:{$tableau[...]}. Pouruntableaumultidimensionnel:{$tableau[...][...]}.

Exemple <?php $nombres = array(zro,un,deux,trois, 5 => cinq,six,un => 1,sept,-1 => moins un); echo "\$nombres[1] = $nombres[1]<br />"; echo "\$nombres[un] = {$nombres[un]}<br />"; $villes = array(FRANCE => array(Paris,Lyon,Nantes), ITALIE => array(Rome,Venise)); echo "\$villes[FRANCE][0] = {$villes[FRANCE][0]}<br />";?> Rsultat $nombres[1] = un $nombres[un] = 1 $villes[FRANCE][0] = Paris

Parcourirletableau Denombreusesmthodespeuventtreutilisespourparcouriruntableaulaidedesconstructionssuivantes :
q

lastructuredecontrleitrativefor, lastructuredecontrleitrativewhile, lastructuredeparcoursdetableauforeach.

Danscelivre,noustudionsuniquementlutilisationdelastructure foreachquiestsanscontestelamthodelaplussimplepour parcouriruntableau.Cettemthodenencessiteaucuneconnaissanceparticuliresurlanaturedutableau(numrique,associatif, plagedesindices/cls,...). Syntaxe foreach(tableau as variable_valeur)

- 12 -

ENI Editions - All rigths reserved

{ instructions } ou foreach(tableau as variable_cl => variable_valeur) { instructions } Lapremiresyntaxepermetdeparcourirletableaududbutlafin chaqueitration,lavaleurcourantedutableaueststocke danslavariable variable_valeuretlesinstructionsentreaccoladessontexcutes.Cettesyntaxeestsuffisantesiletraitement napasbesoindefairerfrenceauxvaleursdelacl. La deuxime syntaxe fonctionne sur le mme principe, mais chaque itration, la cl courante est stocke dans la variable variable_cletlavaleurdanslavariablevariable_valeur.Cettesyntaxeestpratiquesiletraitementabesoindefairerfrence auxvaleursdelacl. Exemple <?php // Initialisation dun tableau. $nombres = array(zro,un,deux, zro => 0,un => 1,deux => 2); // Parcours du tableau avec la premire syntaxe. echo Premire syntaxe :<br />; foreach($nombres as $nombre) { echo "$nombre<br />"; } // Parcours du tableau avec la deuxime syntaxe echo Deuxime syntaxe :<br />; foreach($nombres as $cl => $nombre) { echo "$cl => $nombre<br />"; } ?> Rsultat Premire syntaxe : zro un deux 0 1 2 Deuxime syntaxe : 0 => zro 1 => un 2 => deux zro => 0 un => 1 deux => 2

n cas de besoin, linstruction break (cf. dans ce chapitre Les bases du langage PHP Structures de contrle) peut tre E utilisepourinterrompreleparcoursdutableauavantlafin.

5.Oprateurs
a.Loprateurdaffectationparvaleur
Loprateurdaffectationestlesignegal(=). Syntaxe $variable = expression; Exemple <?php $nom = Olivier; $indice = 1; ?> Avec cette syntaxe, laffectationseffectue par valeur, cestdirequelavaleurdelexpression situe droite du signe gal est copiedanslavariablementionnegauche. Loprationdaffectationestuneexpressionquiaunevaleurgalelavaleuraffecteetquipeuttreutilisedirectementdans

ENI Editions - All rigths reserved

- 13 -

uneautreexpression.Parexemple,lavaleurdelexpression $x=1 est 1etilestlicitedcrireuneinstructiondutype $y=($x=1)+2 affectantlavaleur3$y. Exemple <?php // Affectation en une instruction de $x et $y. $y = ($x = 1) + 2; // Affichage du rsultat. echo "\$x = $x<br />"; echo "\$y = $y<br />"; ?> Rsultat $x = 1 $y = 3 Cettetechniqueesttrspratiquemaispeutnuirelalisibilitducode. our tous les oprateurs qui seront tudis dans ce chapitre, des espaces peuvent ou non tre prsents autour de P loprateur.

b.Loprateurdaffectationparrfrence
Ilestpossibledefaireuneaffectationparrfrenceenutilisantloprateur&. Syntaxe $variable2 = & $variable1; Exemple <?php $nom = Olivier; $patronyme = &nom; ?> Avec cette syntaxe, la valeur de la variable $variable1 nest pas copie dans la variable $variable2. La variable $variable2 fait rfrence la variable $variable1 les deux variables pointent vers la mme zone mmoire et la modification dune des deux variablesserpercutesurlautre. Exemple <?php // Initialisation dune variable. $nom = Olivier; // Affectation dans une autre variable par rfrence. $patronyme = &$nom; // Affichage du rsultat. echo "<b>Initialement :</b><br />"; echo "\$nom = $nom<br />"; echo "\$patronyme = $patronyme<br />"; // Modification de la premire variable. $nom = Heurtel; // Affichage du rsultat. echo "<b>Aprs modification de \$nom :</b><br />"; echo "\$nom = $nom<br />"; echo "\$patronyme = $patronyme<br />"; ?> Rsultat Initialement : $nom = Olivier $patronyme = Olivier Aprs modification de $nom : $nom = Heurtel $patronyme = Heurtel

c.Lesoprateursarithmtiques

- 14 -

ENI Editions - All rigths reserved

Lesoprateursarithmtiquessontlessuivants : Opration Somme Soustraction Multiplication Division Modulo(restedeladivisionentiredu premieroprandeparledeuxime) Oppos Princrmentation(incrmentela variableavantderetournerlavaleur delavariable) Postincrmentation(incrmentela variableaprsavoirretournlavaleur delavariable) Prdcrmentation(dcrmentela variableavantderetournerlavaleur delavariable) Postdcrmentation(dcrmentela variableaprsavoirretournlavaleur delavariable) Oprateur + * / Exemple($x=13et$y=8) echo$x+$y=>21 echo$x$y=>5 echo$x*$y=>104 echo$x/$y=>1.625

echo$x%$y=>5

echo$x=>13

++avantloprande

echo++$x=>14

echo$x++=>13 ++aprsloprande echo$x=>14

avantloprande

echo$x=>12

echo$x=>13 aprsloprande echo$x=>12

d.Loprateurdechane
Leseuloprateurdechaneestloprateurdeconcatnationgalaupoint(.). Syntaxe chane1.chane2; Cetoprateurretourneunechanegalelapremirechaneimmdiatementsuiviedeladeuxime aucunsparateurnestmis entrelesdeuxchanes. Exemple <?php // Utilisation de loprateur de concatnation avec des // variables et des expressions littrales. $prnom = Olivier; $nom = Heurtel; echo $nom., .$prnom.<br />; ?> Rsultat Heurtel, Olivier

e.Lesoprateursdecomparaison
Lesoprateursdecomparaisonsontlessuivants : Opration Oprateur Exemple($x=13,$y=8,$z="8") $x==$y=>FALSE galit == $y==$z=>TRUE $x===$y=>FALSE galitettypesidentiques ===

ENI Editions - All rigths reserved

- 15 -

$y===$z=>FALSE $x!=$y=>TRUE Diffrent != $y!=$z=>FALSE $x!==$y=>TRUE Diffrentoutypesdiffrents

!==
$y!==$z=>TRUE $x<$y=>FALSE

Infrieur

<

$y<$x=>TRUE $y<$z=>FALSE $x<=$y=>FALSE

Infrieurougal

<=

$y<=$x=>TRUE $y<=$z=>TRUE $x>$y=>TRUE

Suprieur

>

$y>$x=>FALSE $y>$z=>FALSE $x>=$y=>TRUE

Suprieurougal

>=

$y>=$x=>FALSE $y>=$z=>TRUE

N econfondezpasloprateurdaffectation(=)avecloprateurdecomparaison(==).

f.Lesoprateurslogiques
Lesoprateurslogiquessontlessuivants : Opration Oprateur Exemple TRUEandTRUE=>TRUE and Etlogique && FALSEandFALSE=>FALSE TRUEorTRUE=>TRUE or Oulogique || FALSEorFALSE=>FALSE TRUExorTRUE=>FALSE Oulogiqueexclusif(FALSEsilesdeux oprandessontTRUE) xor TRUExorFALSE=>FALSE FALSExorFALSE=>FALSE !TRUE=>FALSE Nonlogique ! !FALSE=>TRUE Lesoprateursandet&&ainsiqueoret||sontidentiquesmaisnontpaslammeprcdence. TRUEorFALSE=>TRUE TRUEandFALSE=>FALSE

g.Loprateurternaire
Unautreoprateurconditionnel,loprateurternaire?,fonctionnecommedanslelangageC. Syntaxe expression1?expression2:expression3

- 16 -

ENI Editions - All rigths reserved

Cetteinstructionretournelavaleurdeexpression2siexpression1estvalueTRUEetlavaleurdeexpression3siexpression1est value FALSE.Si expression1nestpasdetypeboolen,uneconversionesteffectueselonlesrglesdcritesprcdemment (cf.danscechapitreLesbasesdulangagePHPTypesdedonnes). Exemple <?php // Initialisation dune variable. $nom = ; // Affichage dun message dpendant de la valeur de $nom. echo Bonjour .(($nom==)?inconnu:$nom). ! <br />; // Affectation dune valeur la variable $nom. $nom = Olivier; // nouvelle tentative echo Bonjour .(($nom==)?inconnu:$nom). ! <br />; ?> Rsultat Bonjour inconnu ! Bonjour Olivier !

h.Lesoprateurscombins
Lesoprateurssomme( +),diffrence(-),multiplication(*),division(/),module(%)etconcatnation(.)peuventtrecombinsavec loprateurdaffectation(=)selonlasyntaxesuivante : Syntaxe $variable+=expression $variable=expression $variable*=expression $variable/=expression $variable%=expression quivalent $variable=$variable+expression $variable=$variableexpression $variable=$variable*expression $variable=$variable/expression $variable=$variable%expression $variable=$variable.expression

$variable .= expression

i.Prcdencedesoprateurs
Laprcdencedesoprateursdsignelordredanslesquelslesoprateurssonttraitsdansuneexpressioncomplte. Comme dans tous les langages, les parenthses peuvent tre utilises pour modifier lordre dans lequel les oprations sont traites. Dans la pratique, nhsitez pas utiliser les parenthses pour viter tout problme et amliorer la lisibilit des expressions. Laprcdencedesoprateursestlasuivante,dumoinsprioritaire(traitendernier)auplusprioritaire(traitenpremier) : Oprateur or xor and = += = *= /= %= .= ?: || && == != === < <= > >=

ENI Editions - All rigths reserved

- 17 -

+ . * / % ! ++ (int) (double) (string) (array) (object)

6.Structuresdecontrle
a.Lastructureif
Lastructuredecontrleifpermetuneexcutionconditionnelledinstructions. Syntaxe if (condition) { instructions; [ } elseif (condition) { instructions; ] [ ... ] [ } else { instructions; ] } Lesconditionsdesclausesifetelseifsonttestessquentiellement.Silaconditionestvraiealorslesinstructionsassociesdela clause sont excutes. Si aucune des conditions nest vraie, les instructions ventuelles dfinies dans la clause else sont excutes. Silesexpressionsdfinissantlesconditionsnesontpasdetypeboolen,uneconversionesteffectueselonlesrglesdcrites prcdemment(cf.danscechapitreLesbasesdulangagePHPTypesdedonnes). Exemple <?php // Structure if / elseif / else $nom = Olivier; $ge = NULL; if ($nom == NULL) { echo "Bonjour inconnu !<br />"; } elseif ($ge == NULL) { echo "Bonjour $nom ! Je ne connais pas votre ge.<br />"; } else { echo "Bonjour $nom ! Vous avez $ge ans.<br />"; } ?> Rsultat Bonjour Olivier ! Je ne connais pas votre ge. UnedeuximesyntaxepeuttreutilisepourcrireunestructuredecontrlesurplusieursblocsPHPentrelesquelsducodeHTML estintercal : <?php if (condition): ?> code_HTML [ <?php elseif (condition): ?> code_HTML ] [ ... ] [ <?php else: ?> code_HTML ] <?php endif; ?> Le principe danalyse de la structure if elseif else est le mme quavec la premire syntaxe, mais au lieu dexcuter des instructionsPHP,lemoteurincorporedanslersultatlecodeHTMLassocilacondition. Exemple <?php // Un peu dalatoire pour dfinir les variables $nom et $ge. $nom = rand(0,1)?Olivier:NULL; $ge = rand(0,1)?rand(7,77):NULL; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

- 18 -

ENI Editions - All rigths reserved

<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Exemple de page PHP</title> <style type="text/css" media="all"> .ko {font-weight: bold; color: red;} .ok {font-weight: bold; color: green;} </style> </head> <body> <div> <?php if ($nom == NULL) : // condition PHP ?> <!-- Code HTML --> Bonjour inconnu !<br /> <?php elseif ($ge == NULL) : // suite de la condition ?> <!-- Code HTML --> Je connais votre <span class="ok">nom</span> mais pas votre <span class="ko">ge</span>.<br /> <?php else : // suite de la condition PHP ?> <!-- Code HTML --> Je connais votre <span class="ok">nom</span> et votre <span class="ok">ge</span>, mais je ne dirai rien !<br /> <?php endif; // fin de la condition PHP ?> </div> </body> </html> Rsultat(dpenddelaffectationalatoiredesvariables) Je connais votre nom mais pas votre ge. CettesyntaxeestrellementtrspratiquepourfaireuneconstructionconditionnelledunepageHTML,envitantlalourdeurde lutilisationdunseulblocPHPgnranttoutlecodeHTMLaveclinstructionecho.

b.Lastructureswitch
Lastructuredecontrle switch,quivalenteuneconstruction ifelseifmultiple,estutilisepourlacomparaisondursultat duneexpressionavecplusieursrsultats. Commelinstructionif,cetteinstructionpossdedeuxsyntaxes : Premiresyntaxe switch (expression_test) { case expression: instructions; [break;] [ case expression: instructions; [break;] ] [ ... ] [ default: instructions; [break;] ] } expression_testestuneexpressionquiestvalueunefoisetdontlavaleurestcomparesquentiellementaveclesexpressions desclauses case.Si expression_testestgalelexpressiondelaclause casealorslesinstructionsassociessontexcuteset lescomparaisonssepoursuiventsilnyapasdinstruction break.Siaucunegalitnesttrouve,lesinstructionsventuellement dfiniesdanslaclausedefaultsontexcutes. Pourinterromprelexcutiondelinstructionswitchetlvaluationdesclausescase,ilfaututiliserlinstructionbreak.

<?php $nom = rand(0,1)?Olivier:NULL; switch ($nom) { case NULL : echo Bonjour inconnu ! , Je vais vous appeler Olivier.<br />; $nom = Olivier; break; case Olivier : echo "Bonjour Matre $nom !<br />"; break;

ENI Editions - All rigths reserved

- 19 -

default : echo "Bonjour lve $nom !<br />"; } ?> Rsultat(dpenddelaffectationalatoiredesvariables) Bonjour inconnu ! Je vais vous appeler Olivier. Commepourlinstruction if,ilexisteunedeuximesyntaxequipermetdimbriquerducodeHTMLdansunestructuredecontrle switch : <?php switch (expression_test): case (expression): ?> code_HTML [ <?php case (expression): ?> code_HTML ] [ ... ] [ <?php default: ?> code_HTML ] <?php endswitch; ?> LepremiercasedoittrecritdansleblocPHPswitch. Exemple <?php $langue = fr; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Exemple de page PHP</title> <style type="text/css" media="all"> .en {font-weight: bold; color: green;} .sp {font-weight: bold; color: orange;} .fr {font-weight: bold; color: blue;} .inconnu {font-weight: bold; color: red;} </style> </head> <body> <div> <?php switch ($langue) : // switch case en : // premier case ?> <!-- Code HTML --> Hello <span class="en">my friend</span> !<br /> <?php break; // break premier case ?> <?php case sp : // deuxime case ?> <!-- Code HTML --> Buenos dias <span class="sp">amigo</span> !<br /> <?php break; // break deuxime case ?> <?php case fr : // troisime case ?> <!-- Code HTML --> Salut <span class="fr">mon pote</span> !<br /> <?php break; // break troisime case ?> <?php default : // dfaut ?> <!-- Code HTML --> <span class="inconnu">?????</span> <?php endswitch; // fin du switch ?> </div> </body> </html> Rsultat Salut m o n p o t e !

c.Lastructurewhile
Lastructuredecontrlewhilepermetdexcuterenboucleunesriedinstructionstantquuneconditionestvraie. Syntaxe

- 20 -

ENI Editions - All rigths reserved

while (condition) { instructions; } Les instructions lintrieur de la boucle sont excutes tant que la condition de la clause while est vraie. Si lexpression dfinissantlaconditionnestpasdetypeboolen,uneconversionesteffectueselonlesrglesdcritesprcdemment(cf.dans cechapitreLesbasesdulangagePHPTypesdedonnes). Exemple <?php // Initialiser deux variables. $nom = OLIVIER; $longueur = 7; // Initialiser un indice. $indice = 0; // Tant que lindice est infrieur la longueur de la chane while ($indice < $longueur) { // Afficher le caractre correspondant lindice suivi // dun point. echo "$nom[$indice]."; // Incrmenter lindice $indice++; } ?> Rsultat O.L.I.V.I.E.R. Silaconditionestfausselapremireitration,lesinstructionssitueslintrieurdelabouclenesontjamaisexcutes.Sila conditionnest jamais fausse, les instructions lintrieur de la boucle sont excutes sans fin (pas tout fait puisque le temps dexcutiondunscriptestlimitparladirectivedeconfigurationmax_execution_time). Commepourlesstructuresconditionnelles,unedeuximesyntaxepermetdimbriquerducodeHTMLdansunestructuredecontrle while : <?php while (condition): ?> code_HTML <?php endwhile; ?> Exemple <?php // Initialiser deux variables. $numro = 0; $nombre = 5; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Exemple de page PHP</title> </head> <body> <form action=""> <div> Indiquez vos cinq comptences principales :<br /> <?php while($numro++ < $nombre) : // boucle PHP ?> <!-- Code HTML --> <input type="text" /><br /> <?php endwhile; // fin de la boucle PHP ?> <input type="submit" value = "OK" /><br /> </div> </form> </body> </html> Rsultat

ENI Editions - All rigths reserved

- 21 -

d.Lastructuredo...while
Lastructuredecontrledo...whilepermetdexcuterenboucleunesriedinstructionstantquuneconditionestvraie. Syntaxe do { instructions; } while (expression); Les instructions lintrieur de la boucle sont excutes tant que la condition de la clause while est vraie. la diffrence de la structurewhile,laconditionesttestelafindelaboucle lesinstructions instructionssontdoncforcmentexcutesaumoins unefois.Silexpressiondfinissantlaconditionnestpasdetypeboolen,uneconversionesteffectueselonlesrglesdcrites prcdemment(cf.danscechapitreLesbasesdulangagePHPTypesdedonnes). Exemple <?php // Initialiser deux variables. $nom = OLIVIER; $longueur = 7; // Initialiser un indice. $indice = 0; // Tant que lindice est infrieur la longueur de la chane do { // Afficher le caractre correspondant lindice suivi // dun point. echo "$nom[$indice]."; // Incrmenter lindice $indice++; } while ($indice < $longueur); ?> Rsultat O.L.I.V.I.E.R. Contrairementauxautresstructuresdecontrle,uneseulesyntaxeestdisponible.

e.Lastructurefor
Lastructuredecontrle for,commedanslelangageC,permetdexcuterdesinstructionsdemanireitrativeencontrlantles itrationslaidedetroisexpressions. Syntaxe for (expression1; expression2; expression3) { instructions; } Leprincipedefonctionnementdecettestructuredecontrleestlesuivant :
q

expression1estexcuteunefoisaudmarragedelaboucle. expression2estexcute,etlersultatestvalucommeboolen,avantchaqueitration(dontlapremire).Silersultat est valu TRUE les instructions instructionssontexcutes silersultatestvalu FALSE,labouclesarrte et le contrleestpasslapremireinstructionquisuitlaconstruction. expression3estexcutelafindechaqueitration.

Danslagrandemajoritdescas,linstructionforestemployedelamaniresuivante :

- 22 -

ENI Editions - All rigths reserved

expression1initialiseuncompteur. expression2testelavaleurducompteur. expression3incrmentelavaleurducompteur.

Cetteutilisationpermetdexcuterdesinstructionsunnombredonndefois. Exemple <?php // Utilisation de la structure for pour parcourir un tableau // indices entiers conscutifs // Initialisation du tableau. $couleurs = array(bleu,blanc,rouge); $nombre = 3; // Boucle utilisant un indice $i qui dmarre 0 ($i = 0) // qui est incrment dune unit chaque itration ($i++) ; // la boucle se poursuit tant que lindice est infrieur au // nombre dlments prsents dans le tableau ($i < $nombre). for ($i = 0; $i < $nombre; $i++) { echo "$couleurs[$i]<br />"; }; ?> Rsultat bleu blanc rouge UnedeuximesyntaxepermetdimbriquerducodeHTMLdansunestructuredecontrlefor : <?php for (expression1; expression2; expression3) : ?> code_HTML <?php endfor; ?> Lexemplefournipourlastructurewhilepeuttrecritavecunestructurefor. Exemple <?php // Initialiser deux variables. $numro = 0; $nombre = 5; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Exemple de page PHP</title> </head> <body> <form action=""> <div> Indiquez vos cinq comptences principales :<br /> <?php // boucle PHP for($numro = 1; $numro <= $nombre; $numro++): ?> <!-- Code HTML --> <input type="text" /><br /> <?php endfor; // fin de la boucle PHP ?> <input type="submit" value = "OK" /><br /> </div> </form> </body> </html>

f.Lesinstructionscontinueetbreak
Linstruction continue peut tre utilise dans toutes les structures de contrle itratives pour interrompre litration en cours et passerlitrationsuivante.

ENI Editions - All rigths reserved

- 23 -

Linstruction break peut tre utilise dans toutes les structures de contrle itratives pour interrompre la boucle en cours. Linstructionbreakpeutaussitreutilisedansunestructuredecontrleswitch. Syntaxe continue[ n]; continue[(n)]; break[ n]; break[(n)]; Lesdeuxinstructionsacceptentunparamtrequiindiquedecombiendeniveau(x)remontersidesstructuresdecontrleitratives sontimbriques.Pardfaut,lesinstructionsremontentdunniveau. Exemple <?php $couleurs = array(bleu,invisible,blanc,rouge); for ($i = 0; $i <= 3; $i++) { // Passer litration suivante pour // la couleur "invisible" if ($couleurs[$i] == invisible) { continue; } echo "$couleurs[$i] "; } echo <br />; for ($i = 0; $i <= 3; $i++) { // Interrompre la boucle la couleur "invisible" if ($couleurs[$i] == invisible) { break; } echo "$couleurs[$i] "; } ;?> Rsultat bleu blanc rouge bleu

7.Inclureunfichier
a.Fonctionnement
Lesfonctionsinclude,include_once,requireetrequire_oncepermettentdinclureunfichierdansunscriptPHP. Syntaxe entier include( chane fichier) entier include_once( chane fichier)require( chane fichier)require_once( chane fichier) fichier Nomdufichierinclure(peuttreindiquavecuncheminabsoluourelatif). Danslefichierphp.ini,ladirectiveinclude_pathpermetdedfinirdescheminsderecherchepourlinclusiondesfichiers.

Les fonctions include et include_once retournent 1 en cas de succs et FALSE en cas derreur. Les fonctions require et require_oncenontpasdecodederetour. En cas derreur, les fonctions include et include_once gnrent une simple erreur de niveau E_WARNING qui ninterrompt pas lexcutionduscript.Cenestpaslecasdesfonctions requireetrequire_oncequiprovoquentalorsuneerreurfataleinterrompant lexcutionduscript. LefichierincluspeutcontenirducodeHTML,ducodePHPoulesdeux.LecodePHPinclutdoittrecritentrelesbaliseshabituelles. LecodeHTMLprsentdanslefichierinclusestintgrtelqueldanslapageenvoyeaunavigateur,commesiltaitprsentdans lescriptappelant.LecodePHPprsentdanslefichierinclusestexcutcommesiltaitprsentdanslescriptappelant. Aprslinclusiontoutsepassecommesilnyavaitquunseulscript.Enconsquence,lesvariablesetconstantesdfiniesdansle fichierinclussontutilisablesdanslescriptappelantetrciproquement. Ilestpossibledinclureplusieursfichiersdansunscript,oudimbriquerlesinclusions(inclureunfichierquiluimmeinclutunautre fichier).

- 24 -

ENI Editions - All rigths reserved

Aveclesfonctionsincludeetrequire,leprocessusdinclusionestrptplusieursfoissilemmefichierestinclusplusieursfois. Dans certains cas, cette situation peut tre indsirable et involontaire, notamment lorsquun fichier est inclus une premire fois directementdansunscriptetunedeuximefoisindirectementparlinclusiondunautrefichier. Ce comportement peut tre vit en utilisant les fonctions include_once et require_once qui garantissent quun fichier ne sera inclusquunefoismmesilestappelplusieursfois. extensiondufichierinclureestparfaitementlibre.Ilnestnotammentpasobligatoiredutiliserlextension.phppourinclure L du code PHP : le fichier inclus nestpasdirectementexcutparlemoteurPHP(cestlescriptappelantquilest). Pour les fichiersinclusquinepeuventpasounedoiventpastreexcutsdirectement,ilestalorspossibledutiliseruneautreextension (.incparexemple).

Exemple:scriptprincipal <?php // Inclusion dun fichier include(commun.inc); // Dclaration dune variable $x dans le script principal. $x = 1; // Affichage de la variable $x. echo "Valeur de \$x dans le script principal : $x<br />"; // Affichage de la variable $y (dfinie dans le fichier // inclus). echo "Valeur de \$y dans le script principal : $y<br />"; ?> Fichierincluscommun.inc <!-- Dmarrage du fichier dinclusion en mode HTML (ouverture ---- dune balise <b> qui est ferme la fin du fichier --> <b>Dbut du fichier commun.inc<br /> <?php // un peu de code PHP // Dclaration dune variable $y dans le script inclus. $y = 2; // Affichage de la variable $y. echo "Valeur de \$y dans le fichier inclus : $y<br />"; ?> Fin du fichier commun.inc</b><br /> Rsultat Dbut du fichier commun.inc Valeur de $y dans le fichier inclus : 2 Fin du fichier commun.inc Valeur de $x dans le script principal : 1 Valeur de $y dans le script principal : 2

b.Utilisation
Latechniquedinclusionestpratiquepourdeuxgrandstypesdutilisation :
q

Incluredesdfinitionsstatiques:constantes,dfinitionsdefonctionsoudeclasses.Danscecas,ilfautpluttutiliserles fonctionsinclude_onceourequire_onceafindviteruneventuelledoubleinclusion(quiprovoqueraituneerreurencequi concerneladfinitiondesfonctions). InclureducodePHPouHTMLdynamiquequisexcuteeffectivementaumomentdelinclusion :sectionHTMLcommune plusieurspages(entte,pieddepage)oucodecommunplusieurspages(bienquedanscettehypothse,ladfinition dunefonctionsoitpluspertinente).Danscecas,ilfautpluttutiliserlesfonctionsincludeourequireafindegarantirque linclusionseproduitbienchaqueappel.

L acrationdefonctionspersonnalisesesttudiedanslechapitrecriredesfonctionsetdesclassesPHP. Exemple
q

Fichierdedfinitiondeconstantes(constantes.inc)

<?php // Dfinition des constantes // par exemple, le nom du site. DEFINE(NOM_SITE,monSite.com);

ENI Editions - All rigths reserved

- 25 -

?>
q

Fichiercontenantledbutdechaquepage( debut.inc)

<?php // Inclusion du fichier des constantes. include_once(constantes.inc); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title><?php echo NOM_SITE; ?></title></head> <body>
q

Fichiercontenantlafindechaquepage(fin.inc)

</body> </html>
q

Scriptdunepage

<?php // Inclusion du dbut de la page. include(debut.inc); ?> <p>Contenu de la page ...</p> <?php // Inclusion de la fin de la page include(fin.inc); ?> Rsultat(sourcedelapagedanslenavigateur) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>monSite.com</title></head> <body> <p>Contenu de la page ...</p> </body> </html>

8.Interromprelescript
Lesinstructionsexitetdiepermettentdinterromprelexcutionduscript(dieestunaliasdexit). exit[( chane message)]; exit[( entier statut)]; die[( chane message)]; die[( entier statut)]; message Messageafficheravantdinterromprelescript. statut Statutderetour(entierentre1et254). Le script sinterrompt brutalement et laffichage est laiss "en ltat". La page HTML envoye au navigateur peut donc tre incohrenteouvide. Silinstructionestappeledansunfichierinclus,cestlescriptprincipalquiestinterrompu. Exemple(sansmessage) <?php // Gnrer le dbut de la page. echo Bonjour ; // Une condition nest pas vrifie, interrompre le script. if ($nom == NULL) { exit(1); // pas de message ... }

- 26 -

ENI Editions - All rigths reserved

// Poursuivre la gnration de la page. echo $nom; ?> Rsultat Bonjour Exemple(avecmessage) <?php // Gnrer le dbut de la page. echo Bonjour ; // Une condition nest pas vrifie, interrompre le script. if ($nom == NULL) { exit(<b>Utilisateur inconnu. Impossible de continuer.</b>); } // Poursuivre la gnration de la page. echo $nom; ?> Rsultat Bonjour U t i l i s a t e u r i n c o n n u . I m p o s s i b l e d e c o n t i n u e r .

ENI Editions - All rigths reserved

- 27 -

Prambule
LobjectifdecechapitreestdeprsenterlesfonctionslesplusutilesdanslecadredudveloppementdunsiteWeb. PHP propose de nombreuses fonctions la description de chaque fonction est accessible en ligne sur le site www.php.net.

ENI Editions - All rigths reserved

- 1-

Manipulerlesconstantes,lesvariablesetlestypesdedonnes
1.Constantes
PHPproposeuncertainnombredefonctionsutilessurlesconstantes : Nom defined constant defined Lafonctiondefinedpermetdesavoirsiuneconstanteestdfinieounon. Syntaxe boolen defined( chane nom) nom Nomdelaconstante. LafonctiondefinedretourneTRUEsilaconstanteestdfinieetFALSEdanslecascontraire. Exemple <?php // Tester si la constante CONSTANTE est dfinie. $ok = defined(CONSTANTE); if ($ok) { echo CONSTANTE est dfinie.<br />; } else { echo CONSTANTE n\est pas dfinie.<br />; }; // Dfinir la constante CONSTANTE define(CONSTANTE,valeur de CONSTANTE); // Tester si la constante CONSTANTE est dfinie. $ok = defined(CONSTANTE); if ($ok) { echo CONSTANTE est dfinie.<br />; } else { echo CONSTANTE n\est pas dfinie.<br />; }; ?> Rsultat CONSTANTE nest pas dfinie. CONSTANTE est dfinie. Rle Indiquesiuneconstanteestdfinieounon. Retournelavaleurduneconstante.

constant Lafonctionconstantretournelavaleurduneconstantedontlenomestpassenparamtre. Syntaxe mixte constant( chane nom) nom Nomdelaconstante. Cettefonctionestpratiquepourrcuprerlavaleurduneconstantedontlenomnestpasconnuapriori. Exemple <?php // Dfinir le nom de la constante dans une variable.

ENI Editions - All rigths reserved

- 1-

$nomConstante = CONSTANTE; // Dfinir la valeur de la constante. define($nomConstante,valeur de CONSTANTE); // Afficher la valeur de la constante. echo $nomConstante, = , c o n s t a n t ( $ n o m C o n s t a n t e ) ; ?> Rsultat CONSTANTE = valeur de CONSTANTE Dautresfonctionspermettentdeconnatreletypeduneconstante(cf.danscechapitreManipulerlesconstantes,lesvariables etlestypesdedonnesTypesdedonnes).

2.Variables
PHPproposeuncertainsnombredefonctionsutilessurlesvariables : Nom isset empty unset var_dump isset Lafonctionissetpermetdetestersiunevariableestdfinieounon. Syntaxe boolen isset( mixte variable) variable Variabletester. LafonctionissetretourneTRUEsilavariableestdfinieetFALSEdanslecascontraire. UnevariableestconsidrecommenondfiniesiellenapastaffecteousiellecontientNULL. Exemple <?php // Test dune variable non initialise. $est_dfinie = isset($variable); echo $variable non initialise<br />; if ($est_dfinie) { echo => $variable est dfinie.<br />; } else { echo => $variable n\est pas dfinie.<br } // Test dune variable contenant une chane $variable = ; $est_dfinie = isset($variable); echo $variable = \\<br />; if ($est_dfinie) { echo => $variable est dfinie.<br />; } else { echo => $variable n\est pas dfinie.<br } // Test dune variable contenant une chane $variable = x; $est_dfinie = isset($variable); echo $variable = \,$variable,\<br />; if ($est_dfinie) { echo => $variable est dfinie.<br />; } else { Rle Indiquesiunevariableestdfinieounon. Indiquesiunevariableestvideounon. Supprimeunevariable. Affichedesinformationssurunevariable(typeetvaleur).

/>; vide.

/>; non vide.

- 2-

ENI Editions - All rigths reserved

echo => $variable n\est pas dfinie.<br />; } ?> Rsultat $variable non initialise => $variable nest pas dfinie. $variable = => $variable est dfinie. $variable = x => $variable est dfinie.

empty Lafonctionemptypermetdetestersiunevariableestvideounon. Syntaxe boolen empty( mixte variable) variable Variabletester. LafonctionemptyretourneTRUEsilavariableestvideetFALSEdanslecascontraire. Unevariableestconsidrecommevidesiellenapastaffecteousiellecontientunechanevide( ""),unechanegale0 ("0"),0,NULLouFALSE. Exemple <?php // Test dune variable non initialise. $est_vide = empty($variable); echo $variable non initialise<br />; if ($est_vide) { echo => $variable est vide.<br />; } else { echo => $variable n\est pas vide.<br />; } // Test dune variable contenant une chane vide. $variable = ; $est_vide = empty($variable); echo $variable = \\<br />; if ($est_vide) { echo => $variable est vide.<br />; } else { echo => $variable n\est pas vide.<br />; } // Test dune variable contenant une chane non vide. $variable = x; $est_vide = empty($variable); echo $variable = \,$variable,\<br />; if ($est_vide) { echo => $variable est vide.<br />; } else { echo => $variable n\est pas vide.<br />; } ?> Rsultat $variable non initialise => $variable est vide. $variable = => $variable est vide. $variable = x => $variable nest pas vide.

unset Lafonctionunsetpermetdesupprimerunevariable.

ENI Editions - All rigths reserved

- 3-

Syntaxe unset( mixte variable[, ...]) variable Variablesupprimer(ventuellementplusieurs,sparesparunevirgule). Lafonctionunsetaccepteunelistedevariables. Aprssuppression,lavariablesetrouvedanslemmetatquesiellenavaitjamaistaffecte.Lutilisationdelafonctionisset surunevariablesupprimeretourneFALSE. Exemple <?php // Dfinir une variable. $variable = 1; // Afficher la variable et tester si elle est dfinie. $est_dfinie = isset($variable); echo $variable = ,$variable,<br />; if ($est_dfinie) { echo => $variable est dfinie.<br />; } else { echo => $variable n\est pas dfinie.<br />; } // Supprimer la variable. unset($variable); // Afficher la variable et tester si elle est dfinie. $est_dfinie = isset($variable); echo $variable = ,$variable,<br />; if ($est_dfinie) { echo => $variable est dfinie.<br />; } else { echo => $variable n\est pas dfinie.<br />; } ?> Rsultat $variable = 1 => $variable est dfinie. $variable = => $variable nest pas dfinie.

var_dump Lafonctionvar_dumpaffichedesinformationssurunevariable(typeetcontenu). Syntaxe var_dump( mixte variable) variable Variableafficher. Lafonctionvar_dumpestsurtoutintressantelorsdesphasesdemiseaupoint. Exemple <?php // Variable non initialise. var_dump($variable); // Variable initialise avec un nombre entier. $variable = 10; echo <br />; var_dump($variable); // Variable initialise avec un nombre dcimal. $variable = 3.14; echo <br />; var_dump($variable); // Variable initialise avec une chane. $variable = abc; echo <br />;

- 4-

ENI Editions - All rigths reserved

var_dump($variable); ?> Rsultat NULL int(10) float(3.14) string(3) "abc" Pourunevariablenoninitialise, var_dumpretourneNULL.Pourunnombre,var_dumpindiqueletype(int=entier,float=nombre dcimal) suivi de la valeur entre parenthses. Pour une chane, var_dump indique le type (string) suivi de la longueur entre parenthsespuisdelavaleurentreguillemets. PHPproposeaussilesfonctionsprint_retvar_exportsimilaireslafonctionvar_dump.Lafonctionprint_rafficheouretournele contenudelavariablesousuneformepluslisible,sansmentiondutypededonnes.Lafonction var_exportafficheouretourne unechanedonnantuncodePHPdedfinitiondelavariable cettefonctionestnouvelleenversion5. anslasectionTypesdedonnes,noustudieronsdautresfonctionsquipermettentdedterminerletypedunevariable D etdeffectuerdesconversionsdetype(nombreenchane,chaneennombre,etc.).

3.Typesdedonnes
a.Conversions
PHP est capable deffectuer des conversions automatiques implicites de type, selon les rgles prsentes dans le chapitre IntroductionPHPLesbasedulangagePHP. Lorsquunevaleur/expressionestaffecteunevariable,lavariabledevientdutypedelavaleur/expression. Pour dterminer le type dune expression compose doprandes de types diffrents, PHP value (mais ne convertit pas) les oprandesenfonctiondesoprateurstraitsdanslordredeprcdence(cf.chapitreIntroductionPHPLesbasedulangage PHP).Parexemple,lesdeuxoprandesutilissdansuneadditionsontvalusennombrealorsquedeuxoprandesutiliss avecloprateurdeconcatnationsontvalusenchane. Exemple <?php $nombre = 123; $chane = "456abc"; echo $nombre + $chane = ; var_dump($nombre + $chane); echo <br />; echo $nombre . $chane = ; var_dump($nombre . $chane); echo <br />; echo $nombre = ; var_dump($nombre); echo <br />; echo $chane = ; var_dump($chane); ?> Rsultat $nombre $nombre $nombre $chane + . = = $chane = int(579) $chane = string(9) "123456abc" int(123) string(6) "456abc"

Surlepremierexemple,lavariable $chaneatvalueennombrepourtredutypeattenduparloprateur + alorsque dans le deuxime exemple, cest $nombre qui a t value en chane pour tre du type attendu par loprateur . (concatnation).Parcontre,lesdeuxderniersaffichagesmontrentquelesvariablesenquestionnontpastconverties lorsdesoprations :ellesconserventleurtyperespectifinitial. Encomplment,PHPproposeunenotationetunefonctionpoureffectueruneconversionmanuelleexplicite. Notation La notation consiste indiquer le nom du type souhait entre parenthses devant lexpression convertir. Les valeurs autorisessontlessuivantes :

ENI Editions - All rigths reserved

- 5-

Notation (int)ou(integer) (bool)ou(boolean) (real),(double)ou(float) (string) (array) (object) Exemple

Conversionen entier boolen nombrevirguleflottante chane tableau objet

<?php echo (float)"1abc" = ,var_dump((float)"1abc"),<br />; echo (float)"1.5abc" = ,var_dump((float)"1.5abc"),<br />; echo (float)"abc1" = ,var_dump((float)"abc1"),<br />; echo (int)1.7 = ,var_dump((int)1.7),<br />; echo (int)TRUE = ,var_dump((int)TRUE),<br />; echo (int)FALSE = ,var_dump((int)FALSE),<br />; echo (bool)-1 = ,var_dump((bool)-1),<br />; echo (bool)0 = ,var_dump((bool)0),<br />; echo (bool)1 = ,var_dump((bool)1),<br />; echo (bool)"" = ,var_dump((bool)""),<br />; echo (bool)"0" = ,var_dump((bool)"0"),<br />; echo (bool)"1" = ,var_dump((bool)"1"),<br />; echo (bool)"a" = ,var_dump((bool)"a"),<br />; ?> Rsultat (float)"1abc" = float(1) (float)"1.5abc" = float(1.5) (float)"abc1" = float(0) (int)1.7 = int(1) (int)TRUE = int(1) (int)FALSE = int(0) (bool)-1 = bool(true) (bool)0 = bool(false) (bool)1 = bool(true) (bool)"" = bool(false) (bool)"0" = bool(false) (bool)"1" = bool(true) (bool)"a" = bool(true) Cesdiffrentsexemplespermettentderetrouverlesrglesdeconversionvoquesdansleparagrapheprcdent. Fonctiondeconversion Lafonctionsettypepermetdeconvertirunevariableduntypeunautre. Syntaxe boolen settype( mixte variable, chane type) variable Variableconvertir type Typesouhaitenutilisantunedesvaleurs :booleanoubool(conversionenboolen) integerouint(conversionenentier) doubleoufloat(conversionennombrevirguleflottante)string(conversionenchanedecaractres)array(conversionen tableau)object(conversionenobjet) LafonctionsettyperetourneTRUEencasdesuccsetFALSEencasderreur. Exemple

- 6-

ENI Editions - All rigths reserved

<?php $x = 1abc; settype($x,integer); echo \1abc\ converti en entier = ,var_dump($x),<br />; $x = 1.7; settype($x,integer); echo 1.7 converti en entier = ,var_dump($x),<br />; $x = TRUE; settype($x,string); echo TRUE converti en chane = ,var_dump($x),<br />; $x = 0; settype($x,boolean); echo \0\ converti en boolen = ,var_dump($x),<br />; $x = -1; settype($x,boolean); echo -1 converti en boolen = ,var_dump($x),<br />; ?> Rsultat "1abc" converti en entier = int(1) 1.7 converti en entier = int(1) TRUE converti en chane = string(1) "1" "0" converti en boolen = bool(false) -1 converti en boolen = bool(true)

n rgle gnrale, il est conseill dutiliser la conversion explicite : le code est plus lisible, plus facile maintenir et E mettreaupoint.

b.Fonctionsutiles
Encomplment,PHPproposeplusieursfonctionsutilesrelativesautypedesvariables : Nom Rle Indiquesilavariableestdutypedonnpar* array=tableau bool=boolen double,float,real=nombrevirguleflottante int,integer,long=entier is_* null=typeNULL numeric=entierounombrevirguleflottanteouchane contenantunnombre(entieroudcimal) object=objet string=chane resource=ressource scalar=typescalaire. strval floatval, doubleval intval is_* Chaquefonctionis_*permetdetestersiunevariableestduntypedonn. Syntaxe boolen is_* ( mixte variable) variable Convertitunevariableenchane. Convertirunevariableennombrevirguleflottante. Convertirunevariableenentier.

ENI Editions - All rigths reserved

- 7-

Variabletester. Lesdclinaisonssontlessuivantes : Fonction is_array is_bool Typetest tableau boolen

is_double
is_float is_real is_int is_integer is_long is_null typeNULL entierounombrevirguleflottanteouchanecontenant unnombre(entieroudcimal) objet chane ressource typescalaire Entier nombrevirguleflottante

is_numeric

is_object is_string is_resource is_scalar

CesfonctionsretournentTRUEsilavariableestdutypedemandetFALSEdanslecascontraire. Exemple <?php if (is_null($x)) { echo Pour l\instant, $x est du type NULL.<br />; } $x = (1 < 2); if (is_bool($x)) { echo $x = (1 < 2) est du type boolen.<br />; } $x = 123abc; if (is_string($x)) { echo $x = "123abc" est du type chane ...<br />; } if (! is_numeric($x)) { echo ... mais pas du type <i>numeric</i>.<br />; } ?> Rsultat Pour linstant, $x est du type NULL. $x = (1 < 2) est du type boolen. $x = "123abc" est du type chane ... ... mais pas du type numeric. Cetexemplemontrequelafonctionis_numericnappliquepastoutfaitlesmmesrglespourvaluersiunechanecontient unnombrequecellesutilisespourlaconversion.Aveclafonction is_numeric,lachanenedoitconteniraucuncaractrenon numrique. strval Lafonctionstrvalretournelavaleurdunevariableaprsconversionenchane.

- 8-

ENI Editions - All rigths reserved

Syntaxe chane strval( mixte variable) variable Variabletraiter. Cette fonction ne sapplique quaux variables de type scalaire (non valable pour les tableaux, ni les objets). Le type de la variableestinchang. Exemple <?php $x = TRUE; echo var_dump($x), => ,var_dump(strval($x)),<br />; $x = 1.2345; echo var_dump($x), => ,var_dump(strval($x)),<br />; ?> Rsultat bool(true) => string(1) "1" float(1.2345) => string(6) "1.2345"

floatval(oudoubleval) Lafonction floatvalretournelavaleurdunevariableaprsconversionennombrevirguleflottante.Lafonction doublevalest unaliasdelafonctionfloatval. Syntaxe nombre doubleval( mixte variable) variable Variabletraiter. Cette fonction ne sapplique quaux variables de type scalaire (non valable pour les tableaux, ni les objets). Le type de la variableestinchang.Lesrglesdeconversionsvoquesprcdemmentsontrespectes. Exemple <?php $x = TRUE; echo var_dump($x)," => ",var_dump(doubleval($x)),<br />; $x = 123; echo var_dump($x)," => ",var_dump(doubleval($x)),<br />; $x = "1.2345"; echo var_dump($x)," => ",var_dump(doubleval($x)),<br />; ?> Rsultat bool(true) => float(1) int(123) => float(123) string(6) "1.2345" => float(1.2345)

intval Lafonctionintvalretournelavaleurdunevariableaprsconversionenentier. Syntaxe nombre intval( mixte variable) variable Variabletraiter. Cette fonction ne sapplique quaux variables de type scalaire (non valable pour les tableaux, ni les objets). Le type de la variableestinchang.Lesrglesdeconversionsvoquesprcdemmentsontrespectes. Exemple

ENI Editions - All rigths reserved

- 9-

<?php $x = TRUE; echo var_dump($x), => ,var_dump(intval($x)),<br />; $x = 123.9; echo var_dump($x), => ,var_dump(intval($x)),<br />; $x = "9.99"; echo var_dump($x), => ,var_dump(intval($x)),<br />; ?> Rsultat bool(true) => int(1) float(123.9) => int(123) string(4) "9.99" => int(9) Noubliezpasquunnombrevirguleflottanteconvertienentieresttronquetnonarrondi :surnotreexemple, 123.9donne 123etnon124.Pourconvertirunnombrevirguleflottanteenentier,avecarrondi,ilfaututiliserlafonctionround(). Exemple <?php $x = 123.9; echo "round($x) => "; var_dump(round($x)); ?> Rsultat round(123.9) => float(124) Lafonction round()retournebienunnombreentierarrondi,maisavecuntypedenombrevirguleflottante.Pourobtenirune donnedetypeentier,ilsuffitdeconvertirlersultatderound()enentier(aveclafonctionintvaloulaconstruction(int)).

- 10 -

ENI Editions - All rigths reserved

Manipulerlestableaux
PHPproposeuntrsgrandnombredefonctionspermettantdemanipulerlestableaux. Lesfonctionslesplusutilisessontlessuivantes : Nom count in_array array_search [a|k][r]sort Rle Comptelenombredlmentsdansuntableau. Testesiunevaleurestprsentedansuntableau. Rechercheunevaleurdansuntableau. Trientuntableau(plusieursvariantespossibles). Dcoupeunechaneselonunsparateuretstockeles lmentsdansuntableau. Dcoupeunechaneenmorceauxdelongueurfixeet stockeleslmentsdansuntableau. Regroupeleslmentsduntableaudansunechane laidedunsparateur.

explode

str_split

implode

oubliezpaslafonction is_arrayquipermetdesavoirsiunevariableestdetypetableau(cf.danscechapitre N Manipulerlesconstantes,lesvariablesetlestypesdedonnesTypesdedonnes). De nombreuses autres fonctions existent. La description de chaque fonction est accessible en ligne sur le site www.php.net.Vousytrouvereznotammentdesfonctionspour :
q

raliserdescalculs(somme,...) extraireunsoustableauduntableau fusionnerdestableaux ddoublonneruntableau,etc.

count Lafonctioncountpermetdeconnatrelenombredlmentsdansunevariableengnral,untableauenparticulier. Syntaxe entier count ( mixte variable) variable Variableconcerne Lafonction countretournelenombredlmentsdanslavariable.Silavariablenestpasinitialise, countretourne0.Si lavariableestinitialisemaisnestpasuntableau, countretourne1(ilyaeffectivementunlmentdansunevariable scalaire).Silavariableestuntableau,countretournelenombredlmentsprsentsdansletableau(0siletableauest vide). Exemple <?php echo $x non initialis => ,count($x),<br />; $x = 1;

ENI Editions - All rigths reserved

- 1-

echo $x = echo $x = echo ?>

$x de type scalaire => ,count($x),<br />; array(); $x tableau vide => ,count($x),<br />; array(1,2); $x tableau de 2 lments => ,count($x),<br />;

Rsultat $x $x $x $x non initialis => 0 de type scalaire => 1 tableau vide => 0 tableau de 2 lments => 2

in_array Lafonctionin_arraypermetdetestersiunevaleurestprsentedansuntableau. Syntaxe boolen in_array( mixte valeur_cherche, tableau tableau[, boolen mme_type]) valeur_cherche Valeurcherchedansletableau. tableau Tableaudanslequelseffectuelarecherche. mme_type Indiquesilacomparaisondoitvrifierqueleslmentssontdummetype(FALSEpardfaut). Lafonctionin_arrayretourneTRUEsillmentcherchestprsentdansletableauetFALSEdanslecascontraire. HPproposeaussilafonctionarray_key_existsquipermetdetestersiunevaleurestprsentedanslesclsdun P tableau. Exemple <?php $nombres = array(zro,un,deux, zro => 0,un => 1,deux => 2); echo 1 type indiffrent => , var_dump(in_array(1,$nombres)),<br />; echo 3 type indiffrent => , var_dump(in_array(3,$nombres)),<br />; echo \1\ mme type => , var_dump(in_array(1,$nombres,TRUE)),<br />; echo \un\ type indiffrent => , var_dump(in_array(un,$nombres)),<br />; echo \trois\ type indiffrent => <b>, var_dump(in_array(trois,$nombres)),</b><br />; echo \trois\ mme type => , var_dump(in_array(trois,$nombres,TRUE)),<br /> ;?> Rsultat 1 type indiffrent => bool(true) 3 type indiffrent => bool(false) 1 mme type => bool(false) un type indiffrent => bool(true) trois type indiffrent => b o o l ( t r u e ) trois mme type => bool(false)
- 2 ENI Editions - All rigths reserved

Les deux exemples avec trois montrent que la fonction in_array est manipuler avec beaucoup de prcaution lorsque le tableau contient des lments de type diffrent. En effet, sur la recherche de mme type, la fonction fonctionnecorrectement(ilnyapasdechanetroisdansletableau).Surlarechercheoletypeestindiffrent,tout se passe comme si la chane tait convertie en entier (trois converti en entier donne 0) et que la recherche seffectuaitsurlersultatdecetteconversion(0estbienprsentdansletableau). array_search Lafonction array_searchpermetdechercherunlmentdansuntableauetdercuprerlacldecetlment,silest prsent. Syntaxe mixte array_search( mixte valeur_cherche, tableau tableau[, boolen mme_type]) valeur_cherche Valeurcherchedansletableau. tableau Tableaudanslequelseffectuelarecherche. mme_type Indiquesilacomparaisondoitvrifierqueleslmentssontdummetype(FALSEpardfaut). Lafonction array_searchretournelaclassociellmentsicedernierestprsentdansletableauet FALSEdansle cascontraire(NULLavantlaversion4.2.0). Exemple <?php $nombres = array(zro,un,deux, zro => 0,un => 1,deux => 2); echo 1 type indiffrent => , var_dump(array_search(1,$nombres)),<br />; echo 3 type indiffrent => , var_dump(array_search(3,$nombres)),<br />; echo \1\ mme type => , var_dump(array_search(1,$nombres,TRUE)),<br />; echo \un\ type indiffrent => , var_dump(array_search(un,$nombres)),<br />; echo \trois\ type indiffrent => <b>, var_dump(array_search(trois,$nombres)),</b><br />; echo \trois\ mme type => , var_dump(array_search(trois,$nombres,TRUE)),<br /> ;?> Rsultat 1 type indiffrent => string(2) "un" 3 type indiffrent => bool(false) 1 mme type => bool(false) un type indiffrent => int(1) trois type indiffrent => string(4) "zro" trois mme type => bool(false) Nous retrouvons sur ces exemples le problme voqu avec la fonction in_array : la recherche sur trois, en type indiffrent,donnelaclzroquicorrespondeffectivementlavaleur0dansletableau. [a|k][r]sort Lesfonctionssort,rsort,asort,arsort,ksortetkrsortpermettentdetrieruntableauselondiffrentesvariantes. Syntaxe

ENI Editions - All rigths reserved

- 3-

boolen [a|k][r]sort( tableau tableau, entier indicateur) tableau Tableautrier. indicateur Paramtreoptionnelpermettantdemodifierlecomportementdutri :
q

SORT_REGULAR(valeurpardfaut) :compareleslmentsnormalement(nemodifiepaslestypes). SORT_NUMERIC :compareleslmentsnumriquement. SORT_STRING :compareleslmentscommedeschanesdecaractres. SORT_LOCALE_STRING (apparu dans la version 5.0.2) : compare les lments en utilisant la configuration locale dfinieparlafonctionsetlocale.

Trieruntableaucomportantdesvaleursdediffrentstypesdonneunrsultatimprvisible. Lesvariantesdefonctionnementsontlessuivantes : Fonction Naturedutri Tricroissantsurlavaleur,sansprservationdes couplescl/valeur. sort Quellequesoitlasituationdedpart,aprsletri,les indicesdutableausontdesentiersconscutifspartir de0. Tridcroissantsurlavaleur,sansprservationdes couplescl/valeur. rsort Quellequesoitlasituationdedpart,aprsletri,les indicesdutableausontdesentiersconscutifspartir de0. Tricroissantsurlavaleur,avecprservationdes couplescl/valeur. Tridcroissantsurlavaleur,avecprservationdes couplescl/valeur. Tricroissantsurlacl,avecprservationdescouples cl/valeur. Tridcroissantsurlacl,avecprservationdes couplescl/valeur.

asort

arsort

ksort

krsort

CesfonctionsretournentTRUEencasdesuccsetFALSEencasdchec. Exemple <?php $tableau = array(c3 => rouge,c1 => vert, c2 => bleu); // Affichage de contrle. echo <b>Tableau de dpart :</b><br />; foreach($tableau as $cl => $valeur) { echo "$cl => $valeur<br />"; } // sort echo <b>sort : tri sur valeur, cls non prserves</b><br />;

- 4-

ENI Editions - All rigths reserved

$tableau_bis = $tableau; sort($tableau_bis); foreach($tableau_bis as $cl => $valeur) { echo "$cl => $valeur<br />"; } // asort echo <b>asort : tri sur valeur, cls prserves</b><br />; $tableau_bis = $tableau; asort($tableau_bis); foreach($tableau_bis as $cl => $valeur) { echo "$cl => $valeur<br />"; } // ksort echo <b>ksort : tri sur cl, cls prserves</b><br />; $tableau_bis = $tableau; ksort($tableau_bis); foreach($tableau_bis as $cl => $valeur) { echo "$cl => $valeur<br />"; } ?> Rsultat Tableau de dpart : c3 => rouge c1 => vert c2 => bleu sort : tri sur valeur, cls non prserves 0 => bleu 1 => rouge 2 => vert asort : tri sur valeur, cls prserves c2 => bleu c3 => rouge c1 => vert ksort : tri sur cl, cls prserves c1 => vert c2 => bleu c3 => rouge

explode Lafonctionexplodepermetdedcouperunechaneselonunsparateuretdestockerleslmentsdansuntableau. Syntaxe tableau explode( chane sparateur, chane _dcouper[, entier limite]) sparateur Sparateurrecherch. _dcouper Chanedcouper. limite Sispcifi,nombremaximumdlmentsdansletableaursultat. Exemple <?php $liste = bleu, blanc, rouge; $couleurs = explode(, ,$liste); // sparateur = virgule+espace foreach($couleurs as $cl => $valeur) { echo "$cl => $valeur<br />"; } ?> Rsultat
ENI Editions - All rigths reserved - 5-

0 => bleu 1 => blanc 2 => rouge

str_split Lafonctionstr_splitdcoupeunechaneenmorceauxdelongueurfixeetstockeleslmentsdansuntableau. Syntaxe tableau str_split( chane chane[, entier longueur]) chane Chanedcouper. longueur Longueurdesmorceaux(1pardfaut). Exemple <?php $chane = A1B2C3; $tableau = str_split($chane,2); foreach($tableau as $cl => $valeur) { echo "\$tableau[$cl] = $valeur<br>"; } ?> Rsultat $tableau[0] = A1 $tableau[1] = B2 $tableau[2] = C3

implode Lafonctionimplodepermetderegrouperleslmentsduntableaudansunechanelaidedunsparateur chane implode( chane sparateur, tableau lments) sparateur Sparateurutilis. lments Tableaucontenantleslmentsregrouper. Exemple <?php $couleurs = array(bleu,blanc,rouge); $liste = implode(, ,$couleurs); // sparateur = virgule+espace echo $liste; ?> Rsultat bleu, blanc, rouge

- 6-

ENI Editions - All rigths reserved

Manipulerleschanesdecaractres
Lesfonctionslesplusutilespourmanipulerleschanesdecaractressontlessuivantes : Nom strlen strtolower strtoupper Conversionsminuscules/majuscules. ucfirst ucwords strcmp Comparaisondechanes(sensiblelacasseounon). strcasecmp [s]printf v[s]printf number_format [l|r]trim substr str_repeat Rle Retournelenombredecaractresdunechane.

Miseenformedunechane(identiqueauxfonctionsC quivalentes). Miseenformedunnombre. Suppressiondecaractres"blancs". Extractionduneportiondechane. Constructiondunechaneparrptitiondecaractres. Recherchelapositionduneoccurrence(caractreou chane)lintrieurdunechane. Extractiondelasouschanecommenantpartirdune certaineoccurrenceduncaractreoudunechane. Remplacementdesoccurrencesdunechaneparuneautre chane. Remplacementdesoccurrencesduncaractreparunautre caractreoudunechaneparuneautrechane. Rechercheetremplacementlaidedexpressions rgulires.

str[r][i]pos

str[i]str strrchr

str_[i]replace

strtr

ereg[i] ereg[i]_replace

Noubliezpaslesfonctionsexplodeetimplodeprsentesprcdemment(cf.danscechapitreManipulerlestableaux).

autres fonctions, plus spcifiquement lies la gestion des "guillemets magiques" sont tudies plus loin dans ce D chapitre(cf.danscechapitreGrerles"guillemetsmagiques"("magicquotes")).

strlen Lafonctionstrlenretournelenombredecaractresdunechane. Syntaxe entier strlen( chane chane) chane Chaneconcerne

ENI Editions - All rigths reserved

- 1-

Exemple <?php $x = Olivier Heurtel; echo "strlen($x) = ",strlen($x); ?> Rsultat strlen(Olivier Heurtel) = 15

strtolowerstrtoupperucfirstucwords Cesfonctionspermettentdefairedesconversionsminuscules/majuscules. Syntaxe chane chane chane chane chane Chanetraiter Lafonctionstrtolowerconvertittouslescaractresdunechaneenminuscules. Lafonctionstrtoupperconvertittouslescaractresdunechaneenmajuscules. Lafonctionucfirstconvertitlepremiercaractredunechaneenmajuscules. Lafonctionucwordsconvertitlepremiercaractredechaquemotdunechaneenmajuscule. Exemple <?php $x = OLIVIER HEURTEL; $y = olivier heurtel; echo "strtolower($x) = ",strtolower($x),<br />; echo "strtoupper($y) = ",strtoupper($y),<br />; echo "ucfirst($y) = ",ucfirst($y),<br />; echo "ucwords($y) = ",ucwords($y),<br />; ?> Rsultat strtolower(OLIVIER HEURTEL) = olivier heurtel strtoupper(olivier heurtel) = OLIVIER HEURTEL ucfirst(olivier heurtel) = Olivier heurtel ucwords(olivier heurtel) = Olivier Heurtel strtolower( chane chane) strtoupper( chane chane) ucfirst( chane chane) ucwords( chane chane)

strcmpstrcasecmp Cesfonctionspermettentdecomparerdeuxchanesentenantcompteoupasdesmajusculesetminuscules. Syntaxe entier strcmp( chane chane1, chane chane2) entier strcasecmp( chane chane1, chane chane2) chane1etchane2 Chanescomparer. Lesdeuxfonctionsretournentunnombrengatifsi chane1estpluspetitquechane2,unnombregal0siellessontgales, etunnombrepositifsichane1estplusgrandquechane2. strcmpestsensiblelacassealorsquestrcasecmpnelestpas. Exemple

- 2-

ENI Editions - All rigths reserved

<?php $x = Olivier; $y = olivier; echo "strcmp($x,$y) = ",strcmp($x,$y),<br />; echo "strcasecmp($x,$y) = ",strcasecmp($x,$y),<br />; ?> Rsultat strcmp(Olivier,olivier) = -1 strcasecmp(Olivier,olivier) = 0

[s]printf Lesfonctionsprintfetsprintfpermettentdemettreenformeunechane(identiquesauxfonctionsCquivalentes). Syntaxe chane sprintf( chane format[, mixte valeur[, ...]]) chane printf( chane format[, mixte valeur[, ...]]) format Chanedemiseenformeprsentantdiversesdirectivesselonlesspcificationsdonnesciaprs. valeur Valeurintgrerdanslachane. Lafonctionsprintfretournelersultatmisenforme(ou FALSEencasderreur)alorsque printfaffichedirectementlersultat (commelinstructionecho)etretournelalongueurdelachanemiseenformeencasdesuccsouFALSEencasderreur. Lachane formatdoitcontenirunedirectivedeformatagepourchaqueargument valeur cettedirectivedeformatageprcise lemplacement et la mise en forme de la valeur correspondante. La correspondance entre une directive de formatage et une valeurestpositionnelle(premiredirectivepourlapremirevaleur...). Lesdirectivesdeformatagecommencentparlecaractre%suividunecinqinformations,laderniretantlaseuleobligatoire : %[remplissage][alignement][longueur][prcision]type Lesinformationssontlessuivantes : remplissage Prciselecaractreventuelutilispourleremplissage.Lecaractrepardfautestlespace.Toutautrecaractrepeuttre utilisenlementionnantprcdduneapostrophe(seullecaractrezropeuttreindiqudirectement) :xindiquequele caractrederemplissageestle"x". alignement Prciselalignement.Pardfaut,lalignementestdroite.Lecaractremoins("")permetdobtenirunalignementgauche. longueur Indiquelenombreminimumdecaractresdellmentmisenforme. prcision Indiquelenombredechiffresutilisspourlamiseenformedunnombrevirguleflottante(valableuniquementsillment associestunnombre). type Donneletypedelavaleurinsrer :c :entierremplacerparlecaractredontlecodeASCIIacettevaleur d :entier reprsentercommetel f :nombrevirguleflottantereprsentercommetel(tientcomptedelaconfigurationlocaleutilise) F :nombrevirguleflottantereprsentercommetel(netientpascomptedelaconfigurationlocaleutilise) s :quelconque, reprsentercommeunechane. Pouravoiruncaractre"%"danslersultatfinal,ilfautledoublerdansleformat. Quelquesexemples : Directive Valeur Rsultat Explication

ENI Editions - All rigths reserved

- 3-

%d

Nombreentiersansmiseen formeparticulire. 02=complteravecle caractrezro,pourune longueurdedeuxminimum. Nombrevirguleflottante sansmiseenforme particulire. .2=deuxchiffresaprsle sparateurdcimal. Chanesansmiseenforme particulire. .-10=complteravecun pointpouratteindreune longueurminimumdedix caractres(signe= alignementgauche) .2=deuxchiffresaprsle sparateurdcimal.

%02d

01

%f

1/3

0.333333

%.2f

1/3

0.33

%s

Olivier

Olivier

%.-10s

Olivier

Olivier...

%.5.2f

9.9

....9.90

.5=complteravecun pointpouratteindreune longueurminimumde5 caractresavantlepoint dcimal(alignementpar dfaut)

Exemple <?php echo Mise en forme dune date : , sprintf(%02d/%02d/%04d,1,1,2001),<br />; echo Mise en forme de nombres : , sprintf(%01.2f - %01.2f,1/3,12345678.9),<br />; echo Pourcentage : , sprintf(%01.2f %%,12.3),<br />; echo Utilisation des options de remplissage :<br />; echo <tt>; // police non proportionnelle printf("%.-10s%.5.2f<br />",Livres,9.35); // printf direct printf("%.-10s%.5.2f<br />",Disques,99.9); // printf direct echo </tt>; ?> Rsultat Mise en forme dune date : 01/01/2001 Mise en forme de nombres : 0.33 - 12345678.90 Pourcentage : 12.30 % Utilisation des options de remplissage : Livres.....9.35 Disques...99.90

v[s]printf Lesfonctions vprintfet vsprintfsontidentiquesauxfonctions printfet sprintfmaisacceptentendeuximeparamtreun tableaucontenantlesdiffrentesvaleursutiliser(laplacedesparamtresmultiples). Syntaxe chane vsprintf( chane format[, tableau valeurs]) chane vprintf( chane format[, tableau valeurs]) format

- 4-

ENI Editions - All rigths reserved

Chanedemiseenformecomportantdiversesdirectivesselonlesspcificationsdonnesprcdemment. valeurs Tableaudonnantlesvaleursintgrerdanslachane. Exemple <?php $donnes = array(array(Livres,9.35),array(Disques,99.9)); echo <tt>; // police non proportionnelle foreach($donnes as $ligne) { vprintf("%.-10s%.5.2f<BR>",$ligne); // printf direct } echo "</tt>"; ?> Rsultat Livres.....9.35 Disques...99.90

number_format Lafonctionnumber_formatpermetdemettreenformeunnombre. Syntaxe chane number_format( nombre valeur[, entier dcimales[, chane sparateur_dcimal, chane sparateur_milliers]]) valeur Nombremettreenforme. dcimales Nombrededcimales(aucunepartiedcimalepardfaut). sparateur_dcimal Sparateurdcimal(pointpardfaut). sparateur_milliers Sparateurdesmilliers(virgulepardfaut). La fonction peut tre appele avec un, deux ou quatre arguments, pas trois : si le troisime est fourni, le quatrime est obligatoire. Si le nombre a une prcision suprieure celle demande (paramtre dcimales), le nombre est arrondi la prcision demande. Exemple <?php $x = 1234.567; echo "number_format($x) = ",number_format($x),<br />; echo "number_format($x,1,,, ) = ", number_format($x,2,,, ),<br />; ?> Rsultat number_format(1234.567) = 1,235 number_format(1234.567,1,,, ) = 1 234,57 Notezsurcetexemplequelenombreatarrondilaprcisiondemande. ltrimrtrimtrim Cesfonctionspermettentdesupprimerlescaractres"blancs",oudautrescaractres,endbutdechane,enfindechaneou

ENI Editions - All rigths reserved

- 5-

desdeuxcts. Syntaxe chane ltrim( chane chane[, chane caractres]) chane rtrim( chane chane[, chane caractres]) chane trim( chane chane[, chane caractres]) chane Chanetraiter. caractres Chanedonnantlalistedescaractressupprimer.Siceparamtreestabsent,lescaractres"blancs"sontsupprims. Les trois fonctions retournent une chane gale la chane initiale dans laquelle les caractres "blancs" ou les caractres spcifisonttsupprimsaudbut( ltrim,l=left=gauche),lafin(rtrim,r=right=droite)oudesdeuxcts(trim). Lescaractres"blancs"sontlesautdeligne( \n=codeASCII10),leretourchariot(\r=codeASCII13),latabulation(\t=code ASCII9),lecaractreNUL(\0=codeASCII0)etlespace. Exemple <?php $x = "\t\t\t x \n\r"; echo strlen($x) = ,strlen($x),<br />; echo strlen(ltrim($x)) = ,strlen(ltrim($x)),<br />; echo strlen(rtrim($x)) = ,strlen(rtrim($x)),<br />; echo strlen(trim($x)) = ,strlen(trim($x)),<br />; $x = ***+-Olivier-+***; echo "trim($x,*+-) = ",trim($x,*+-), <br />; ?> Rsultat strlen($x) = 8 strlen(ltrim($x)) = 4 strlen(rtrim($x)) = 5 strlen(trim($x)) = 1 trim(***+-Olivier-+***,*+-) = Olivier

substr Lafonctionsubstrpermetdextraireuneportiondunechane. Syntaxe chane substr( chane chane, entier dbut[, entier longueur]) chane Chanetraiter. dbut Positiondupremiercaractredelasouschaneextraire(attention:0=1ercaractre) longueur Nombredecaractresextraire(pardfaut,jusqulafindelachane).
q

Sidbutestpositif,lasouschaneextraitecommenceaucaractredbut(0=1ercaractre). Sidbutestngatif,lasouschaneextraitecommenceaucaractredbutenpartantdelafin(1=derniercaractre). Silongueurnestpasspcifi,lasouschaneextraiteseterminelafindelachane. Silongueurestspcifietpositif,substrextraitlenombredecaractresindiquparlongueur.

- 6-

ENI Editions - All rigths reserved

Si longueur est spcifi et ngatif, la portion extraite se termine la fin de la chane moins le nombre de caractres indiquparlavaleurabsoluedelongueur.

Exemple <?php // 0123456 => pour le contrle $x = Olivier; echo "substr($x,3) = ",substr($x,3),<br />; echo "substr($x,3,2) = ",substr($x,3,2),<br />; echo "substr($x,-4) = ",substr($x,-4),<br />; echo "substr($x,-4,3) = ",substr($x,-4,3),<br />;?> Rsultat substr(Olivier,3) = vier substr(Olivier,3,2) = vi substr(Olivier,-4) = vier substr(Olivier,-4,3) = vie

str_repeat Lafonctionstr_repeatpermetdeconstruireunechaneparrptitiondecaractres. Syntaxe chane str_repeat( chane squence, entier rptitions) squence Squencedecaractresrpter. rptitions Nombrederptitionssouhaites. Exemple <?php echo str_repeat(abc,3); ?> Rsultat abcabcabc

strposstrrposstriposstrripos Cesfonctionspermettentderechercherlapositionduneoccurrence(caractreouchane)lintrieurdunechane. Syntaxe entier entier entier entier strpos( chane _traiter, chane chercher[, entier dbut]) strrpos ( chane _traiter, chane chercher[, entier dbut]) stripos( chane _traiter, chane chercher[, entier dbut]) strripos ( chane _traiter, chane chercher[, entier dbut])

_traiter Chanetraiter. chercher lmentrecherch. dbut Numroducaractre(0=premiercaractre)partirduquellarecherchedoittreralise(pardfaut,ledbutdelachane). La fonction strpos recherche, dans la chane _traiter, la premire occurrence de la chane chercher, en commenant ventuellementaucaractrenumrodbut(0=premiercaractre).

ENI Editions - All rigths reserved

- 7-

La fonction strrpos recherche, dans la chane _traiter, la dernire occurrence de la chane chercher, en commenant ventuellement au caractre numro dbut (0 = premier caractre) Si dbut est ngatif (n), les n derniers caractres de la chane_traitersontignors. Lesdeuxfonctionssontsensibleslacasse(unemajusculenestpasgaleuneminuscule).Lesfonctionsstriposetstrripos sontidentiquesrespectivementauxfonctionsstrposetstrrpos,maisellesnesontpassensibleslacasse. Cesquatrefonctionsretournentlapositiondeloccurrencetrouve(0=premiercaractre)ou FALSEsillmentrecherchnest pastrouv. FALSEtantquivalent0,ilestfaciledeconfondrelecasollmentnapasttrouvetlecasoilattrouvendbut dechane.Latechniqueconsisteutiliserloprateurdecomparaison===(troissignesgal)quipermetdecomparerlavaleuret letypededeuxexpressions(pourplusdedtail,cf.chapitreIntroductionPHPLesbasedulangagePHP). Exemple <?php // 0123456789 ... => pour le contrle $mail = contact@olivier-heurtel.fr; // strrpos $position = strrpos($mail,@); echo "@ est la position $position dans $mail<br />"; // strpos $position = strpos($mail,Olivier); echo "Olivier est la position $position dans $mail<br />"; // occurrence en dbut de chane $position = strpos($mail,contact); if ($position === FALSE) { / / b o n t e s t : = = = echo "contact est introuvable dans $mail<br />"; } else { echo "contact est la position $position dans $mail<br />"; } // occurrence non trouve $position = strpos($mail,information); if ($position === FALSE) { / / b o n t e s t : = = = echo "information est introuvable dans $mail<br />"; } else { echo "information est la position $position dans $mail<br />"; } ?> Rsultat @ est la position 7 dans contact@olivier-heurtel.fr Olivier est la position dans contact@olivier-heurtel.fr contact est la position 0 dans contact@olivier-heurtel.fr information est introuvable dans contact@olivier-heurtel.fr

strstrstristrstrrchr Ces fonctions permettent dextraire la souschane commenant partir dune certaine occurrence dun caractre ou dune chane. Syntaxe chane strstr( chane _traiter, chane rechercher) chane stristr( chane _traiter, chane rechercher) chane strrchr( chane _traiter, caractre rechercher) _traiter Chanetraiter. chercher lmentrecherch. Les fonctions strstr et stristr recherchent, dans la chane _traiter, la premire occurrence de la chanerechercher, et retournentlaportionterminaledelachanecommenantcetteoccurrence(incluse).Lafonctionstrstrestsensiblelacasse (unemajusculeestdiffrenteduneminuscule)alorsquestristrnelestpas. Lafonction strrchrrecherche,danslachane _traiter,ladernire occurrence ducaractrerechercheretretournelaportion

- 8-

ENI Editions - All rigths reserved

terminale de la chane commenant cette occurrence (incluse). Si rechercher est une chane de plusieurs caractres, seul le premierestprisencompte.Lafonctionstrrchrestsensiblelacasse. CestroisfonctionsretournentFALSEsillmentrecherchnestpastrouv. Exemple <?php $mail = Olivier-Heurtel@olivier-heurtel.fr; echo "Reste de $mail commenant par :<br />"; // strrchr $reste = strrchr($mail,-); echo "- la dernire occurrence de -<br />----> $reste <br />"; // strstr $reste = strstr($mail,olivier); echo "- la premire occurrence de olivier (sensible la casse)<br />----> $reste <br />"; // stristr $reste = stristr($mail,olivier); echo "- la premire occurrence de olivier (insensible la casse)<br />----> $reste <br />"; ?> Rsultat Reste de Olivier-Heurtel@olivier-heurtel.fr commenant par : - la dernire occurrence de - ----> -heurtel.fr - la premire occurrence de olivier (sensible la casse) ----> olivier-heurtel.fr - la premire occurrence de olivier (insensible la casse) ----> Olivier-Heurtel@olivier-heurtel.fr

str_replacestr_ireplace Lafonctionstr_replacepermetderemplacerlesoccurrencesdunechaneparuneautrechane.Larechercheestsensiblela casse. Lafonctionstr_ireplacepermetlammeactionmaisnestpassensiblelacasse. Syntaxe mixte str_replace( mixte rechercher, mixte remplacer, mixte _traiter[, entier nombre]) mixte str_ireplace( mixte rechercher, mixte remplacer, mixte _traiter[, entier nombre]) _traiter Chanetraiteroutableaudechanestraiter. rechercher Chaneremplaceroutableaudonnantunelistedechanesrechercher. remplacer Chanederemplacementoutableaudonnantunelistedechanesderemplacement. nombre Variablepermettantdercuprerlenombrederemplacements. Si rechercher et remplacer sont des chanes, la fonction str_replace recherche toutes les occurrences de rechercher et les remplaceparremplacer. Si rechercheret remplacersontdestableaux,lafonction str_replacerecherchetouteslesoccurrencesdechaquelmentde rechercheretlesremplaceparllmentcorrespondantderemplacer. Danslesdeuxcas,letraitementesteffectusurlachane _traiterousurchaquelmentde_traitersicettedernireest untableau. Exemple <?php

ENI Editions - All rigths reserved

- 9-

// premire syntaxe $x = cet t, la plage; $rechercher = t; $remplacer = hiver; echo <b>Premire syntaxe :</b><br />; echo "$rechercher => $remplacer <br />"; echo "$x => ",str_replace($rechercher,$remplacer,$x),<br />; // deuxime syntaxe $x = array(cet t, la plage,le bateau bleu et vert); $rechercher = array(t,plage,bleu,vert); $remplacer = array(hiver,montagne,rouge,jaune); echo "<b>Deuxime syntaxe :</b><br />"; foreach($rechercher as $indice => $avant) { echo "$avant => $remplacer[$indice]<br />"; } // Utilisation de la variable $nombre pour rcuprer // le nombre de remplacements. $y = str_replace($rechercher,$remplacer,$x,$nombre); echo "$x[0] => $y[0]<br />"; echo "$x[1] => $y[1]<br />"; echo "$nombre remplacements<br />"; ?> Rsultat Premire syntaxe : t => hiver cet t, la plage => cet hiver, la plage Deuxime syntaxe : t => hiver plage => montagne bleu => rouge vert => jaune cet t, la plage => cet hiver, la montagne le bateau bleu et vert => le bateau rouge et jaune 4 remplacements

strtr La fonction strtr permet de remplacer les occurrences dun caractre par un autre caractre ou dune chane par une autre chane Syntaxe chane strtr( chane _traiter, chane rechercher, chane remplacer) ou chane strtr( chane _traiter, tableau correspondance) _traiter Chanetraiter. rechercher Chanedonnantlalistedescaractresremplacer. remplacer Chanedonnantlalistedescaractresderemplacement. correspondance Tableauassociatifdonnantunecorrespondancechaneremplacer/chanederemplacement La fonction strtr accepte deux syntaxes : la premire permet de remplacer des caractres par dautres et la deuxime de remplacerdeschanespardautres. Aveclapremiresyntaxe,lacorrespondanceentrelescaractresremplaceretlescaractresderemplacementestdonnepar deuxchanes(lecaractrendelapremiretantremplacerparlecaractrendeladeuxime). Avecladeuximesyntaxe,lacorrespondanceentreleschanesremplaceretleschanesderemplacementestdonneparun tableauassociatif(lacltantlachanerechercheretlavaleurlachanederemplacement). Exemple

- 10 -

ENI Editions - All rigths reserved

<?php // premire syntaxe $x = cet t, la plage; $avant = ; $aprs = eea; echo <b>Premire syntaxe :</b><br />; echo "$avant => $aprs<br />"; echo "$x => ",strtr($x,$avant,$aprs),<br />; // deuxime syntaxe $x = le bateau bleu et vert; $correspondance = array(bleu=>rouge,vert=>jaune); echo <b>Deuxime syntaxe :</b><br />; foreach($correspondance as $avant => $aprs) { echo "$avant => $aprs<br />"; } echo "$x => ",strtr($x,$correspondance),<br />; ?> Rsultat Premire syntaxe : => eea cet t, la plage => cet ete, a la plage Deuxime syntaxe : bleu => rouge vert => jaune le bateau bleu et vert => le bateau rouge et jaune

Lesexpressionsrguliresereg[i]ereg[i]_replace PHPproposeplusieursfonctionsquipermettentdeffectuerdesrecherchesoudesremplacementsdansunechanelaidedun modleappel"expressionrgulire"dcrivantllmentrecherch. Syntaxe entier ereg( chane rechercher, chane _traiter[, tableau rsultat]) entier eregi( chane rechercher, chane _traiter[, tableau rsultat]) chane ereg_replace( chane rechercher, chane remplacer, chane _traiter) chane eregi_replace( chane rechercher, chane remplacer, chane _traiter) _traiter Chanetraiter. rechercher Chanedonnantlemodle(lexpressionrgulire)dellmentrecherch. remplacer Chanederemplacement. rsultat Sousformedetableau,listedesportionsdelachane_traiterquicorrespondentaumodlerecherch. Lesfonctions eregeteregirecherchent,danslachane _traiter,silexisteunechanequicorrespondaumodlespcifipar rechercher(voirciaprspourlesrgles).Lafonctioneregestsensiblelacasse(unemajusculeestdiffrenteduneminuscule) alorsque ereginelestpas.Cesfonctionsretournentlalongueurdeloccurrencetrouvesilemodleesttrouvet FALSEdans lecascontraire. Encomplment,silemodleledemande(voircidessouspourlesrgles)etsiuntroisimeparamtreestfourni,lesdiffrentes portions de la chane _traiter qui correspondent au modle seront stockes sous forme de tableau dans le troisime paramtre. Lesfonctionsereg_replaceeteregi_replaceeffectuentlarecherchesurlemmeprincipeetremplacentlesdiffrentesportions delachane_traiterquicorrespondentaumodle,parlachane remplacer.Lafonction ereg_replaceestsensiblelacasse alorsqueeregi_replacenelestpas.Siaucuneoccurrencenesttrouve,lachane_traiterestretourneinchange. Plusieurscaractresspciauxpeuventtreutilissdanslemodlepourdcrirellmentrecherch : Caractrespcial Signification Si^estprsentcommepremiercaractredumodle,cela

ENI Editions - All rigths reserved

- 11 -

indiquequelachanedoitcommencerparcequisuit : ^abc :doitcommencerparabc. Si$estprsentcommederniercaractredumodle,cela indiquequelachanedoitterminerparcequiprcde : xyz$ :doitterminerparxyz.

^abcxyz$ :doitcommencerparabcxyzetseterminerpar abcxyz(breftregalabcxyz !). Unmodlenecomportantni^ni$indiquequelemodle estrecherchnimporteolintrieurdelachane : abc :contientabc. Indiquequelecaractrequiprcde,oulasquencequi prcde(voirciaprs),peuttreprsentezro,uneou plusieursfois : ab*caccepteac,abc,abbc... Indiquequelecaractrequiprcde,oulasquencequi prcde(voirciaprs),doittreprsenteuneouplusieurs fois : ab+caccepteabc,abbc...,maisrefuseac. Indiquequelecaractrequiprcde,oulasquencequi prcde(voirciaprs),peuttreprsentezroouune fois : ab?caccepteacetabcmaisrefuseabbc,abbbc... Indiquequelecaractrequiprcde,oulasquencequi prcde(voirciaprs),doittreprsenteexactementx fois({x})ouauminimumxfois({x,})ouentrexetyfois ({x,y}) : ab{2}cnacceptequeabbc. ab{2,4}caccepteabbc,abbbc,etabbbbcmaisrefuseabc (manqueunb)ouabbbbbc(unbdetrop). ab{2,}caccepteabbc,abbbc,abbbbc,...maisrefuseabc (manqueunb). Permetdemarquerunesquencerecherche,typiquement aveclessymbolesrelatifsaunombredoccurrences :

{x} {x,} {x,y}

(...) a(bc)*dacceptead,abcd,abcbcd...maisrefuseabdouacd (lasquencebcnestpastrouve). Recherchedexoudey(gnralementutilisavecles parenthsespourvitertouteconfusion) : x|y a(b|c)*dacceptead,abd,acd,abcd,abbcd,accbd...(en clairunnombrequelconquedeboudecsitusdans nimportequelordreentreunaetund). Permetdespcifierunesriedecaractresacceptssoit souslaformec1c2...cnpourunelisteexhaustiveprcise, soitsouslaformec1-c2pouruneplagedecaractres,soit enmlangeantlesdeux : [abcd]accepteuncaractreparmiabcd(quivalent (a|b|c|d)). [a-z]accepteuncaractrecomprisentreaetz. [123a-zA-z]accepteuncaractrecomprisentreaetzou comprisentreAetZougal1ou2ou3. [...] [a-zA-z0-9]accepteuncaractrecomprisentreaetzou entreAetZouentre0et9.

- 12 -

ENI Editions - All rigths reserved

Uneexclusionpeuttrespcifieenmettantun^en premiercaractrelintrieurdescrochets : [^0-9]refusetoutcaractrecomprisentre0-9. [^abc]refuselescaractresa,betc. Comptetenudesasignificationparticulire,lesigne-,sil estrecherchentantquetel,doitfigurerenpremierouen dernierentrelescrochets. Indiqueuncaractrequelconque : a.bacceptetoutesquencecomportantunasuivi dexactementuncaractrequelconquesuividunb : axb, ayb,maispasabniaxyb. a.{0,2}bacceptetoutesquencecomportantunasuivide zrodeuxcaractresquelconquessuividunb : ab,axb,, axyb,maispasaxyzb. Permetdchapperlescaractresspciaux( ^.[$()|*+?{\) lorsqueceuxcisontrecherchsentantquetels,sauf lorsquilssontmentionnsentrecrochets : \ a\*{2,4}bpermetderechercherlessquences commenantparunasuivide24toilessuiviesdunb (notezle\*). a[$*+]{2,4}bpermetderechercherlessquences commenantparunasuivide24caractresprisparmi$, *et+suivisdunb(pasbesoinde\). Lesparenthsesontunedeuximesignification lorsquellesenglobenttoutlemodleoudespartiesdu modle.Ellespermettentde"capturer"danslachaneles squencesquirpondentaumodleoulaportionde modleentreparenthses.Danslecasdelutilisationdes fonctionseregeteregi,lesportionscapturessont stockessousformedetableaudansletroisime paramtre(silestspcifi) :lapremireligne(indice0)du tableaucontientunecopiedelachanecorrespondantla totalitdumodleetlesportionscapturessontstockes dansleslignessuivantes.Danslecasdelutilisationdes fonctionsereg_replaceeteregi_replace,lesportions capturespeuventtrereprisesdanslachanede remplacementgrcelanotation\\n,avecnentier(0 dsignantlaportiondelachanecorrespondantla totalitdumodleetlesnumros1nlesportions captures). Classedecaractres(voircidessous).

(...)

[::] Lesclassesdecaractressontlessuivantes : [:alnum:] Caractresalphanumriques [:alpha:] Caractresalphabtiques [:blank:] Caractresblancs [:cntrl:] Caractresdecontrle [:digit:] Chiffres

ENI Editions - All rigths reserved

- 13 -

[:graph:] Caractresgraphiques [:lower:] Caractresalphabtiquesminuscules [:print:] Caractresgraphiquesoublancs [:punct:] Caractresdeponctuation [:space:] Espace,tabulation,nouvelleligne,retourchariot [:upper:] Caractresalphabtiquesmajuscules [:xdigit:] Caractresdeschiffreshexadcimaux Lesexpressionsrguliressontdesoutilstrspuissantspoureffectuerdesrecherchesdansunechaneouvaliderlaconformit dunesaisiecertainesrgles. Les diffrents sites Web prsents dans le chapitre Introduction regorgent dexemples de code utilisant les expressions rgulires. En complment des quelques exemples prsents ciaprs, le chapitre Grer les liens et les formulaires avec PHP illustrera lutilisationdesexpressionsrgulirespourvaliderlasaisiedunutilisateur. Exemple1 <?php // Vrifier quune chane commence par une lettre et // est suivie dau moins 3 lettres ou chiffres ou caractres // spciaux _(#*$). $modle = ^[a-z][a-z0-9_#*$]{3,}; // Tableau contenant les chanes tester. $chanes[] = A0_#b*1$2; // OK; $chanes[] = 0_#b*1$2; // ne commence pas par une lettre; $chanes[] = A0_; // longueur insuffisante; $chanes[] = A0_#; // caractre invalide; // Utilisation de eregi (insensible la casse). foreach ($chanes as $chane) { if (eregi($modle,$chane) === FALSE) { / / t e s t : = = = echo "$chane => pas OK<br />"; } else { echo "$chane => OK<br />"; } }?> Rsultat A0_#b*1$2 => OK 0_#b*1$2 => pas OK A0_ => pas OK A0_# => pas OK Quelquesexplicationssurlexpressionrgulireutilise(^[a-z][a-z0-9_#*$]{3,}) :
q

eregiestutiliseafindenepasfairedediffrenceentremajusculesetminuscules. ^=commencepar... [a-z]=unelettreentreaetz(ouAetZcareregiestutilise)...

- 14 -

ENI Editions - All rigths reserved

[a-z0-9_#*$]{3,} = suivi dau moins 3 ({3,}) caractres parmi ceux indiqus : a z (et donc A Z), 0 9 et les caractres_#*$

Exemple <?php // Vrifier quune chane une structure conforme celle // dune date au format [J]J/[M]M/AAAA et rcuprer les // 3 composantes jour, mois et anne. $modle = ^([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})$; // Tableau contenant les chanes tester. $dates[] = 21/09/2001; // OK $dates[] = 1/2/2001; // OK $dates[] = 21/09/01; // anne incomplte // Utilisation de ereg. foreach ($dates as $date) { $ok = ereg($modle,$date,$rsultat); if ($ok) { echo "$date valide.<br />"; echo "- jour = $rsultat[1]<br />"; echo "- mois = $rsultat[2]<br />"; echo "- anne = $rsultat[3]<br />"; } else { echo "$date invalide.<br />"; } } ?> Rsultat 21/09/2001 valide. - jour = 21 - mois = 09 - anne = 2001 1/2/2001 valide. - jour = 1 - mois = 2 - anne = 2001 21/09/01 invalide. Quelquesexplicationssurlexpressionrgulireutilise(^([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})$) :
q

^=commencepar... [0-9]{1,2}=unoudeuxchiffres... /=suividucaractre"/"... [0-9]{1,2}=suivideunoudeuxchiffres... /=suividucaractre / ... [0-9]{4}=suivide4chiffres... $=suivide...riendutout !Lachanedoitseterminerimmdiatement.

etestpermetdevrifierquunechanecensecontenirunedateestbienforme.Ilconvientensuitedevrifier,avecla C fonctioncheckdateparexemple,quelestroiscomposantescorrespondentbienunedatevalide.

Exemple3 <?php // Utiliser ereg_replace pour rorganiser une chane. // En loccurrence, il sagit de transformer une date // au format JJ/MM/AAAA en date au format AAAA-MM-JJ

ENI Editions - All rigths reserved

- 15 -

$avant = 26/08/1966; $aprs = ereg_replace( ^([0-9]{2})/([0-9]{2})/([0-9]{4})$, \\3-\\2-\\1, $avant); echo "$avant => $aprs"; ?> Rsultat 26/08/1966 => 1966-08-26 Danslachanederemplacement,lessquences\\ndsignentlestroisportionscapturesparlesparenthses :
q

\\1=premier([0-9]{2})=26 \\2=deuxime([0-9]{2})=08 \\3=([0-9]{4})=1966

Lersultatdelarecherche,quiestgallachanecompltedanscecas,estdoncensuiteremplacparlachane\\3-\\2-\\1 soit1966-08-26.

- 16 -

ENI Editions - All rigths reserved

Manipulerlesdates
PHP ne gre pas les dates avec un type de donne spcifique. Nanmoins, des dates peuvent tre manipules, soit sous la forme dune chane de caractres, soit sous la forme dun timestamp Unix (correspondant au nombre de secondescoulesdepuisle1erjanvier197001:00:00). Plusieursfonctionspermettentdemanipulerlesdatessousluneoulautredecesformes : Nom checkdate Rle Vrifiequetroisentiersreprsentantlejour,lemoiset lannecorrespondentunedatevalide. Convertitenchaneunedatedonnesouslaforme duntimestampUnix. Convertitenchaneunedatedonnesouslaforme duntimestampUnix,enutilisantdescaractristiques locales. Stockedansuntableaulesdiffrentescomposantes dunedatedonnesouslaformeduntimestampUnix. DonneletimestampUnixactuel. CreuntimestampUnixpartirdesdiffrentes composantesdunedate. DonneletimestampUnixactuelaccompagndu nombredemicrosecondescoulesdepuisladernire seconde. Donnelescomposantesdunedatefourniesousla formeduntimestampUnix.

date

strftime

getdate

time

mktime

microtime

idate

epuislaversion5.1.0,ilexistedesfonctionsquimanipulentdesdatessouslaformedunobjet(voirnotamment D lefonctiondate_createdansladocumentation).

checkdate Lafonctioncheckdatevrifiequetroisentiersreprsentantlejour,lemoisetlannecorrespondentunedatevalide. Syntaxe boolen checkdate( entier mois, entier jour, entier anne) mois Numrodumois(112). jour Numrodujour(131). anne Anne(132767). La fonction checkdate retourne TRUE si la date construite avec les trois composantes est valide et FALSE dans le cas contraire.Cettefonctiontientcomptedesannesbissextiles. Exemple

ENI Editions - All rigths reserved

- 1-

<?php $jour = 26; $mois = 8 ; $anne = 1966; echo "$jour/$mois/$anne => ", var_dump(checkdate($mois,$jour,$anne)),<br />; $jour = 29; $mois = 2 ; $anne = 2000; echo "$jour/$mois/$anne => ", var_dump(checkdate($mois,$jour,$anne)),<br />; $jour = 29; $mois = 2 ; $anne = 2001; echo "$jour/$mois/$anne => ", var_dump(checkdate($mois,$jour,$anne)),<br />; ?> Rsultat 26/8/1966 => bool(true) 29/2/2000 => bool(true) 29/2/2001 => bool(false)

date LafonctiondateconvertitenchaneunedatedonnesouslaformeduntimestampUnix. Syntaxe chane date( chane format[, entier timestamp]) format Formatdeconversion. timestamp Timestampconvertir(pardfautletimestampactuel). Leformatpeuttrespcifilaidedescaractressuivants(nonexhaustif) : Caractre Signification Numrodujourdumois,surdeuxchiffres(0131) Numrodujourdumois,surunoudeuxchiffres(1 31) Numrodumois,surdeuxchiffres(0112) Numrodumois,surunoudeuxchiffres(112) Annesurquatrechiffres(2001parexemple) Annesurdeuxchiffres(01parexemple) Heure,auformat24h,surdeuxchiffres(0023) Minutessurdeuxchiffres(0059) Secondessurdeuxchiffres(0059) Numrodujourdelanne(1365) Numrodujourdelasemaine(0=dimanche6= samedi) NumrodujourdelasemaineselonlanormeISO8601 (1=lundi7=dimanche).Ajoutdanslaversion

d j m n Y y H i s z w

N
- 2-

ENI Editions - All rigths reserved

5.1.0.

W D r

NumrodelasemainedanslanneselonlanormeISO 9601 Troispremireslettresdunomdujourdelasemaine, enanglais FormatdedatedelaRFC822(parexemple,"Thu,20 Sep200115:47:00+0200")

Encasdebesoin,cesdiffrentscaractrespeuventtrechappsavecunantislash(\). Depuislaversion5.1.1,desformatsstandardspeuventtrespcifislaidedeconstantes,parexemple : DATE_ISO8601 ISO8601(exemple:20070713T17:53:10+0200) DATE_RFC822 RFC822(exemple:Fri,13Jul0717:53:10+0200) DATE_RSS RSS(exemple:Fri,13Jul200717:53:10+0200) Exemple <?php // sans deuxime paramtre = utilisation du timestamp courant echo Date au format JJ/MM/AAAA : , date(d/m/Y),<br />; echo Heure : , date(H:i:s),<br />; echo Unix a ft sa milliardime seconde le , date(d/m/Y H:i:s,1000000000),<br />; ?> Rsultat Date au format JJ/MM/AAAA : 28/01/2008 Heure : 20:58:12 Unix a ft sa milliardime seconde le 09/09/2001 03:46:40

strftime La fonction strftime convertit en chane une date donne sous la forme dun timestamp Unix, en utilisant des caractristiqueslocales. Syntaxe chane strftime( chane format[, entier timestamp]) format Formatdeconversion. timestamp Timestampconvertir(pardfautletimestampactuel). ladiffrencedelafonctiondate,strftimeutiliselescaractristiqueslinguistiqueslocales(cellesduserveur). Leformatpeuttrespcifilaidedescaractressuivants(nonexhaustif) : Caractre Signification Jourdumois,surdeuxchiffres(0131)
ENI Editions - All rigths reserved - 3-

%d

%m %y %Y %H %M %S %j %w %u %a %A
%bou%h

Numrodumois,surdeuxchiffres(0112) Annesurdeuxchiffres(01parexemple) Annesurquatrechiffres(2001parexemple) Heure,auformat24h Minutessurdeuxchiffres(0059) Secondessurdeuxchiffres(0059) Numrodujourdelannesurtroischiffres(001365) Numrodujourdelasemaine(0=dimanche6= samedi) Numrodujourdelasemaine(1=lundi7= dimanche) Nomabrgdujourdelasemaine Nomcompletdujourdelasemaine Nomabrgdumois Nomcompletdumois Numrodesemainedanslanne(enconsidrantle premierdimanchedelannecommelepremierjourde lapremiresemaine) Numrodesemainedanslanne(enconsidrantle premierlundidelannecommelepremierjourdela premiresemaine) NumrodelasemainedanslanneselonlanormeISO 9601 Fuseauhoraire,ounomouabrviation Formatpardfautpourladateetlheure Formatpardfautpourladateseule Formatpardfautpourlheureseule Identique%H:%M Identique%H:%M:%S Tabulation Retourlaligne uncaractre%littral

%B %U

%W

%V %Z %c %x %X %R %T %t %n %%

T ouslessymbolesnesontpasforcmentsupportssurtouteslesplatesformes.

- 4-

ENI Editions - All rigths reserved

Lescaractristiqueslinguistiqueslocalespeuventtreluesetmodifiesparlintermdiairedelafonctionsetlocale. Syntaxe chane setlocal( mixte catgorie, chane langue)

Fonctionnalitconcerneparlescaractristiques linguistiqueslocalesdfinieslaidedunedes constantessuivantes : LC_COLLATE :comparaisondechaneaveclafonction strcoll LC_CTYPE :classificationetconversions(fonction stroupperparexemple) LC_NUMERIC :sparateurdcimal LC_MONETARY :symbolemontaire(fonction localeconv) LC_TIME :formatsdedate(fonctionstrftime) LC_ALL :touteslesprcdentes. Codedelalanguedevantgouvernerlafonctionnalit associe.Extraitdesvaleurspossibles : du :Hollande fr :France ge :Allemagne

catgorie

langue

it :Italie ru :Russie sp :Espagne sw :Sude en :RoyaumeUni us :EtatsUnis.

La fonction setlocal retourne la nouvelle valeur ou FALSE en cas derreur. Si le deuxime paramtre est gal "0", setlocal retourne simplement la valeur courante. Sil est gal NULL ou une chane vide, setlocale prend la valeur correspondantlenvironnementdusystmedexploitation. Exemple <?php echo Date/Heure : , strftime(%d/%m/%Y - %H:%M:%S ),<br />; setlocale(LC_ALL,fr); echo Format long (franais) : , strftime(%A %d %B %Y),<br />; setlocale(LC_ALL,en); echo Format long (anglais) : , strftime(%A %d %B %Y),<br />; ?> Rsultat Date/Heure: 28/01/2008 - 21:21:48 Format long (franais) : lundi 28 janvier 2008 Format long (anglais) : Monday 28 January 2008

getdate La fonction getdate stocke, dans un tableau, les diffrentes composantes dune date donne sous la forme dun

ENI Editions - All rigths reserved

- 5-

timestampUnix. Syntaxe tableau getdate( entier timestamp) timestamp Timestamputiliser(pardfautletimestampactuel). Lafonctiongetdateretourneuntableauassociatifcomportantlesclssuivantes : Cl Valeur Secondes(059) Minutes(059) Heures(024) Numrodujourdumois Numrodujourdelasemaine(de0=dimanche6= samedi) Numrodumois(112) Anne Numrodujourdanslanne(1365) Nomdujourdelasemaine Nomdumois Letimestamp

seconds minutes hours mday wday mon year yday weekday month 0
Exemple <?php $date = getdate(); // maintenant foreach($date as $cl => $valeur) { echo "$cl => $valeur<br />"; } ?> Rsultat seconds => 54 minutes => 28 hours => 21 mday => 28 wday => 1 mon => 1 year => 2008 yday => 27 weekday => Monday month => January 0 => 1201552134

time LafonctiontimedonneletimestampUnixactuel.

- 6-

ENI Editions - All rigths reserved

Syntaxe entier time() Exemple <?php $ts = time(); echo "timestamp Unix actuel = $ts"; ?> Rsultat timestamp Unix actuel = 1201552164

mktime LafonctionmktimecreuntimestampUnixpartirdesdiffrentescomposantesdunedate. Syntaxe entier mktime([ entier heure[, entier minutes[, entier secondes[, entier mois[, entier jour[, entier anne]]]]]]) heure Heure(023) minutes Minutes(059) secondes Secondes(059) mois Mois(112) jour Jour(131) anne Annesur2ou4chiffres.Lanne,sur4chiffres,doittrecompriseentre1902(1970avantlaversion5.1.0)et2038. Nousdconseillonsdespcifierlannesur2chiffres(diffrencedecomportemententrelesversions). Lesparamtresomisprennentleurvaleuractuelle. La fonction mktime a la particularit intressante de corriger les valeurs incorrectes en effectuant un calcul de date intelligent.Exemples :
q

le35/12/2001seracorrigen31/12/2001+4jours=04/01/2002 le30/14/2001seracorrigen30/12/2001+2mois=30/02/2002quiluimmeestcorrigen28/02/2002+2 jours=02/03/2002

Cefonctionnementesttrspratiquepourraliserdescalculssurlesdates. Exemple <?php $ts = mktime(); echo mktime() = maintenant = , date(d/m/Y - H:i:s,$ts),<br />;
ENI Editions - All rigths reserved - 7-

$ts = mktime(0,0,0,8,26,1966); echo mktime(0,0,0,8,26,1966) = , date(d/m/Y - H:i:s,$ts),<br />; $ts = mktime(0,0,0,8,26+20000,1966); echo 20000 jours aprs le 26/08/1966 = , date("d/m/Y",$ts),"<BR>"; ?> Rsultat mktime() = maintenant = 28/01/2008 - 21:39:51 mktime(0,0,0,8,26,1966) = 26/08/1966 - 00:00:00 20000 jours aprs le 26/08/1966 = 29/05/2021

microtime LafonctionmicrotimeretourneletimestampUnixactuelaveclafractiondesecondeenmicrosecondes. Syntaxe mixte microtime([ boolen type_rel]) type_rel Boolenindiquantsilafonctiondoitretournerunnombrerel. Sans paramtre (ou si le paramtre est valu FALSE), la fonction retourne une chane donnant les microsecondes suiviesdunespaceetdutimestampUnixactuel.SileparamtreestvaluTRUE,lafonctionretourneunnombrerel. Exemple <?php // Affichage de microtime sous la forme dune chane. echo microtime().<br />; // Affichage de microtime sous la forme dun rel. echo microtime(TRUE).<br />; // Pour ne conserver que les micosecondes, le plus // simple est de transformer la chane en rel. echo (float) microtime().<br />; ?> Rsultat 0.45474800 1201552264 1201552264.45 0.454881

idate Lafonctionidateretournelesdiffrentescomposantes(anne,mois,etc.)duntimestampUnix. Syntaxe entier idate( caractre composante [, entier timestamp]) composante Caractreindiquantlacomposantesouhaite(voirciaprs). timestamp Timestamputiliser(pardfautletimestampactuel). Lafonctionretourneunentiercorrespondantlacomposantedemande. Lacomposantepeuttrespcifielaidedundescaractressuivants(listenonexhaustive) : Caractre
- 8-

Signification
ENI Editions - All rigths reserved

Y z y m D H i s t W w
Exemple

Annesur4chiffres Jourdelanne Annesur2chiffres Numrodumois Numrodujourdumois Heuresur24 Minutes Secondes Nombredejoursdanslemois Numrodesemainedelanne Jourdelasemaine(0pourdimanche)

<?php // Affichage de la date/heure courante pour contrle echo strftime(%d/%m/%Y - %H:%M:%S),<br />; // Extraction de diffrentes composantes $composantes = str_split(YmdHistwW); foreach($composantes as $composante) { echo "$composante = ",idate($composante),<BR>; } ?> Rsultat 28/01/2008 - 21:33:12 Y = 2008 m = 1 d = 28 H = 21 i = 33 s = 12 t = 31 w = 1 W = 5

ENI Editions - All rigths reserved

- 9-

Gnrerunnombrealatoire
Lafonctionrandpermetdegnrerdesnombresalatoires. Syntaxe entier rand([ entier min[, entier max]]) minetmax Bornesdesnombresalatoiresgnrer.Valeurpardfautdemin=0.Valeurpardfautdemax=unevaleurdonne parlafonctiongetrandmax. Lafonctionrandretourneunnombrealatoireentiercomprisentrelaborneminimumetlabornemaximumincluses. <?php // Gnration de nombres alatoires. echo rand().<br />; echo rand().<br />; echo rand(1,100).<br />; echo rand(1,100).<br />; ?> Rsultat 214120785 257944955 68 65

ENI Editions - All rigths reserved

- 1-

Crerunidentifiantunique
Danscertainessituations,ilpeuttrencessairedegnrerdesidentifiantsuniques. PHPproposelafonctionuniqidpourgnrerdesidentifiantsuniques. Syntaxe chane uniqid()([ chane prfixe [, boolen plus_unique]]) prfixe Prfixeajouterlidentifiant. Mettreunechanevideounerienmettresivousnesouhaitezpasdeprfixe. plus_unique SiceparamtreestpositionnTRUE,desdonnessupplmentairessontajouteslafindelavaleurretournepour obtenirunidentifiantpluslongetplusdifficilementidentifiable. Lafonctionuniqidretourneunechanedetreizecaractres,ouvingttroissileparamtreplus_uniqueest TRUE(sans compterleprfixe),calculepartirdelheurecouranteenmicrosecondes. Exemple <?php echo uniqid(),<br />; echo uniqid(),<br />; echo uniqid(abc),<br />; echo uniqid(,TRUE) ,<br />; ?> Rsultat 47864520950dd 47864520958b1 abc47864520960b6 47864520960bf5.27165445 Cet exemple montre que lidentifiant gnr est bien unique, mme si la diffrence entre deux appels successifs est faible.Ducoup,lidentifiantgnrpeuttrejuginsuffisammentalatoireetunpeutropdterministe. Unetechniqueclassiqueconsistealorshacherlidentifiantgnr.Lafonctionmd5permetdelefairetrsfacilement,en utilisantunemthodeMD5. Syntaxe chane md5( chane valeur) valeur Chanehacher. Lafonctionmd5retournelachanehache. Exemple <?php echo md5(olivier),<br />; echo md5(uniqid()),<br />; echo md5(uniqid()),<br />; ?> Rsultat d3ca5dde60f88db606021eeba2499c02 694fb65aee42c22b371bcd9f9b3cfc3b

ENI Editions - All rigths reserved

- 1-

b69e0eba91d77fe9b6b6a4f80e3d4acd La combinaison des fonctions uniqid et md5 donne un identifiant qui comporte 32 caractres. Cet identifiant est maintenantplusalatoireetmoinsfaciledterminer. Pourlesparanoaquesdelascurit,ilestpossibledallerencoreplusloinenutilisantenplusunprfixealatoire. Exemple <?php echo md5(uniqid(rand())),<br />; echo md5(uniqid(rand())),<br />; ?> Rsultat 0615709d67387b9c91df4d8f9eb5a92a b6c5ec69c0d4d0ed76c5f48e95857ac6

- 2-

ENI Editions - All rigths reserved

Grerles"guillemetsmagiques"("magicquotes")
1.Principe
PHP propose une fonctionnalit, appele "magic quotes" ("guillemets magiques") dont lobjectif principal est de rsoudre un problmelilenregistrementdesdonnesdansunebasededonneseneffectuantunencodagesurlesdonnesvenantde "lextrieur" :
q

donnessaisiesdansunformulaire,transmisesdansuneURLouenvoyesparuncookie donnesluesdansunebasededonnesouunfichier.

Cette"fonctionnalit"peutrapidementdeveniruncassettesielleestmalpriseencompte. Lorsque la fonctionnalit "magic quotes" est active, les caractres apostrophe (), guillemet ("), antislash (\) et nul (\0) sont automatiquementprotgsparunantislash(\). Exemple Donneinitiale cest lt Donnercupredanslescript

c\est l\t

Deuxdirectivespermettentdactiver(valeuron)oudedsactiver(valeuroff)les"guillemetsmagiques". Directive Donnesconcernes Donnessaisiesdansunformulaire,transmisesdansune URLouenvoyesparuncookie. DonnesluesdansunebasededonnesMySQLoudans unfichiertexte.

magic_quotes_gpc magic_quotes_runtime

LesuffixegpcdeladirectivecorrespondGet,PostetCookie.

Ce principe dencodage "magic quotes" est intressant, notamment devant lapostrophe, si les donnes sont destines tre enregistresdansunebaseSQL.Eneffet,enSQL,ledlimiteurdechanedecaractresestlapostrophe(cf.chapitreIntroduction MySQL Apprendre les bases du langage SQL) si une requte envoie la chane cest lt labasededonnes,cette dernire va interprter c comme une chane et ne saura pas quoi faire du reste ( est lt) : un message derreur sera retournparlabase. Pourrglerceproblme,ilfautindiquerlabasequelesapostropheslintrieurdelachanenesontpasdesdlimiteursdela chane, gnralement en les faisant prcder dun caractre "magique" ("dchappement") : il sagit de lantislash (\) pour MySQL.Labonnevaleurenvoyerestdoncc\est l\tpourMySQL. i la directive magic_quotes_sybase est on, le caractre dchappement est remplac par lapostrophe ce caractre S dchappementestutilispardautresbasesdedonnescommeOracleouMicrosoftSQLServer. La fonctionnalit "magic quotes" est intressante si la donne saisie est destine tre enregistre dans une base MySQL (lencodage est automatique), mais pose des problmes si la donne saisie est destine tre simplement affiche dans une pageHTML(lencodageestinutile). Danslapratique,cettefonctionnalit"magicquotes"posedeuxproblmes :
q

Si la donne est la fois destine tre affiche dans la page et enregistre dans une base de donnes, il y a un problme :aveclaffichagesi"magicquotes"estactifetaveclenregistrementdanslabasededonnessi"magicquotes" estinactif. LedveloppeurnematrisepasforcmentlaconfigurationdePHPdanslenvironnementdexploitation :ilpeutdonccrire ducodequifonctionnedanssonenvironnementdedveloppement(avecunecertaineconfigurationde"magicquotes"), maisquirisquedeneplusfonctionnerdanslenvironnementdexploitationolaconfigurationestpeuttrediffrente.

LquipededveloppementdePHPrecommandededsactiverlafonctionnalit"magicquotes":ladirectivemagic_quotes_gpcest offdanslefichierdeconfigurationrecommand(php.ini-recommended).Dansunefutureversion(sansdoutelaversion6),la fonctionnalit"magicquotes"seradfinitivementdsactive. Pour tre conforme cette recommandation et prparer le futur, nous vous conseillons de dsactiver la fonctionnalit "magic

ENI Editions - All rigths reserved

- 1-

quotes",danslamesuredupossible. Nanmoins, dans ce livre, nous verrons comment grer proprement cette fonctionnalit et crire un code indpendant de la configuration.

2.Fonctionsrelativesaux"guillemetsmagiques"
PHPproposeplusieursfonctionsquipermettentdegrercorrectementlafonctionnalit"magicquotes" : get_magic_quotes_gpc Permetdeconnatrelavaleurdeladirectivemagic_quotes_gpc. get_magic_quotes_runtime Permetdeconnatrelavaleurdeladirectivemagic_quotes_runtime. set_magic_quotes_runtime Modifielavaleurdeladirectivemagic_quotes_runtimeencoursdescript. addslashes Ajouteuneprotection"magicquotes"dansunechanedecaractres. stripslashes Supprimerlaprotection"magicquotes"dunechanedecaractres. Ladirectivemagic_quotes_gpcnepeutpastremodifieencoursdescript.

get_magic_quotes_gpc Lafonctionget_magic_quotes_gpcpermetdeconnatrelavaleurdeladirectivemagic_quotes_gpc. Syntaxe entier get_magic_quotes_gpc() Lafonctionget_magic_quotes_gpcretourne0siladirectivemagic_quotes_gpcestoff,ou1sinon. get_magic_quotes_runtimeetset_magic_quotes_runtime La fonction get_magic_quotes_runtime permet de connatre la valeur de la directive magic_quotes_runtime et la fonction set_magic_quotes_runtimedelamodifierencoursdescript. Syntaxe entier get_magic_quotes_runtime() boolen set_magic_quotes_runtime( entier valeur) valeur Nouvellevaleurdeladirectivemagic_quotes_runtime:0=dsactiv(off),1=activ(on). Lafonctionget_magic_quotes_runtimeretourne0siloptionestdsactiveet1sielleestactive. Lafonctionset_magic_quotes_runtimeretourneTRUEsilechangementsesteffectuetFALSEsinon. addslashesetstripslashes Lesfonctionsaddslashesetstripslashespermettentdajouteroudesupprimerlaprotection"magicquotes"dansunechanede caractres. Syntaxe chane addslashes( chane texte) chane stripslashes( chane texte) texte

- 2-

ENI Editions - All rigths reserved

Chaneconcerne. Lafonctionaddslashesprendenparamtreunechanedecaractresetretournecettechaneenajoutantunantislash(\)devant lescaractresapostrophe( ),guillemet("),antislash(\)etnul(\0). Lafonction stripslashesestlinversedelafonction addslashes :elleprendenparamtreunechanedecaractresetretourne cettechaneensupprimantlantislash(\)devantlescaractresapostrophe( ),guillemet("),antislash(\)etnul(\0). Danslesdeuxcas,lecaractredchappementutilisestlapostrophe( )siladirectivemagic_quotes_sybaseeston. Exemple <?php $texte = "cest lt"; $texte = addslashes($texte); echo $texte,<br />; $texte = stripslashes($texte); echo $texte,<br />; ?> Rsultat(ensupposantquemagic_quotes_sybase = off) c\est l\t cest lt Cesfonctionsvonttreutilesdanslesdeuxcassuivants :
q

Sivousavezunedonnedansunevariable,quinapasdjtencode,etquecettedonnedoittreenregistredans labase,ilestconseilldappeleraddslashespoureffectuerlencodageadapt. Si vous avez une donne dans une variable, qui a t encode (manuellement ou automatiquement), et que vous souhaitezlafficherdansunepageHTML,ilfautappelerstripslashespourenleverlencodage.

l ne faut pas appeler addslashes ou stripslashes au hasard sur des variables dj encodes en ce qui concerne I addslashesounonencodesencequiconcernestripslashes.

Exemple <?php // Utilisation de la fonction addslashes sur une donne dj // encode. echo addslashes("c\est l\t"),<br />; // Utilisation de la fonction stripslashes sur une donne non // encode : // - Cas 1 : pas grave echo stripslashes("cest lt"),<br />; // - Cas 2 : mauvais echo stripslashes(d:\photos\identit.jpg),<br />; ?> Rsultat(ensupposantquemagic_quotes_sybase = off) c\\\est l\\\t cest lt d:photosidentit.jpg Il est donc important de ne pas appeler addslahes systmatiquement avant un enregistrement dans la base, ou stripslashes systmatiquementavantunaffichagedansunepageHTML.Ilfautsavoirdovientladonneetsielleestounondjencode par la fonctionnalit "magic quotes". Cette information peut tre obtenue grce la fonction get_magic_quotes_gpc prsente prcdemment.

3.Gestionintelligenteetportable
IlexistedeuxsituationssimplessivousmatrisezlaconfigurationdePHP :
q

Voustescertainquemagic_quotes_gpc = off :danscecas,vouspouvezaffichersanssoucilesdonnesenprovenance dun formulaire, duneURLouduncookie(pasbesoindappeler stripslashes)etvousdevezappeler addslashesavant toutenregistrementdanslabase.

ENI Editions - All rigths reserved

- 3-

Voustes certainque magic_quotes_gpc = on et que magic_quotes_sybaseestadaptlabasequevousutilisez( off pour MySQL par exemple) : dans ce cas, vous devez appeler stripslashes avant tout affichage des donnes en provenance dun formulaire, dune URL ou dun cookie, mais vous pouvez les enregistrer directement dans la base. Par contre un problme peut se poser pour des donnes ayant une autre source. Si vous initialisez une variable du type $valeur = "cest lt", cette variable va contenir une information qui na pas subi lencodage automatique de la fonctionnalit "magic quotes" un moment ou un autre, il faudra encoder la donne avec addslashes si elle doit tre enregistredanslabase...

SivousnematrisezpaslaconfigurationdePHPetquevoussouhaitezavoiruncodeportable,ilfautprocderautrement. Voicilasolutionquenousprconisons :
q

DcidezunefoispourtoutequetoutevariablePHPcontientunedonnequinestpasprotge(approchecohrenteavec lesvolutionsvenirdePHP). Faitesletraitementncessaire,lorsdelaffectationdunevariableparunedonnequivientdelextrieurpoursassurer quellenecontientpasdencodage"magicquotes". Nefaitesrienvisvisdelencodage"magicquote"lorsdelaffichagedunevariabledansunepageHTML(lesvariables necontiennentpasdecaractresdchappementsuperflus). Faiteslencodagencessairelorsdelenregistrementdunevariabledansunebase.

Leschmasuivantprsentelessourcesdedonnesextrieuresquilvafalloirgreraumomentdelalimentationdesvariables :

Donneenprovenancedunformulaire,duneURLouduncookie Commenouslavonsdit,toutcequivientdunformulaire(mthodeGETouPOST),duneURL(mthode GET)ouduncookie,etque nous appellerons dsormais donnes GPC, est sous linfluence de la directive magic_quotes_gpc : au moment de lalimentation dunevariablepartirdunedecessources,pourrespecternotreprincipedefonctionnement,ilfautenleverlencodage"magic quotes"si"magicquotes"estactifetnerienfairesinon. Un tel traitement est possible grce aux fonctions get_magic_quotes_gpc et stripslashes.Ilsuffitdcrire une fonction qui sera systmatiquement appele lors de la rcupration dunedonneGPCpourenleverlencodage "magic quotes" si ce dernier est actif. Exemple <?php function supprimer_encodage_MQ($valeur) { // Si magic quotes est actif, retourner // la valeur aprs suppression de lencodage // (=> appel stripslashes), sinon, retourner // la valeur. return (get_magic_quotes_gpc())?stripslashes($valeur):$valeur; } ?>

ppelezcettefonctionuniquementsurdesdonnesGPCpournepasrisquerdenleverdescaractresdchappementqui A nesontpaslisunencodage"magicquotes".

- 4-

ENI Editions - All rigths reserved

Dans le chapitre Grer les liens et les formulaires avec PHP, nous reviendrons sur ce sujet et nous prsenterons une mthode alternativepermettantdesupprimerenunseulappellaprotectionventuelledetouteslesdonnesGPC. DonneenprovenancedeMySQLoudunfichiertexte PourlesdonnesenprovenancedeMySQLoudunfichiertexte,letraitementestbeaucoupplussimplepuisquilestpossiblede modifierencoursdescriptlavaleurdeladirectivemagic_quotes_runtime. Un simple appel set_magic_quotes_runtime(0) permet de garantir quil ny aura pas de protection "magic quotes" dans les donnesluesparlasuitedansunebaseMySQL(cf.chapitreAccderunebasededonnesMySQL)oudansunfichiertexte(cf. danscechapitreAccderunebasededonnesMySQLManipulerlesfichierssurleserveur). EnregistrementdansunebasededonnesMySQL Pour lenregistrement dans la base de donnes, nous verrons dans le chapitre 11 comment traiter de manire gnrique les donnesavantdelesenvoyerlabasepourviterlesproblmes.

ENI Editions - All rigths reserved

- 5-

Manipulerlesfichierssurleserveur
1.Fonctionsutiles
PHPproposeungrandnombredefonctionspermettantdemanipulerlesfichierssurleserveur. Lesfonctionslesplusutilessontlessuivantes : Nom Rle Ouvrirunfichier Fermerunfichier Lirelecontenudunfichier(dansunechane) Lirelecontenudunfichier(dansuntableau) criredansunfichier Ouvrir,lireetfermerunfichier Ouvrir,crireetfermerunfichier Affichelecontenudunfichierdirectementsurlasortie Copierunfichier Supprimerunfichier Renommerunfichier Testerlexistencedunfichier Lirelatailledunfichier

fopen fclose fread file fwrite file_get_contents file_put_contents readfile copy unlink rename file_exists filesize

Certaines de ces fonctions vont prendre comme paramtre un nom de fichier ou de rpertoire. Sur la plateforme Windows, pour spcifier un chemin daccs dans une chane de caractres dlimite par des guillemets, vous devez chapperlantislash(parunantislash= \\)ouvouspouvezutiliserunenotationdetype"Unix",avecdesslashs( /). Parexemple,lecheminc:\temp\info.txtpeuttrecrit"c:\\temp\\info.txt"ou" c:/temp/info.txt".Siaucunchemin nest indiqu, cest le rpertoire courant qui est utilis. Des noms relatifs peuvent tre spcifis en utilisant le caractre.(point)pourdsignerlerpertoirecourantet..(deuxpoints)pourdsignerlerpertoiresuprieur. La constante prdfinie DIRECTORY_SEPARATOR donne le caractre de sparation utilis dans les noms de rpertoire pour la plateformesurlaquellePHPestinstalle.Laconstanteprdfinie PHP_EOLdonnelasquencedecaractres utiliseparlaplateformepourreprsenterunenouvelleligne. Par ailleurs, plusieurs fonctions possdent un paramtre (appel utiliser_inclusion dans les syntaxes de cet ouvrage) qui permet de rechercher le fichier dans les rpertoires spcifis par la directive de configuration include_path. fopen Lafonctionfopenpermetdouvrirunfichier. Syntaxe ressource fopen( chane nom_fichier, chane mode [, boolen utiliser_inclusion]) nom_fichier

ENI Editions - All rigths reserved

- 1-

Chemindaccsaufichierouvrir. mode Modedouverturedufichier : r=lectureseule +=lecture/criture w=critureseule(videlefichiersilexiste,lecresilnexistepas) w+=lecture/criture(videlefichiersilexiste,lecresilnexistepas) a=critureseule(enajoutcrelefichiersilnexistepas) a+=lecture/criture(enajoutcrelefichiersilnexistepas) x=critureseuleaveccrationpralabledufichier(gnreuneerreursilefichierexistedj) x+=lecture/critureaveccrationpralabledufichier(gnreuneerreursilefichierexistedj) SousWindows,ajouterunbpourmanipulerlesfichiersbinaires(cetteoption,siprsente,estignoresousUnix) utiliseruntlaplacedubspcifieunmodetexte(lessquences\nsontautomatiquementremplacesparun\r\n). utiliser_inclusion MettreTRUEpourrechercherlefichierdanslesrpertoiresspcifisparladirectivedeconfigurationinclude_path. LafonctionfopenretourneunpointeurdefichierencasdesuccsetFALSEencasderreur. ourdesraisonsdeportabilit,ilestrecommanddetoujoursutiliserloptionblorsquevousouvrezdesfichiers P avecfopen.

fclose Lafonctionfclosepermetdefermerunfichier. Syntaxe boolen fclose( ressource fichier) fichier Pointeurdefichierpralablementouvert. LafonctionfcloseretourneTRUEencasdesuccsetFALSEencasdchec. fread Lafonctionfreadpermetdelirelecontenudunfichier(dansunechane). Syntaxe chane fread( ressource fichier, entier longueur) fichier Pointeurdefichierpralablementouvert. longueur Nombredoctetsliredanslefichier. LafonctionfreadretournelesdonnesluesouFALSEencasderreur. file Lafonctionfilepermetdelirelecontenudunfichier(dansuntableau). Syntaxe
- 2 ENI Editions - All rigths reserved

tableau file( chane nom_fichier [, entier indicateur]) nom_fichier Chemindaccsaufichierlire. indicateur Uneouplusieursdesconstantessuivantes : FILE_USE_INCLUDE_PATH :rechercherlefichierdanslesrpertoiresspcifisparladirectivedeconfiguration include_path. FILE_IGNORE_NEW_LINES :nepasajouterlasquencedenouvellelignelafindechaquelignedutableau. FILE_SKIP_EMPTY_LINES :ignorerleslignesvides. fwrite Lafonctionfwritepermetdcriredansunfichier. Syntaxe entier fwrite( ressource fichier, chane donnes[, entier longueur]) fichier Pointeurdefichierpralablementouvert. donnes Donnescriredanslefichier. longueur Siprcis,indiquelenombredoctetscrire(toutelachanedonnespardfaut). LafonctionfwriteretournelenombredoctetscritsouFALSEencasderreur. file_get_contents Lafonctionfile_get_contentspermetdelirelecontenudunfichier(dansunechane). Syntaxe chane file_get_contents( chane nom_fichier [, boolen utiliser_inclusion]) nom_fichier Chemindaccsaufichierlire. utiliser_inclusion MettreTRUEpourrechercherlefichierdanslesrpertoiresspcifisparladirectivedeconfigurationinclude_path. Lafonctionfile_get_contentsouvrelefichierdontlenomestpassenparamtreetleretournedansunechane.La fonctionretourneFALSEencasderreur. Utilisercettefonctionservleplusperformantquouvrirlefichier(fopen),lelire(fread)etlerefermer(fclose). file_put_contents Lafonction file_put_contentspermetdcrirelecontenudunechanedansunfichier.Cettefonctionestapparueen version5. Syntaxe entier file_put_contents( chane nom_fichier, chane donnes [, entier mode])

ENI Editions - All rigths reserved

- 3-

nom_fichier Chemindaccsaufichierlire. donnes Donnescriredanslefichier. mode ConstanteFILE_USE_INCLUDE_PATHpourcriredanslepremierrpertoirespcifidansladirectivedeconfiguration include_path.ConstanteFILE_APPENDpourajouterlesdonneslafindufichier,silexistedj.Spcifierlasomme desdeuxconstantespourcombinerlesdeuxoptions. La fonction file_put_contents ouvre le fichier dont le nom est pass en paramtre, crit le contenu de la chane passeenparamtrepuisfermelefichier. Silefichiernexistepas,ilestcr.Silefichierexistedj,soncontenuestremplac,saufsilaconstanteFILE_APPEND estspcifieentroisimeparamtre,auquelcaslesdonnessontajouteslafindufichier. Lafonctionretournelenombredoctetscritsdanslefichier,ouFALSEencasderreur. readfile Lafonctionreadfilelitunfichieretlenvoiedirectementverslasortie. Syntaxe entier readfile( chane nom_fichier [, boolen utiliser_inclusion]) nom_fichier Chemindaccsaufichierlire. utiliser_inclusion MettreTRUEpourrechercherlefichierdanslesrpertoiresspcifisparladirectivedeconfigurationinclude_path. LafonctionreadfileretournelenombredoctetslusouFALSEencasderreur. copy Lafonctioncopypermetdecopierunfichier. Syntaxe boolen copy( chane source, chane destination) source Emplacementdufichiersource. destination Emplacementdufichierdestination. LafonctioncopyeffectuelacopieetretourneTRUEencasdesuccsouFALSEencasdchec. unlink Lafonctionunlinkpermetdesupprimerunfichier. Syntaxe boolen unlink( chane nom_fichier) nom_fichier Emplacementdufichiersupprimer.

- 4-

ENI Editions - All rigths reserved

LafonctionunlinksupprimelefichieretretourneTRUEencasdesuccsouFALSEencasdchec. rename Lafonctionrenamepermetderenommerunfichier. Syntaxe boolen rename( chane ancien_nom, chane nouveau_nom) ancien_nom Emplacementdufichierrenommer. nouveau_nom Nouveaunomdufichier. LafonctionrenamerenommelefichieretretourneTRUEencasdesuccsouFALSEencasdchec. file_exists Lafonctionfile_existspermetdetesterlexistencedunfichier. Syntaxe boolen file_exists( chane nom_fichier) nom_fichier Emplacementdufichiertester. Lafonctionfile_existsretourneTRUEsilefichierexisteouFALSEdanslecascontraire. filesize Lafonctionfilesizepermetdelirelatailledunfichier. Syntaxe entier filesize( chane nom_fichier) nom_fichier Emplacementdufichier. LafonctionfilesizeretournelatailledufichierouFALSEencasderreur.

2.Exempledutilisation
Cesdiffrentesfonctionspeuventtreutilisespourlireoucriredansdesfichierssurleserveur. Exemple <?php // Ouvrir un fichier en criture. $f = f o p e n (info.txt,wb); // Ecrire dans le fichier. f w r i t e ($f, Olivier HEURTEL); // Fermer le fichier. f c l o s e ($f); // Ouvrir un fichier en lecture $f = f o p e n (info.txt,rb); // Lire dans le fichier. $texte = f r e a d ($f, f i l e s i z e (info.txt)); // Fermer le fichier. f c l o s e ($f);

ENI Editions - All rigths reserved

- 5-

// Afficher les informations lues. echo $texte,<br />; // Plus simple : utiliser file_get_contents. $texte = f i l e _ g e t _ c o n t e n t s (info.txt); // Afficher les informations lues. echo $texte; ?> Rsultat Olivier HEURTEL Olivier HEURTEL

3.Les"guillemetsmagiques"
Comme nous lavons vu dans la section Grer les "guillemets magiques" ("magic quotes"), si la directive de configuration magic_quotes_runtime est on,lesdonnesluesdanslesfichierstextesubirontuneprotection"magic quotes".Cependant,ilesttrsfaciledemodifierlavaleurdeladirectivemagic_quotes_runtimeencoursdescriptgrce lafonctionset_magic_quotes_runtime. Exemple <?php // Ecrire une information dans un fichier. file_put_contents(info.txt,"Cest lt"); // Afficher la valeur de la directive magic_quotes_runtime. $mqr = get_magic_quotes_runtime(); echo "<b>magic_quotes_runtime = $mqr</b><br />"; // Lire et afficher le contenu du fichier. $texte = file_get_contents(info.txt); echo $texte,<br />; // Modifier la valeur de la directive magic_quotes_runtime. $mqr = ($mqr == 1)?0:1; set_magic_quotes_runtime($mqr); echo "<b>magic_quotes_runtime = $mqr</b><br />"; // Lire et afficher le contenu du fichier. $texte = file_get_contents(info.txt); echo $texte,<br />; ?> Rsultat magic_quotes_runtime = 0 Cest lt magic_quotes_runtime = 1 C\est l\t Un appel systmatique set_magic_quotes_runtime(0) permet de garantir quil ny aura pas de protection "magic quotes"danslesdonnesluesparlasuitedansunfichiertexte,etdoncseconformerlastratgieproposedansla sectionGrerles"guillemetsmagiques"("magicquotes").

- 6-

ENI Editions - All rigths reserved

Envoyeruncourrierlectronique
1.Vuedensemble
Unsiteinteractifasouventbesoindenvoyerdesmessageslectroniquesauxutilisateurs,parexemplepourconfirmer unachat,uneinscriptionouenvoyerunelettredinformation. Lafonction mail,proposeparPHP,permetderpondresimplementcegenredebesoin.Cettefonctionestdtaille danscechapitre,dabord,pourenvoyerdesmessagestextes(sanspicejointe),puispourenvoyerdesmessagesau formatMIME(MultipurposeInternetMailExtensions). Encomplment,PHPproposeunebibliothquepuissante,maispluscomplexedutilisation,pourgrerdesmessages selonleprotocoleIMAP(InternetMessageAccessProtocol).Cettebibliothqueneserapasabordedanscetouvrage carellenestpasindispensablepourrpondreaubesoinvoquprcdemment.

2.Envoyerunmessagetextesanspicejointe
Lafonctionmailpermetdenvoyerunmessagelectronique. Syntaxe boolen mail( chane destinataire, chane objet, chane message[, chane entte]) destinataire Adresseemaildudestinataire.Desdestinatairesmultiplespeuventtreindiqusenlessparantpardesvirgules. objet Objetdumessage. message Textedumessage. entte Enttessupplmentaires. Lafonction mailenvoielemessagecaractrisparlesdiffrentsparamtresunserveurdemessageriedfiniparles directivesdeconfigurationsuivantes : AdresseduserveurSMTPauquel envoyerlemessage.Exemple : smtp.gmail.com Adresseemaildelmetteur. Exemple :

Win32

SMTP

sendmail_from

webmaster@monsite.com Cettedirectivedoittreprsente, mmevide. Chemindaccsverslexcutable duserveurdemessagerie(peut comporterdesparamtres). Exemple : sendmail -t -i

Unix

sendmail_path

Lafonctionmailretourne TRUEsilemessageaputreenvoyauserveur(cequinegarantitpasquecedernierapu lenvoyeravecsuccs)et FALSEdanslecascontraire.Ilnyaaucunmoyendesavoirsilemessageabientenvoy


ENI Editions - All rigths reserved - 1-

avecsuccs cettevrificationdoittreraliseendehorsdePHP. Lequatrimeparamtrepermetdespcifierdesinformationssupplmentairesquiserontenvoyesdanslenttedu message desinformationsmultiplesdoiventtresparesparlasquence\r\n. a squence utiliser comme sparateur dentte est souvent source de problme (et de dbat dans les L forumsdediscussion).Trssouvent,lasquence \nseulefonctionne parfois,lasquence \r\nnefonctionne pas. Exempledemessagesimple <?php // Destinataire. $destinataire = contact@olivier-heurtel.fr; // Objet. $objet = "Inscription monSite.com"; // Message. $message = Monsieur Heurtel, Nous vous remercions pour votre inscription sur note site monSite.com. Nous esprons que ce site rpondra vos attentes. Le webmaster.; // Envoi. $ok = mail($destinataire,$objet,$message); ?> Cet exemple montre que le message peut tre directement crit sur plusieurs lignes il est aussi possible de la construireparconcatnation. Exempledemessagepluscomplexe <?php // Deux destinataires spars par une virgule. $destinataires = olivier@diane.com,xavier@zeus.fr; // Objet. $objet = Inscription au marathon; // Message. $message .= "Olivier, Xavier,\n"; $message .= "Nous vous confirmons votre inscription au\n"; $message .= "marathon le dimanche 6 avril.\n"; $message .= "Le dpart sera donn 9h00.\n\n"; $message .= "Les organisateurs.\n"; // En-ttes supplmentaires. $enttes .= "From: \"Inscription\" <contact@marathon.fr>\n"; $enttes .= "Reply-To: \"Inscription\" <contact@marathon.fr>\n"; $enttes .= "X-Priority: 1\n"; // Envoi. $ok = mail($destinataires,$objet,$message,$enttes); ?> Lesenttessupplmentairessontspcifissouslaformemot_cl: valeur. Lesentteslespluscourantssontlessuivants : From: Originedumessagesouslaforme["nom en clair"] <adresse e-mail>.Exemples :"Olivier HEURTEL" <contact@olivier-heurtel.fr>,<contact@olivier-heurtel.fr> To: Destinataire(s)(mmeformatquelentteFrom). Reply-To: Adressederponse(mmeformatquelentteFrom). X-Priority:

- 2-

ENI Editions - All rigths reserved

Prioritdumessage,de14 :1=prioritlaplushaute2=priorithaute3=prioritnormale4=prioritbasse ansleparamtredestinataire,ilnestpaspossibledespcifieruneadressesouslaforme ["nom en clair"] D <adresse e-mail>. Par contre, il est possible dindiquer des adresses sous cette forme en les envoyant dans lentteTo:,endoublonduparamtredestinataire.

3.EnvoyerunmessageauformatMIME
a.Prambule
Dans cette partie, nous allons tudier comment envoyer des messages au format MIME ou plus gnralement au formatMultipartMIME. LeformatMIMEpermetdenvoyerunmessageayantunautreformatquedutexte :image,formatHTML,etc. Le format Multipart MIME permet denvoyer un message compos de plusieurs parties ayant chacune un format diffrent(dutexteplusuneimage,parexemple),unedes"parties"pouvanttreunepicejointe. Lobjectif de cette partie, sans rentrer dans le dtail du format MIME (les amateurs peuvent se pencher sur les nombreusesRFCquitraitentdusujet),estdemontrerconcrtementcommentprocdersurdeuxcastypiques,lenvoi dunmessageauformatHTMLetlenvoidunmessageavecunepicejointe.

b.MessageauformatHTML
LecasdelenvoidunmessageauformatHTMLpermetdillustrerlutilisationduformatMIMEsimple. Exemple(sourcedunmessageMIMEauformatHTML) From: "Olivier" <olivier@diane.com> To: "Xavier" <xavier@zeus.fr> Subject: Bonjour ! Date: Mon, 10 Sep 2001 09:24:13 -0100 Message-ID: <3b9c6a403d9f000b@hermes.diane.com> MIME-Version: 1.0 Content-Type: text/html; charset=iso-8859-1 Content-Transfer-Encoding: 8bit <html> <head><title>Bonjour !</title></head> <body> <font color="green">Bonjour !</font> </body> </html> Un message MIME simple comporte dabord les enttes standards dun message, puis trois lignes denttes supplmentaires(engras)indiquantquelemessageestauformatMIME,etenfinlecorpsdumessageproprement dit. Lestroislignesdenttessupplmentairessontlessuivantes : MIME-Version IndiquequelemessageestauformatMIMEetprciselaversion. Content-Type IndiqueletypeMIMEducontenu. Content-Transfer-Encoding Indiqueletypedencodage. QuelquestypesMIMEusuels :

ENI Editions - All rigths reserved

- 3-

text/plain Textesimple.Lejeudecaractresutilispeuttrespcifiparloptioncharset(parexempleiso-8859-1). text/html FormatHTML.Lejeudecaractresutilispeuttrespcifiparloptioncharset(parexempleiso-8859-1). image/jpeg ImageauformatJPEG. application/octet-stream Donnesbinaires. Quelquestypesdencodageusuels : 7bit Encodagedutextesur7bits. 8bit Encodagedutextesur8bits(utiliserpourconserverlescaractresaccentus). base64 Encodagepourlesdonnesbinaires(voirlafonctionbase64_encode). Classiquement, pour les types MIME text/*, un type dencodage 7bit ou 8bit est utilis et le corps du message contientletexteenclair.Ilestaussipossibledutiliserunencodagebase64etdemettredanslecorpsdumessage desdonnesencodesenconsquence(voirlafonctionbase64_encodeplusloin). PourlestypesMIMEcorrespondantdesdonnesbinaires(image,son,documentPDF...),unencodagebase64est utilis et le corps du message contient les donnes encodes en consquence (voir la fonction base64_encodeplus loin). EnvoyerunmessageauformatHTMLaveclafonctionmailestrelativementsimple.Ilfaut :
q

placerleslignesadquatesdanslentte mettrelesdonnesHTMLdanslecorpsdumessage.

Exemple <?php // Destinataires. $destinataires = xavier@zeus.fr; // Objet. $objet = Bonjour !; // En-ttes supplmentaires. $enttes .= "From: \"Olivier\" <olivier@diane.com>\n"; $enttes .= " M I M E - V e r s i o n : 1 . 0 \n"; $enttes .= " C o n t e n t - T y p e : t e x t / h t m l ; c h a r s e t = i s o - 8 8 5 9 - 1 \n"; $enttes .= " C o n t e n t - T r a n s f e r - E n c o d i n g : 8 b i t \n"; // Message (HTML). $message .= "<html>\n"; $message .= "<head><title>Bonjour !</title></head>\n"; $message .= "<body>\n"; $message .= "<font color=\"green\">Bonjour !</font>\n"; $message .= "</body>\n"; $message .= "</html>\n"; // Envoi. $ok = mail($destinataires,$objet,$message,$enttes); ?>

- 4-

ENI Editions - All rigths reserved

Si vous utilisez un encodage base64, vous pouvez appeler la fonction base64_encodepoureffectuerlencodage des donnes. Syntaxe chane base64_encode( chane donnes) donnes Donnesencoder. Cettefonctionretournelesdonnesencodes. Encomplment,pourseconformerauxspcifications,ilfautdcouperlesdonnesencodesenbase64enmorceaux de76octetssparsparunesquence\r\n. Cetteoprationpeuttreralisetrssimplementgrcelafonctionchunk_split. Syntaxe chane chunk_split ( chane donnes [, entier longueur [, chane sparateur]]) donnes Donnesdcouper. longueur Longueurdesmorceaux(76pardfaut). sparateur Sparateurdesmorceaux(\r\npardfaut). Lafonctionchunk_splitretournelachanedcoupe. Exempledutilisationpourlenvoidunmessage <?php // Destinataires. $destinataires = xavier@zeus.fr; // Objet. $objet = Bonjour !; // En-ttes supplmentaires. $enttes = ; $enttes .= "From: \"Olivier\" <olivier@diane.com>\r\n"; $enttes .= "MIME-Version: 1.0\r\n"; $enttes .= "Content-Type: text/html; charset=iso-8859-1\r\n"; $enttes .= "Content-Transfer-Encoding: b a s e 6 4 \r\n"; // Message (HTML). $message .= "<html>\n"; $message .= "<head><title>Bonjour !</title></head>\n"; $message .= "<body>\n"; $message .= "<font color=\"green\">Bonjour !</font>\n"; $message .= "</body>\n"; $message .= "</html>\n"; // Encodage et dcoupage. $message = chunk_split(base64_encode($message)); // Envoi. $ok = mail($destinataires,$objet,$message,$enttes); ?>

c.Messageavecpicejointe
LecasdelenvoidunmessageavecpicejointepermetdillustrerlutilisationduformatMultipartMIME. Exemple(sourcedunmessageavecpicejointeauformatMultipartMIME) From: "Olivier" <olivier@diane.com>

ENI Editions - All rigths reserved

- 5-

To: "Xavier" <xavier@zeus.fr> Subject: Bonjour ! Date: Mon, 10 Sep 2001 09:24:13 -0100 Message-ID: <3b9c6a403d9f000b@hermes.diane.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=O=L=I=V=I=E=R=" --=O=L=I=V=I=E=R= Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Voir la pice jointe. --=O=L=I=V=I=E=R= Content-Type: application/octet-stream; name="PJ.DOC" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="PJ.DOC" 0M8R4KGxGuEAAA ... AAAAAAAAAAAAAAAAAAAAAAAAAA== --=O=L=I=V=I=E=R=-Un message Multipart MIME comporte dabord les enttes standards dun message, puis deux lignes denttes supplmentaires(engras)indiquantquelemessageestauformatMultipartMIME,etenfinlesdiffrentespartiesdu message chaquepartiepossdesonpropreentteindiquantsonformat(typeMIMEetencodage). Dans lentte du message, nous retrouvons les deux lignes MIME-Version et Content-Type. Pour un message MultipartMIME,Content-Typeestgalmultipart/mixedsuividuneoptionboundaryquidonnelachaneutilisepour marquerledbutdesdiffrentespartiesdumessage( =O=L=I=V=I=E=R=surnotreexemple). Chaquepartiedumessagecommencepardeuxsignes"moins"suivisdelachanedonneparboundary(cequidonne --=O=L=I=V=I=E=R=surnotreexemple). Dans lentte de chaque partie, nous retrouvons les deux lignes Content-Type et Content-Transfer-Encoding qui prcisentletypedeMIMEetlencodagedelapartie. Lesdonnesdelapartieviennentensuite. La fin du message est marque par deux signes "moins", suivis de la chane donne par boundary suivie de deux signes"moins"(cequidonne--=O=L=I=V=I=E=R=--surnotreexemple). La chane donne par boundary doit tre choisie avec soin pour viter dtre confondue avec des donnes, ce qui conduiraitunemauvaiseinterprtationdumessage. Danslenttedechaquepartie,ilestpossibledindiquerunelignedenttesupplmentaire(Content-Disposition) quiva suggrerauclientdemessagerieunemaniredeprsenterlesdonnescorrespondantelutilisateur :les deuxvaleurspossiblessontinline(lesdonnessontprsentesdirectementdanslemessage)ou attachment(les donnes sont prsentes en pice jointe) dans ce cas, un nom de fichier peut tre suggr grce loption filename. Exemple Content-Disposition: attachment; filename="PJ.DOC" PourenvoyerunmessageMultipartMIMEaveclafonction mail,ilfautconstruirelesdiffrentespartiesdumessage dans le paramtre message,enrespectantlastructureindiqueprcdemment leparamtre enttedelafonction mailcontientlesenttesstandards,ycomprislentteindiquantquilsagitdunmessageauformatMultipartMIME. esdiffrentespartiesdumessagedoiventtresparesparunelignevide( \r\n).Auseindechaquepartie, L ilenestdemmeentrelenttedelapartieetlesdonnes.VoirlaremarquedansletitreEnvoyeruncourrier lectroniqueEnvoyerunmessagetextesanspicejointeausujetdelasquence\r\n.

Exempledenvoidunmessageavecpicejointe <?php // Destinataires. $destinataires = xavier@zeus.fr; // Objet. $objet = Bonjour !;

- 6-

ENI Editions - All rigths reserved

// En-ttes supplmentaires. $enttes = ; // -> origine du message $enttes .= "From: \"Olivier\" <olivier@diane.com>\r\n"; // -> message au format Multipart MIME $enttes .= "MIME-Version: 1.0\r\n"; $enttes .= "Content-Type: multipart/mixed; "; $enttes .= "boundary=\"=O=L=I=V=I=E=R=\"\r\n"; // Message. $message = ""; // -> premire partie du message (texte proprement dit) // -> en-tte de la partie $message .= "--=O=L=I=V=I=E=R=\r\n"; $message .= "Content-Type: text/plain; "; $message .= "charset=iso-8859-1\r\n "; $message .= "Content-Transfer-Encoding: 8bit\r\n"; $message .= "\r\n"; // ligne vide // -> donnes de la partie $message .= "Voir la pice jointe.\r\n"; $message .= "\r\n"; // ligne vide // -> deuxime partie du message (pice-jointe) // -> en-tte de la partie $message .= "--=O=L=I=V=I=E=R=\r\n"; $message .= "Content-Type: application/octet-stream; "; $message .= "name=\"PJ.DOC\"\r\n"; $message .= "Content-Transfer-Encoding: base64\r\n"; $message .= "Content-Disposition: attachment; "; $message .= "filename=\"pj.doc\"\r\n"; $message .= "\r\n"; // ligne vide // -> lecture du fichier correspond la pice jointe // (sassurer quil ny a pas dencodage magic quotes) set_magic_quotes_runtime(0); $donnes = file_get_contents(pj.doc); // -> encodage et dcoupage des donnes $donnes = chunk_split(base64_encode($donnes)); // -> donnes de la partie (intgration dans le message) $message .= "$donnes\r\n"; $message .= "\r\n"; // ligne vide // Dlimiteur de fin du message. $message .= "--=O=L=I=V=I=E=R=--\r\n"; // Envoi du message. $ok = mail($destinataires,$objet,$message,$enttes); ?> Plusieurs pices jointes peuvent tre envoyes en rptant, autant de fois que ncessaire, les lignes de code correspondantes. nthorie,latotalitdumessagepourraittreconstruitedanslentte(paramtremessagegalunechane E vide). Dans la pratique, et en rgle gnrale, cela fonctionne sur une plateforme Linux, mais pas sur une plateformeWindows.

ENI Editions - All rigths reserved

- 7-

ManipulerlesenttesHTTP
LafonctionheaderpermetdenvoyerdesenttesHTTPaveclapageHTML. Syntaxesimplifie header( chane en-tte [, boolen remplacer]) en-tte ChaneenvoyercommeentteHTTPaveclapageHTML. remplacer Indiquesilafonctiondoitremplacerunentteprcdemmentmis(valeurTRUE,pardfaut)oubienajouterunnouvel entte(valeurFALSE). LesdiffrentsenttesHTTPsontdcritsdanslaRFC2616. Parexemple,lafonctionheaderpeuttreutilisepourenvoyerunenttequiinterditlamiseencachedelapageparle client ou par un proxy. Ce besoin est assez frquent dans les scripts PHP qui gnrent du HTML dynamique dont le contenuchangeenfonctiondelutilisateur. Exemple // HTTP 1.0 header("Pragma: no-cache"); // HTTP 1.1 header("Cache-Control: no-cache, must-revalidate"); Danslasuitedecetouvrage,nousauronsloccasiondutiliserlafonctionheaderdansplusieurssituations :
q

redirectionHTTP(cf.chapitreGrerlesliensetlesformulairesavecPHPAllersuruneautrepage) identificationHTTP(cf.chapitreGrerlessessionsAuthentification) tlchargement("download")dundocument(cf.chapitreGrerlesliensetlesformulairesavecPHPchanger unfichierentreleclientetleserveur) affichageduneimagedansunepagelaidedunscriptPHP(cf.chapitreAccderunebasededonnesMySQL UtilisationdelextensionMySQLi).

a fonction header doit tre appele avant toute instruction (PHP ou HTML) qui a pour effet de commencer L construire la page HTML (cest en quelque sorte trop tard pour lentte). Un simple espace, dans le script, ou dansunscriptinclus(requireouinclude)provoqueuneerreur.

Exempledappellafonctionheaderquignreuneerreur <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Saisie</title></head> <body> <?php header(location: accueil.htm); exit; ?> </body> </html> Rsultat W a r n i n g : Cannot modify header information - headers already

ENI Editions - All rigths reserved

- 1-

sent by (output started at /app/scripts/info.php:6) in /app/scripts/saisie.php on line 7

ilafonctionnalitdemiseenbufferdelapageestactiveavecladirectivedeconfigurationoutput_buffering,le S rsultatduscriptnestpasenvoyaufuretmesuremaismisdansunbufferpuisenvoydunseulcouplafin (ou par morceaux si le buffer est limit en taille). Dans ce cas, il est possible dutiliser la fonction header sans provoquerderreuralorsquelescriptacommencconstruirelapage. PHPproposedautresfonctionsrelativesauxenttes :
q

headers_list :listedesenttesdelarponse(version5). header_sent :permetdetestersilesenttesontdjtenvoys. get_headers :listedesenttesrenvoysparunserveur,pouruneURLdonne(version5).

- 2-

ENI Editions - All rigths reserved

Fonctions
1.Introduction
linstardesdiffrentslangagesdedveloppement,PHPoffrelapossibilitdedfinirsespropresfonctions(appeles fonctions utilisateur )avectouslesavantagesassocis(modularit,capitalisation).Unefonctionestunensemble dinstructions identifies par un nom, dont lexcution retourne une valeur et dont lappel peut tre utilis comme oprande dans une expression. Une procdure est un ensemble dinstructions identifies par un nom qui peut tre appelcommeuneinstruction.

2.Dclarationetappel
Lemotclfunctionpermetdintroduireladfinitiondunefonction. Syntaxe function nom_fonction([paramtres]) { instructions; } nom_fonction Nomdelafonction(doitrespecterlesrglesdenommageprsentesdanslechapitreIntroductionPHPStructure debasedunepagePHP). paramtre Paramtresventuelsdelafonctionexprimssousformedunelistedevariables(cf.Paramtres) :$paramtre1, $paramtre2,... instructions Ensembledesinstructionsquicomposentlafonction. LenomdelafonctionnedoitpastreunmotrservPHP(nomdefonction,dinstruction)nitregalaunomdune autrefonctionpralablementdfinie. UnefonctionutilisateursappellecommeunefonctionnativedePHP :dansuneaffectation,dansunecomparaison,etc. Si la fonction retourne une valeur, il est possible dutiliser linstruction return pour dfinir la valeur de retour de la fonction. Syntaxe return [expression]; expression Expressiondontlersultatconstituelavaleurderetourdelafonction(NULLpardfaut). Lersultatdunefonctionpeuttredenimportequeltype(chane,nombre,tableau,etc.). Linstruction return stoppe lexcution de la fonction et retourne le rsultat de expression lappelant. Si plusieurs instructions returnsontprsentesdanslafonction,cestlapremirerencontredansledroulementdesinstructions qui dfinit la valeur de retour et provoque linterruption de la fonction. Si la fonction ne comporte aucune instruction return(ousiaucuneinstructionreturnnestexcute),lavaleurderetourdelafonctionestNULL. Exemple <?php // Fonction sans paramtre qui affiche "Bonjour !" // pas de valeur de retour function afficher_bonjour() { echo Bonjour !<br />; }

ENI Editions - All rigths reserved

- 1-

// Fonction avec 2 paramtres qui retourne le produit // des deux paramtres. function produit($valeur1,$valeur2) { return $valeur1 * $valeur2; } // Appel de la fonction afficher_bonjour afficher_bonjour(); // Utilisations de la fonction produit : // - dans une affectation $rsultat = produit(2,4); echo "2 x 4 = $rsultat<br />"; // - dans une comparaison if (produit(10,12) > 100) { echo 10 x 12 est suprieur 100.<br />; } ?> Rsultat Bonjour ! 2 x 4 = 8 10 x 12 est suprieur 100.

anslelangagePHP,ilnexistepasproprementparlerdeprocdure.Pourdfinirquelquechosedquivalent D uneprocdure,ilsuffitdedfinirunefonctionquineretournepardevaleuretdappeler la fonction comme si ctaituneinstruction(commelafonctionafficher_bonjourparexemple).

Il est possible dutiliser une fonction avant de la dfinir. Il ny a donc aucun problme pour dfinir des fonctions qui sappellententreelles. ne fonction est utilisable uniquement dans le script o elle est dfinie. Pour pouvoir lutiliser dans plusieurs U scripts,lemieuxestdeladfinirdansunfichierincluspartoutolafonctionestncessaire. PHPpermetdestockerunnomdefonctiondansunevariableetdappelerlavariabledansuneinstruction,commesi ctait une fonction, avec la notation $variable(). Sur une telle criture, PHP remplace la variable par sa valeur et cherche excuter la fonction correspondante (qui doit, bien entendu, exister). Cette fonctionnalit est appele "fonctionvariable". Exemple <?php // Fonction qui effectue un produit. function produit($valeur1,$valeur2) { return $valeur1 * $valeur2; } // Fonction qui effectue une somme. function somme($valeur1,$valeur2) { return $valeur1 + $valeur2; } // Fonction qui effectue un calcul, le nom du calcul //(somme ou produit) tant pass en paramtre. function calculer( $ o p r a t i o n ,$valeur1,$valeur2) { // $opration contient le nom de la fonction // a excuter => appel $opration(). return $ o p r a t i o n ( $ v a l e u r 1 , $ v a l e u r 2 ) ; } // Utilisation de la fonction calculer. echo 3 + 5 = ,calculer(somme,3,5).<br />; echo 3 x 5 = ,calculer(produit,3,5).<br />; ?> Rsultat 3 + 5 = 8 3 x 5 = 15

- 2-

ENI Editions - All rigths reserved

3.Paramtres
Lesparamtres(aussiappelsarguments)ventuelsdunefonctionsontdfinissouslaformedunelistedevariables. Dansceparagraphe,nousallonstudierlespossibilitssuivantes :
q

dfinirunevaleurpardfautpourunparamtre passerunparamtreparrfrence utiliserunelistevariabledeparamtres.

a.Valeurpardfaut
Ilestpossibledindiquerquunparamtrepossdeunevaleurpardfautgrcelasyntaxesuivante : $paramtre = expression_littrale Lavaleurpardfautdunparamtredoittreuneexpressionlittraleetnepeuttreniunevariable,niunefonction, niuneexpressioncompose.Lesconstantessontautorises. Lavaleurpardfautestutilisecommevaleurdunparamtrelorsquelafonctionestappelesansmentionnerde valeurpourleparamtreenquestion. Exemple <?php // Dfinition dune constante define(UN,1); // Dfinition de la fonction produit avec des valeurs // par dfaut pour les paramtres (dont une constante // pour le premier paramtre). function produit($valeur1=UN,$valeur2=2) { return $valeur1 * $valeur2; } // Appels // - sans paramtre echo produit() = ,produit(),<br />; // - avec un seul paramtre = forcment le premier echo produit(3) = ,produit(3),<br />; ?> Rsultat produit() = 2 produit(3) = 6 Ne pas donner de valeur un paramtre ayant une valeur par dfaut nest possible quen partant de la droite. Passerunevaleur"vide"(chanevideou NULL)nersoutpasleproblmecarlavaleurenquestionestconvertiepar PHPdansletypeadquat(0surlexempleprcdent). Passerunnombreinsuffisantdeparamtresetnepasavoirdevaleurpardfautgnreuneerreur.Passertropde paramtresnegnrepasderreur lesparamtresentropsontignors.

b.Passageparrfrence
Par dfaut, le passage des paramtres seffectue par valeur : cest une copie de la valeur qui est passe la fonction.Enconsquence,lamodificationdesparamtreslintrieur de la fonction naaucuneffetsurlesvaleurs danslescriptappelant. Encasdebesoin,ilestpossibledavoirunpassageparrfrenceenutilisantloprateurderfrence&(cf.chapitre IntroductionPHPLesbasesdulangagePHP)devantlenomduparamtredansladfinitiondelafonction.Avec une telle dfinition, cest une rfrence vers la variable (et non une copie) qui est passe la fonction cette derniretravailledirectementsurlavariableduscriptappelant.

ENI Editions - All rigths reserved

- 3-

Exemple <?php // Dfinition dune fonction qui prend deux paramtres : // un pass par valeur et lautre par rfrence. function une_fonction($par_valeur,&$par_rfrence) { // Incrmentation des deux paramtres. $par_valeur++; $par_rfrence++; // Affichage des deux paramtres lintrieur // de la fonction. echo "\$par_valeur = $par_valeur<br />"; echo "\$par_rfrence = $par_rfrence<br />"; } // Initialisation de deux variables. $x = 1; $y = 10; // Affichage des variables avant lappel la fonction. echo "\$x avant appel = $x<br />"; echo "\$y avant appel = $y<br />"; // Appel de la fonction en utilisant les deux variables comme // valeur des paramtres. une_fonction($x,$y); // Affichage des variables aprs lappel la fonction. echo "\$x aprs appel = $x<br />"; echo "\$y aprs appel = $y<br />"; ?> Rsultat $x avant appel = $y avant appel = $par_valeur = 2 $par_rfrence = $x aprs appel = $y aprs appel = 1 10 11 1 11

Avec une telle dfinition, il nest plus possible de passer une constante ou une expression comme valeur du paramtre.

c.Listevariabledeparamtres
lintrieurdunefonction,ilestpossibledutiliserlestroisfonctionsPHPsuivantes : Fonction Rle Donnelenombredeparamtrespassslafonction. Retournelalistedesparamtrespassslafonction (dansuntableau). Retournelavaleurdunparamtredontlenumroest prcis.

func_num_args func_get_args func_get_arg


Syntaxe entier func_num_args() tableau func_get_args() mixte func_get_arg( entier numro) numro Numroduparamtredemand(0=premierparamtre).

- 4-

ENI Editions - All rigths reserved

laide de ces fonctions natives, il est trs simple dcrire une fonction qui accepte un nombre variable de paramtres.Lesprincipessontlessuivants :
q

dclarerlafonctionsansparamtre rcuprer,danslecorpsdelafonction,lesparamtresaveclesfonctions func_get_argsou func_get_arget lesutiliser(typiquementdansuneboucle).

Danslapratique,rienninterditauxparamtresdtredetypediffrent. Parailleurs,ilestpossiblededclarerexplicitementlespremiersparamtresetdaccepterensuiteunelistevariable deparamtrescomplmentaires.Danscecas,lesparamtresexplicitementdclarssontreprisdanslecomptageet danslalistedesparamtres.Ilconvientdoncdelesliminersoimmedutraitement. Exemple <?php // Fonction qui accepte un premier paramtre par rfrence // et qui y stocke le produit de tous les autres paramtres. function produit(&$rsultat) { switch (func_num_args()) { case 1: // Un seul paramtre (la variable pour le rsultat) // Retourner 0 (choix arbitraire). $rsultat = 0; break; default: // Rcuprer les paramtres dans un tableau // et supprimer le premier lment (le premier // paramtre). $paramtres = func_get_args(); unset($paramtres[0]); // Initialiser le rsultat 1 $rsultat = 1; // Faire une boucle sur le tableau des paramtres // pour multiplier le rsultat par le paramtre. foreach($paramtres as $paramtre) { $rsultat *= $paramtre; } break; } } // appels produit($rsultat); echo produit($rsultat) => ,$rsultat,<br />; produit($rsultat,1,2,3); echo produit($rsultat,1,2,3) => ,$rsultat,<br />; ?> Rsultat produit($rsultat) => 0 produit($rsultat,1,2,3) => 6

4.Considrationssurlesvariablesutilisesdanslesfonctions
a.Variablelocaleglobale
Les variables utilises lintrieurdune fonction sont locales : elles sont non dfinies en dehors de la fonction et initialiseschaqueappeldelafonction.Ilenestdemmedesparamtresdelafonction. Rciproquement,unevariabledfinieendehorsdelafonction(danslescriptappelant)nestpasdfinielintrieur delafonction. PHPproposeunenotiondevariableglobalepouraccderdansunefonctionauxvariablesdfiniesdanslecontexte duscriptappelant.

ENI Editions - All rigths reserved

- 5-

Pourcela,lintrieurdelafonction,ilfautdclarerlesvariablesglobalesquelafonctionutiliseaveclemotclglobal ouutiliserletableauassociatifprdfini$GLOBALS. Syntaxe global $variable[, ...]; $variable Variabledelafonctionquiauneporteglobale.Plusieursvariablespeuventtrementionnes,enlessparantpar unevirgule. Le tableau prdfini $GLOBALS est un tableau associatif. Dans ce tableau associatif, la cl est gale au nom de la variableglobale(sansle$)etlavaleurassocieestgalelavaleurdelavariableglobale. e tableau associatif $GLOBALS est un tableau "superglobal". Un tableau superglobal est automatiquement L disponible dans tous les environnements dexcution, sans avoir le dclarer global. Dans ce livre, nous utiliseronsdautrestableauxsuperglobaux. Exemple <?php // Objectif : crire une fonction qui effectue le produit // des variables $x et $y et qui stocke le rsultat // dans la variable $z. // Initialisation de deux variables dans le script appelant. $x = 2; $y = 5; echo <b>Cas 1 : pas d\utilisation des variables , globales</b><br />; function produit1() { // $x et $y sont vides lintrieur de la fonction. echo "\$x = $x<br />"; echo "\$y = $y<br />"; $z = 0 + $x * $y; } produit1(); // $z est vide dans le script principal. echo "\$z = $z<br />"; // Rsolution du problme en utilisant des variables globales : // - avec le mot cl global pour $x et $y // - avec le tableau $GLOBALS pour $z echo <b>Cas 2 : utilisation des variables globales</b><br />; function produit2() { global $x, $y; echo "\$x = $x<br />"; echo "\$y = $y<br />"; $GLOBALS[z] = 0 + $x * $y; } produit2(); echo "\$z = $z<br />"; ?> Rsultat Cas $x = $y = $z = Cas $x = $y = $z = 1 : pas dutilisation des variables globales

2 : utilisation des variables globales 2 5 10

n paramtre dune fonction se comporte comme une variable locale la fonction, sauf sil est pass par U rfrence,auquelcasilestquivalentunevariableglobale.

- 6-

ENI Editions - All rigths reserved

b.Variablestatique
Pardfaut,lesvariableslocalesdunefonctionsontrinitialiseschaqueappeldelafonction. Le mot cl staticpermetdedfinirdesvariableslocalesstatiquesquiontpourpropritdeconserverleurvaleur dunappellautredelafonction,pendantladureduscript. Syntaxe static $variable = expression_littrale[, ...]; $variable Variableconcerne. expression_littrale Valeurinitialeaffectelavariablelorsdupremierappellafonctionlintrieurduscript.Seuleslesexpressions littralesetlesconstantessontacceptes lesexpressionscomposesoulesfonctionsnesontpasautorises. Exemple <?php // Dfinition dune fonction function variable_statique() { // Initialisation dune variable statique. static $variable_statique = 0; // Initialisation dune autre variable. $autre_variable = 0; // Affichage des deux variables. echo "\$variable_statique = $variable_statique <br />"; echo "\$autre_variable = $autre_variable<br />"; // Incrmentation des deux variables. $variable_statique++; $autre_variable++; } // Premier appel de la fonction. echo <b>Premier appel de la fonction :</b><br />; variable_statique(); // ... // Deuxime appel de la fonction. echo <b>Deuxime appel de la fonction :</b><br />; variable_statique(); //... // Troisime appel de la fonction. echo <b>Troisime appel de la fonction :</b><br />; variable_statique(); ?> Rsultat Premier appel de la fonction : $variable_statique = 0 $autre_variable = 0 Deuxime appel de la fonction : $variable_statique = 1 $autre_variable = 0 Troisime appel de la fonction : $variable_statique = 2 $autre_variable = 0

avaleurnestconservequependantladureduscript :lorsquecederniersetermine,lavaleurestperdue L etauprochainappelduscript,lavariablestatiqueestrinitialise.

ENI Editions - All rigths reserved

- 7-

5.Lesconstantesetlesfonctions
DanslechapitreIntroductionPHP,nousavonsvuquelaportedesconstantesestlescriptdanslequelellessont dfinies. la diffrence des variables, cette porte stend aux fonctions utilises dans le script : une constante peut tre utiliselintrieurdelafonctionsansquellesoitdclareglobale.Rciproquement,uneconstantedfiniedansune fonctionpeuttreutilisedansunscript,aprsappeldelafonction. Exemple <?php // Dfinition dune constante dans le script. define(CONSTANTE_SCRIPT,constante script); // Dfinition dune fonction. function constante() { // Qui dfinit une constante. define(CONSTANTE_FONCTION,"constante fonction"); // Et qui affiche une constante du script appelant. echo Dans la fonction, CONSTANTE_SCRIPT = , CONSTANTE_SCRIPT,<br />; } // Appel de la fonction. constante(); // Affichage de la constante dfinie dans la fonction. echo Dans le script, CONSTANTE_FONCTION = , CONSTANTE_FONCTION,<br />; ?> Rsultat Dans la fonction, CONSTANTE_SCRIPT = constante script Dans le script, CONSTANTE_FONCTION = constante fonction

6.Rcursivit
linstardenombreuxlangages,PHPautoriselarcursivit,cestdirelapossibilitpourunefonctiondesappeler ellemme. Pourillustrercettepossibilit,nousallonscrireunefonctiongnriquequipermetdafficherlecontenuduntableau, ventuellementmultidimensionnel. Source <?php function afficher_tableau($tableau,$titre="",$niveau=0) { // Paramtres // - $tableau = tableau dont il faut afficher le contenu // - $titre = titre afficher au dessus du contenu // - $niveau = niveau daffichage // Sil y a un titre, lafficher. if ($titre != "") { echo "<br /><b>$titre</b><br />"; } // Tester sil y a des donnes. if (isset($tableau)) { // il y a des donnes // Parcourir le tableau pass en paramtre. reset ($tableau); foreach ($tableau as $cle => $valeur) { // Afficher la cl (avec indentation fonction // du niveau). echo str_pad(,12*$niveau, &nbsp;), htmlentities($cle), = ; // Afficher la valeur if (is_array($valeur)) { // cest un tableau ...

- 8-

ENI Editions - All rigths reserved

// mettre une balise <br /> echo <br />; // Et appeler rcursivement afficher_tableau pour // afficher le tableau en question (sans titre et // au niveau suivant pour lindentation) afficher_tableau($valeur,,$niveau+1); } else { // cest une valeur scalaire // Afficher la valeur. echo htmlentities($valeur),<br />; } } } else { // pas de donnes // Mettre une simple balise <br /> echo <br />; } } // Afficher un tableau de couleurs. $couleurs = array(Bleu,Blanc,Rouge); afficher_tableau($couleurs,Couleurs); // Afficher un tableau deux dimensions (pays/ville). $pays = array(France => array(Paris,Lyon,Nantes), Italie => array(Rome,Venise)); afficher_tableau($pays,Pays/Villes); ?> Rsultat Couleurs 0 = Bleu 1 = Blanc 2 = Rouge Pays/Villes France = 0 = Paris 1 = Lyon 2 = Nantes Italie = 0 = Rome 1 = Venise Pourtrerigoureux,ilfaudraittesterquelavariablepasseinitialementenpremierparamtreestbienuntableau. Nousutiliseronscettefonctionplusieursreprisesdanscetouvrage,partantdelhypothsequellefaitpartiedunjeu defonctionsgnriquesdfiniesdansunfichierquiestinclusdanslescriptencasdebesoin.

ENI Editions - All rigths reserved

- 9-

Classes
1.Concept
PHPproposedesfonctionnalitsclassiquesdeprogrammationorienteobjet :
q

dfinitiondeclasse utilisationdemthodesconstructeuretdestructeur notionsdattributoudemthodepublic,priv,protg hritage notions de classe ou mthode abstraite, de classe ou mthode finale, dinterface, dattribut ou mthode statique(declasse) exceptions.

Uneclasseestuntypecompositeregroupantdesvariables(appelesattributsdelaclasse)etdesfonctions(appeles mthodesdelaclasse).Ensoi,uneclassenecontientpasdedonnes cestjusteunmodle,unedfinition. partir de la classe, il est possible de dfinir ("instancier") des objets qui ont la structure de la classe et qui, eux, contiennentdesdonnes. Dans cette partie, nous allons prsenter les fonctionnalits de base les plus couramment utilises : cest une introductionpratiqueauxfonctionnalitsobjetdePHP.Pourplusdinformations,reportezvousladocumentationde PHP.

2.Dfiniruneclasse
Lemotclclasspermetdintroduireladfinitionduneclasse. Syntaxe class nom_classe { // dfinition des attributs [ public | private | protected $attribut [= littral]; ... ] // dfinition des mthodes [ [public | private | protected] function mthode() { ... } ... ] } nom_classe Nomdelaclasse(doitrespecterlesrglesdenommageprsentesdanslechapitreIntroductionMySQL). $attribut Nomdunevariablecorrespondantunattributdelaclasse. littral Valeurinitialedelattribut.Seuleslesexpressionslittralesetlesconstantessontacceptes lesexpressions

ENI Editions - All rigths reserved

- 1-

composesoulesfonctionsnesontpasautorises. mthode Dfinitiondunefonctioncorrespondantunedesmthodesdelaclasse. Lavisibilitdesattributsetdesmthodesestdfinieparundesmotsclssuivants : public Lattributoulamthodesontpublicsetlonpeutyaccderdelextrieurdelaclasse. private Lattributoulamthodesontprivsetlonnepeutyaccderquedelintrieurdelaclasse. protected Lattributoulamthodesontprotgsetlonnepeutyaccderquedelintrieurdelaclasseoudesclassesdrives delaclasse(voirlanotiondhritage). Pardfaut,unemthodeestpublique.Parcontre,lavisibilitdelattributdoittrespcifie. Les mthodes sont dfinies comme des fonctions utilisateur classiques (avec paramtres, instruction return, etc.), mais,lintrieurdelaclasse.Unemthodeduneclassepeutavoirlemmenomquunefonctionutilisateurouquune autremthodeduneautreclasse. Unedesmthodespeutporterlemmenomquelaclassedanslaquelleelleestdfinie.Cettemthodeparticulire, appele mthode constructeur, est automatiquement appele la cration ("instanciation") dun nouvel objet. Gnralement,cettemthodeestutilisepourinitialiserdesattributsquinepeuventltreparunesimpleexpression littrale.Lamthodeconstructeurduneclassepeuttrenommedemanireunifie__construct.Cettemthodede nommageestconseillecarellefacilitelappeldelamthodeconstructeurduneclasseparentdansuneclassedrive (voirlanotiondhritage).EnpremierPHPrecherchetoujoursunemthodenomme__construct silnentrouvepas ilrechercheunemthodeportantlemmenomquelaclasse. Encomplment,ilestpossibledespcifierunemthode destructeur nomme __destruct(pasdeparamtre).Cette mthode destructeur est automatiquement appele lorsque la dernire rfrence un objet est supprime. Cette mthodepeuttreutilisepourlibrerdesressourcesutilisesparlobjet(fichier,connexionunebasededonnes, etc.). Enfin,ilestpossibledespcifierunemthode tostringnomme__toString(pasdeparamtre)quipermetdeconvertir unobjetenchane.Cettemthodeestautomatiquementappelechaquefoisquelobjetestutilisdansuncontexte oPHPattendunechane(parexempledansun echo).Cettemthodedoitretournerunechanedanslaquellevous pouvezintgrerlesinformationsquevoussouhaitezsurlobjet. lintrieur des mthodes, lobjet courant (ou instance courante) peut tre rfrenc par la variable $this pour accder aux attributs ou aux mthodes, il suffit dutiliser loprateur -> suivi du nom de lattribut ou du nom de la mthode,derrirelenomdelavariable$this. Syntaxe $this->attribut $this->mthode([valeur[, ...]]) Biennoterquelesigne$portesurlenomdelavariablethis,passurlenomdelattribut. Exemple <?php // Dfinition dune classe destine stocker des informations // sur un utilisateur. class utilisateur { // Dfinition des attributs. public $nom; // nom de lutilisateur public $prnom; // prnom de lutilisateur public $langue = fr; // langue de lutilisateur // franais par dfaut private $timestamp; // date/heure de cration (priv) // Dfinition des mthodes : // - mthode constructeur public function __construct($prnom,$nom) {

- 2-

ENI Editions - All rigths reserved

// Initialiser le nom et le prnom // avec les valeurs passes en paramtre. $this->prnom = $prnom; $this->nom = $nom; // Initialiser le timestamp avec la fonction time(). $this->timestamp = time(); } // - mthode destructeur public function __destruct() { // Se contente dafficher un message. echo "<p><b>Suppression de $this->nom</b></p>"; } // - mthode de conversion de lobjet en chane public function __toString() { // Retourne juste le nom et le prnom. return "__toString = $this->nom - $this->prnom"; } // - mthode qui modifie la langue de lutilisateur. public function langue($langue) { $this->langue = $langue; } // - mthode (prive) qui met en forme la date/heure // de cration de lutilisateur. private function miseEnFormeTimestamp() { setlocale(LC_TIME,$this->langue); return strftime(%c, $this->timestamp); } // - mthode qui donne des informations sur lutilisateur public function informations() { $cration = $this->miseEnFormeTimestamp(); return "$this->prnom $this->nom - $cration"; } } ?>

ne classe est utilisable uniquement dans le script o elle est dfinie. Pour pouvoir lutiliser dans plusieurs U scripts,lemieuxestdeladfinirdansunfichierquiestincluspartoutolaclasseestutilise.

3.Instancieruneclasse
Instancieruneclassesignifiecrerunobjetbassurladfinitiondelaclasse.Dansunecertainemesure,celarevient dfinirunevariableayantcomme"type"laclasse. Linstanciationseffectuegrceloprateurnew. Syntaxe $nom_objet = $nom_objet Variabledestinestockerlobjet. nom_classe Nomdelaclassequisertde"modle"lobjet. valeur Paramtreventuelpasslamthodeconstructeurdelaclasseappelelorsdelacrationdelobjet. Aprscrationdelobjet,lesattributsetmthodespublicsdelobjetpeuventtreatteintsavecloprateur ->,surla variable$nom_objet,commeaveclavariable$this. new nom_classe[(valeur[, ...])]

ENI Editions - All rigths reserved

- 3-

Ilnyapasdeprotectiondesattributspublicsdesobjets ilspeuventtremanipulsdirectement. Exemple <?php // Inclusion du fichier qui contient la dfinition de la // classe utilisateur prsente prcdemment. include(classes.inc); // Instanciation dun objet. $moi = new utilisateur(Olivier,Heurtel); // La variable $moi contient maintenant un objet bas sur la // classe utilisateur. Les mthodes sont accessibles par // loprateur ->. // Utilisation des mthodes de lobjet. echo "{$moi->informations()} <br/>"; $moi->langue(us); // modification de la langue echo "{$moi->informations()} <br/>"; // Modification et lecture directe dun attribut public $moi->nom = strtoupper($moi->nom); echo "$moi->nom <br />"; // Affichage direct de lobjet => utilisation de __toString echo "$moi <br />"; ?> Rsultat Olivier Heurtel - 07/12/2007 21:09:28 Olivier Heurtel - 12/7/2007 09:09:28 PM HEURTEL __toString = HEURTEL - Olivier Suppression de HEURTEL Commelemontrecetexemple,lesvariablesobjetpeuventtresubstituescommelesautres(cf.chapitreIntroduction PHPLesbasesdulangagePHP)dansleschanesdecaractresdlimitespardesguillemetsdoubles.Encasde besoin,lesaccoladespeuventtreutilisespourdlimiterlavariablelintrieurdelachane. esrglesdeporteetdeduredeviedesvariablessappliquentauxobjets(cf.chapitreIntroductionPHP L LesbasesdulangagePHP).

4.Hritage
Ilestpossiblededfinirunenouvelleclassequihriteduneclasseexistanteaveclemotclextends. Syntaxe class nom_classe e x t e n d s nom_classe_de_base{ // Dfinition des attributs supplmentaires. [ public | private | protected $attribut [= littral]; ... ] // Dfinition des mthodes supplmentaires. [ [public | private | protected] function mthode() { ... } ... ] } Lasignificationdesdiffrentslmentsestlammequepourladfinitionduneclasse. La nouvelle classe cre est appele classe fille et la classe de base (qui a servi de "moule" cette cration) est nommeclassemre.

- 4-

ENI Editions - All rigths reserved

La nouvelle classe possde implicitement les attributs et mthodes de la classe de base et peut en dfinir de nouveaux, notamment une mthode constructeur nomme __construct. Si la classe fille na pas de mthode constructeur,cestlamthodeconstructeurdelaclassemrequiestappelelorsdelinstanciation dunobjetsurla classefille. Quandlamthodeconstructeurexistedanslaclassefille,ilnyapasdappelautomatiquelamthodeconstructeur delaclassemre :sincessaire,ilfautlappelerexplicitementenutilisantparent::__construct(). Exemple <?php // Dfinition dune classe de base. class utilisateur { // Dfinition des attributs. public $nom; // nom de lutilisateur public $prnom; // prnom de lutilisateur // Dfinition des mthodes : // - mthode constructeur public function __construct($prnom,$nom) { // Initialiser le nom et le prnom // avec les valeurs passes en paramtre $this->prnom = $prnom; $this->nom = $nom; } // - mthode qui donne les informations sur lutilisateur public function informations() { return "$this->prnom $this->nom"; } } // Dfinition dune classe qui hrite de la premire class utilisateur_couleur extends utilisateur{ // Dfinition des attributs complmentaires. public $couleurs; // couleurs prfres de lutilisateur // Dfinition des mthodes complmentaires // - mthode constructeur public function __construct($prnom,$couleurs) { // Appel au constructeur de la classe mre // pour la premire partie de linitialisation. parent::__construct ($prnom,X); // Initialisation spcifique complmentaire. $this->couleurs = explode(,,$couleurs); } // - liste des couleurs prfres de lutilisateur public function couleurs() { return implode(,,$this->couleurs); } } // Instanciation dun objet sur la classe fille. $moi = new utilisateur_couleur(Olivier,bleu,blanc,rouge); // Utilisation des mthodes : // - de la classe mre echo "{$moi->informations()}<br />"; // existe par hritage // - de la classe fille echo "{$moi->couleurs()}<br />"; // existe dans la classe ?> Rsultat Olivier X bleu,blanc,rouge

ans une classe fille, il est possible de redclarer une mthode ou un attribut qui existe dans la classe mre. D Dans ce cas, loprateur parent:: peut tre utilis pour faire rfrence explicitement aux attributs (parent::attribut) ou mthodes (parent::mthode()) de la classe mre et lever lambigut du nommage (cet oprateurpeuttreutilismmesilnyapasdambigut).

ENI Editions - All rigths reserved

- 5-

5.Autresfonctionnalitssurlesclasses
a.Classeoumthodeabstraite
Uneclasseabstraiteestuneclassequinepeutpastreinstancie(pasdecrationdobjetsurlaclasse).Parcontre unetelleclassepeutservirdebaseladfinitionduneclassefillequipourratreinstancie(saufsielleestelle mmeabstraite). Unemthodeabstraiteestunemthodequiestdfiniedansuneclasse(ellemmeobligatoirementabstraite)mais pasimplmente(lecodedelamthodenestpasprsent).Unetellemthodepourratreimplmentedansune classefille.Unemthodeabstraitenepeutpastreprive. Entermedesyntaxe,ilsuffitdemettrelemotclabstractdevantladfinitiondelaclasseoudelamthode. Une classe fille qui nimplmente pas toutes les mthodes abstraites de la classe mre est implicitement abstraite (mmesilemotclabstractnestpasprsent). Exemple <?php // Dfinition dune classe abstraite. a b s t r a c t class classeMre { // Attribut protg. protected $x; // Deux mthodes pour accder lattribut protg : // - pour lire public function get() { return "GET = $this->x"; } // - pour crire // > mthode abstraite a b s t r a c t public function put($valeur); } // Dfinition dune classe fille qui hrite de la classe mre. class classeFille extends classeMre { // Implmentation de la mthode dcriture. public function put($valeur) { $this->x = $valeur; } } // Utilisation de la classe fille. $objet = new classeFille(); $objet->put(123); echo "{$objet->get()} <br />"; ?> Rsultat GET = 123

b.Classeoumthodefinale
Onnepeutpashriterduneclassefinale. Unemthodefinalenepeutpastreredfiniedansuneclassefille. Entermesdesyntaxe,ilsuffitdemettrelemotclfinaldevantladfinitiondelaclasseoudelamthode. Tenterdhriterduneclassefinalegnreuneerreur : F a t a l e r r o r : Class classeFille may not inherit from final class (classeMre) in \ a p p \ s c r i p t s \ i n d e x . p h p on line 1 0 Tenterderedfinirunemthodefinaledansuneclassedrivegnreuneerreur : F a t a l e r r o r : Cannot override final method classeMre::mthodeFinale() in \ a p p \ s c r i p t s \ i n d e x . p h p on line 1 4

- 6-

ENI Editions - All rigths reserved

c.Interface
Uneinterfaceestuneclassequinecontientquedesspcificationsdemthodessansimplmentations.Uneinterface necontientpasdattributsnonplus. Dautresclassespeuventtreensuitedfiniesetimplmenteruneouplusieursinterfaces,cestdireimplmenter lesmthodesduneouplusieursinterfaces. Syntaxededfinitionduneinterface interface nom_interface { // Dfinition des mthodes. [public] function mthode(); ... } nom_interface Nomdelinterface(doitrespecterlesrglesdenommageprsentesdanslechapitreIntroductionPHPStructure debasedunepagePHP). mthode Spcificationdunemthodedelinterface. Lesmthodesduneinterfacesontforcmentpubliques lemotclpublicpeuttreomis. Ilestpossiblededfinirunenouvelleclassequiimplmenteuneouplusieursinterfacesaveclemotclimplements. Syntaxe class nom_classe i m p l e m e n t s nom_interface[,...] { ... } Unetelleclassedoitredfinirlesdiffrentesmthodesdesinterfacesquelleimplmente.Silunedesmthodesdes interfacesnestpasimplmente,laclassedoittredclareabstraite. Exemple <?php // Dfinition de deux interfaces. interface lecture { function get(); } interface criture { function put($valeur); } // Dfinition dune classe qui implmente les deux interfaces. class uneClasse implements lecture,criture { // Dfinition dun attribut quelconque. private $x; // Implmentation de la mthode de lecture. public function get() { return $this->x; } // Implmentation de la mthode dcriture. public function put($valeur) { $this->x = $valeur; } } ?>

d.AttributoumthodestatiqueConstantedeclasse
Un attribut ou une mthode statique sont utilisables directement sans instanciation pralable dun objet. On parle aussidattributoudemthodedeclasse. Pourdfinirunattributouunemthodestatique,ilsuffitdeplacerlemotclstaticdevantladfinitiondelattribut

ENI Editions - All rigths reserved

- 7-

oudelamthode. Pour rfrencer un attribut ou une mthode statique, il faut utiliser la syntaxe nom_classe::$nom_attribut ou nom_classe::nom_mthode(). Une constante de classe est une constante dfinie dans une classe utilisable directement sans instanciation pralabledunobjet(commeunattributdeclasse,maisconstant). Syntaxededfinitionduneconstantedeclasse const nom_constante = valeur; nom_constante Nomdelaconstante. valeur Valeurdelaconstante. Uneconstantedeclasseestimplicitementpublique. Pourrfrenceruneconstantedeclasse,ilfaututiliserlasyntaxenom_classe::nom_constante. Exemple <?php // Dfinition dune classe. class uneClasse { // Attribut priv quelconque. private $x; // Attribut priv statique pour stocker // le nombre dobjets instancis. static private $nombre = 0; // Constante de classe pour dfinir une valeur // par dfaut. const DEFAUT = X; // Fonction publique statique qui retourne le // nombre dobjets. static public function nombreObjets() { return uneClasse::$nombre; } // Mthode constructeur // - rcuprer la valeur de lattribut (valeur par dfaut // = la constante de classe) // - incrmenter le nombre dobjets public function __construct($valeur = uneClasse::DEFAUT) { $this->x = $valeur; uneClasse::$nombre++; echo "Cration de lobjet : $this->x<br />"; } // Mthode destructeur. // - dcrmenter le nombre dobjets public function __destruct() { uneClasse::$nombre--; echo "Suppression de lobjet : $this->x<br />"; } } // Crer deux objets. $inconnu = new uneClasse(); $abc = new uneClasse (ABC); // Afficher le nombre dobjets echo uneClasse::nombreObjets(), objet(s)<br />; // "Supprimer" un objet. unset($inconnu); // Afficher le nombre dobjets echo uneClasse::nombreObjets(), objet(s)<br />; ?> Rsultat

- 8-

ENI Editions - All rigths reserved

Cration de Cration de 2 objet(s) Suppression 1 objet(s) Suppression

lobjet : X lobjet : ABC de lobjet : X de lobjet : ABC

6.Exceptions
LesfonctionnalitsorientesobjetdePHPutilisentlanotiondexceptionpourgrerleserreurs(commeleslangages C++etJava). Le principe consiste inclure le code susceptible de gnrer des erreurs dans un bloc try et lui associer un bloc catchdestinintercepterleserreursetlestraiter : Structuregnrale try { // Code susceptible de gnrer des erreurs. ... } catch (Exception $e) { // Code destin traiter les erreurs. ... } LaclasseExceptionestuneclassequicomportenotammentlesmthodessuivantes : __construct Mthodeconstructeuracceptantdeuxparamtres :unmessagederreuretuncodederreur(optionnel). getMessage Mthodepermettantdercuprerlemessagederreur. getCode Mthodepermettantdercuprerlecodederreur. lintrieur du bloc try, une exception peut tre leve par une instruction du type throw new Exception(message [,code]).DanslebloccatchlesmthodesgetMessageetgetCodepermettentdercuprerdesinformationssurlerreur etdelatraiter.Encasdexceptiondansunbloctry,letraitementsebranchedirectementdanslebloccatch :lereste dubloctrynestpasexcut. Exemple <?php // Dfinition dune classe. class uneClasse { // Un attribut quelconque. private $x; // Mthode constructeur. public function __construct($valeur) { $this->x = $valeur; } // Mthode qui effectue une action quelconque. public function action() { // Pour une raison donne laction est interdite // si lattribut est ngatif : une exception est leve. if ($this->x < 0) { throw new Exception(Action interdite,123); } } } // Crer deux objets. $objet = new uneClasse(1); try {

ENI Editions - All rigths reserved

- 9-

echo Objet 1 : ; $objet->action(); // ne va pas lever dexception echo OK<br />; } catch (Exception $e) { echo ERREUR ,$e->getCode(), - ,$e->getMessage(),<br />; } $objet = new uneClasse(-1); try { echo Objet 2 : ; $objet->action(); // va lever une exception echo OK<br />; } catch (Exception $e) { echo ERREUR ,$e->getCode(), - ,$e->getMessage(),<br />; } ?> Rsultat Objet 1 : OK Objet 2 : ERREUR 123 - Action interdite

- 10 -

ENI Editions - All rigths reserved

Vuedensemble
Uneerreur,dansunscriptPHP,peutsemanifesterdedeuxfaons,ventuellementsimultanes :
q

parunevaleurderetourparticuliredelafonctionPHPdanslaquellelerreurestrencontre parunmessageenvoydirectementdanslapage.

Exemples Fonction Comportementencasderreur Silefichierpassenparamtrenexistepas,un messageestaffichmaisaucuncodeparticuliernest retournparlafonction. SileserveurMySQLretourneuneerreursurlexcution dunerequte,aucunmessagenestaffichmaisla fonctionretourneFALSE(lanaturedelerreurpouvant trercuprepardautresfonctions). SileserveurMySQLretourneuneerreurlorsdela connexion,unmessageestaffichetlafonction retourneFALSE(lanaturedelerreurpouvanttre rcuprepardautresfonctions).

require

mysqli_query

mysqli_connect

Grer les erreurs dans un script PHP consiste donc, en gnral, mettre en place un mcanisme qui permette de dtecterlagnrationduneerreurafindaffichersoimmeunmessagelaplacedumessagedirectementaffichpar PHP.

ENI Editions - All rigths reserved

- 1-

LesmessagesderreurPHP
Lesmessagesderreur(oudalerte)affichsparPHPontunniveaucorrespondantleurgravit : Valeur Constanteassocie Description Erreurfataledexcution(message "fatalerror: ...").Lescriptne sexcutepas.Exemples :appel unefonctionquinexistepas, fichiermentionndanslinstruction requirequinexistepas. Alertedexcution(message "warning: ...").Lescriptse poursuit.Exemple :tentative douverture,avecfopen,dunfichier quinexistepas,ouverturedune connexionMySQLquichoue... Gnralement,lapoursuitedu scriptprovoquedautresmessages dummetype. Erreurdecompilation("Parse error: ...").Lescriptnesexcute pas.Exemple :oublidunpoint virgule,duneparenthse fermante... Avertissementlorsdelexcution (message"Notice: ...").Pardfaut, PHPestconfigurpournepas affichercesavertissements.Le scriptsepoursuit.Exemple : utilisationdunevariablenon initialise. Erreurfatalelorsdelinitialisation dePHP. AlertelorsdelinitialisationdePHP. Erreurfatalelorsdelacompilation. Alertelorsdelacompilation. Erreurgnreparledveloppeur. Alertegnreparledveloppeur. Avertissementgnrparle dveloppeur. Conseilslorsdelexcution. AutorisePHPsuggrerdes modificationspouramliorerla portabilitducode,notamment verslesfuturesversions(utilisation dunefonctiondprciepar exemple).Semblemasquerles erreursdeniveauinfrieur.Ce niveauestapparuenversion5. Erreurfatalercuprable.Si

E_ERROR

E_WARNING

E_PARSE

E_NOTICE

16

E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING E_USER_ERROR E_USER_WARNING E_USER_NOTICE

32 64 128 256 512

1024

2048

E_STRICT

ENI Editions - All rigths reserved

- 1-

4096

E_RECOVERABLE_ERROR

lerreurnestpasgreparle dveloppeur(voirplusloin),le scriptsinterrompt.Ajouten version5.2.0. Toutesleserreurset avertissements(sommedes niveauxprcdents),lexception deE_STRICT.Enversion5,E_ALL valait2047:toutesleserreurset avertissements,lexceptionde E_STRICTetE_RECOVERABLE_ERROR.

6143

E_ALL

Exemplederreurfatale <?php $fichier = f o p e (/tmp/info.txt,r); $texte = fread($fichier,100); fclose($fichier); ?> Rsultat F a t a l e r r o r : Call to undefined function: fope() in / a p p / s c r i p t s / i n d e x . p h p on line 2 Exemplesdalerte <?php $fichier = fopen( / t m p / i n f o s . t x t ,r); $texte = fread($fichier,100); fclose($fichier); ?> Rsultat W a r n i n g : fopen(/tmp/infos.txt) [function.fopen]: failed to open stream: No such file or directory in / a p p / s c r i p t s / i n d e x . p h p on line 2 W a r n i n g : fread(): supplied argument is not a valid stream resource in / a p p / s c r i p t s / i n d e x . p h p on line 3 W a r n i n g : fclose(): supplied argument is not a valid stream resource in / a p p / s c r i p t s / i n d e x . p h p on line 4 Exemplederreurdanalyse <?php echo Bonjour !<br /> echo Bienvenue !<br />; ?> Rsultat P a r s e e r r o r : syntax error, unexpected T_ECHO, expecting , or ; in / a p p / s c r i p t s / i n d e x . p h p on line 3

// pas de point virgule !

- 2-

ENI Editions - All rigths reserved

Lesfonctionsdegestiondeserreurs
PHPproposeplusieursfonctionspermettantdegrercorrectementleserreursdansunscript : Nom Rle DfinitlesniveauxderreurquisontaffichsparPHP. Envoieunmessagederreurversunedestination(fichierpar exemple). Indiquelenomdunefonctionutilisateurutilisercomme gestionnairederreurs. Ractivelanciengestionnairederreurs. Dclenchentuneerreurdfinieparledveloppeur (user_errorestunaliasdetrigger_error). Retournedesinformationssurladernireerreurrencontre danslescript.

error_reporting error_log set_error_handler restore_error_handler trigger_error, user_error error_get_last

En complment, loprateur @,placdevantlenomdunefonction,permetdesupprimerlaffichagedesmessagesgnrsencas derreurdanslafonction. Exemple <?php $fichier = @fopen( / t m p / i n f o s . t x t ,r); $texte = @fread($fichier,100); @fclose($fichier); ?> Lorsdelexcutiondecescript,aucunmessagenestaffichbienquelefichierdemandnexistepas. Silerreurprovoquelarrtduscript,lutilisationdeloprateur @nychangerien lapageafficheestalorsvideouincomplte,et aucunmessagenestaffichlutilisateur.Ilconvientdoncdetesterlersultatdesfonctions,oudutiliserungestionnairederreurs, afindecontrlerledroulementduprogrammeetdefairelestraitementsncessaires. error_reporting Lafonctionerror_reportingpermetdedfinirlesniveauxderreurpourlesquelsleprogrammelaissePHPafficherlesmessages. Syntaxe entier error_reporting([ entier niveaux]) niveaux NiveauxderreuraffichsparPHP,exprimssouslaformedunesommedesvaleursaffecteschaqueniveau. Lafonction error_reportingretournelanciennevaleur.Appelesansparamtre,cettefonctionsecontentederetournerlavaleur courantesansrienchanger. Pourdfinirlesniveauxsouhaits,ilestvivementconseill,pourlacompatibilitfuture,dutiliserlesconstantesetdenepasmettre lesvaleursendurdansleprogramme. LaconstanteE_ALL,galelasommedetouteslesautresconstantes(sauf E_STRICT)peuttreutilisepourdemanderlaffichage detouslesniveauxderreur. Inversement,unniveaugal0provoquelasuppressiondelaffichagedetouslesmessages cestlquivalent,pourlensembledu script,deloprateur@quipeuttreutilissurunefonction. Telles que les valeurs de niveaux derreur sont dfinies, spcifier plusieurs niveaux se fait trs simplement par des oprations arithmtiquessurlesconstantes. Exemple E_ERROR+E_WARNING NiveauxE_ERRORetE_WARNING E_ALL-E_USER_ERROR-E_USER_WARNING-E_USER_NOTICE

ENI Editions - All rigths reserved

- 1-

TouslesniveauxsaufE_USER_ERROR,E_USER_WARNING,etE_USER_NOTICE Lavaleurpardfaut(toutsaufE_NOTICE=E_ALL-E_NOTICE)estdfinieparladirectivedeconfigurationerror_reporting. En complment, la directive de configuration display_errors permet dautoriser (on) ou dinterdire (off) laffichage des messages derreur si display_errorsest off,donnerunevaleurquelconque error_reporting(danslefichier inioudansunscript)est sanseffet. Enphasededveloppement,ilestconseilldaffichertoutesleserreurs(E_ALL),ycomprislesavertissements,afindcrireuncode leplusproprepossible. Exemple <?php // Valeur courante de error_reporting. echo <b>error_reporting = ,error_reporting(),</b><br />; // Par dfaut gal tout sauf E_NOTICE = E_ALL - E_NOTICE. echo = E_ALL - E_NOTICE = ,(E_ALL-E_NOTICE),<br />; // Affichage dune variable non initialise. echo "\$x (non initialise) = $x => pas de message <br />"; // Passage de error_reporting E_ALL (tout) error_reporting(E_ALL); echo <b>error_reporting = E_ALL</b><br />; // Affichage dune variable non initialise. echo "\$x (non initialise) = $x => message <br />"; // Lecture dun fichier qui nexiste pas. if (! readfile( / t m p / i n f o s . t x t )) { echo Erreur dans readfile => message<br />; }; // Passage de error_reporting 0 (rien). error_reporting(0); echo <b>error_reporting = 0</b><br />; // Lecture dun fichier qui nexiste pas. if (! readfile( / t m p / i n f o s . t x t )) { echo Erreur dans readfile => plus de message<br />; }; ?> Rsultat error_reporting = 6135 = E_ALL - E_NOTICE = 6135 $x (non initialise) = => pas de message error_reporting = E_ALL Notice: Undefined variable: x in / a p p / s c r i p t s / i n d e x . p h p on line 1 2 $x (non initialise) = => message W a r n i n g : readfile(/tmp/infos.txt) [function.readfile]: failed to open stream: No such file or directory in / a p p / s c r i p t s / i n d e x . p h p on line 1 4 Erreur dans readfile => message error_reporting = 0 Erreur dans readfile => plus de message En gnral, une fois en production, il est conseill de dsactiver laffichage des messages derreur (soit par une directive de configuration,soitparunappel error_reporting(0)audbutdechaquescriptpourtreindpendantdelaconfiguration).Cette inhibition des messages derreurs, justifie dune part pour des raisons de scurit (les messages derreurs PHP rvlent des informationssurlarborescenceduserveur)permetgalementdaffichersoimmedesmessagespropres. error_log Lafonctionerror_logpermetdenvoyerunmessagederreurversunedestinationdonne. Syntaxe entier error_log( chane message, entier type_destination, [ chane destination[, chane complment]) message Messageenvoyer type_destination Typededestination :0 :historiquePHP1 :adresseemail2 :postededboggage3 :fichier destination

- 2-

ENI Editions - All rigths reserved

Prciseladestinationpourlestypes13 :1 :adresseemail2 :adresse(IPounom)dupostedistantetventuellementnumro deport3 :nomdufichier(crautomatiquementsilnexistepas) complment Entte(s)complmentaire(s)envoyerdanslemessagedanslecas1(voirlafonctionmaildanslechapitreUtiliserlesfonctions PHPEnvoyeruncourrierlectronique) Lafonctionerror_logretourneTRUEsilemessageaputreenvoyetFALSEdanslecascontraire. Pourletype0(historiquePHP),lefichierdedestinationestdfiniparladirectivedeconfigurationerror_log. iladirectivedeconfiguration log_errorseston,lesmessagessontsystmatiquementcritsdanslefichierspcifiparla S directiveerror_log,sansquilsoitncessairedappelerlafonctionerror_log.

Le type de destination 2 permet de mettre en place une console de dboggage sur un poste distant du serveur. Dans les grandeslignes,unpetitprogrammedoittredvelopp(enC,C++,VisualBasic...)surleposteenquestion,pourrcuprer,surun socket,lesinformationsenvoyesparleprogrammePHP.Cettepossibilitneserapastudieplusendtaildanscetouvrage. Exemple <?php // Pas daffichage des erreurs dans le script. error_reporting(0); // Lecture dun fichier qui nexiste pas. $nom_fichier = /tmp/infos.txt; if (! readfile($nom_fichier)) { // Ecriture dun message derreur dans un fichier de trace // spcifique lapplication error_log("Impossible de lire le fichier $nom_fichier.\n", 3,/app/logs/monApplication.log); // Affichage dun message pour lutilisateur. echo Votre requte ne peut pas aboutir ; , essayez de nouveau plus tard.; }; ?> RsultatdanslefichiermonApplication.log Impossible de lire le fichier /tmp/infos.txt. Rsultatdanslenavigateur Votre requte ne peut pas aboutir ; essayez de nouveau plus tard. La fonction error_log est pratique, en phase de test ou de production, pour conserver la trace dune erreur quelque part. Cependant,elleneremplacepaslaffichagedunmessageexplicitepourlutilisateur. set_error_handler Lafonction set_error_handlerpermetdespcifierlenomdunefonctionutilisateurquidoittreappelepourgrerleserreursde faoncentralise. Syntaxe chane set_error_handler( chane fonction[, entier niveaux]) Avec fonction Nomdelafonctionchargedegrerleserreurs niveaux Niveauxderreurconcerns(apparuenversion5) Lafonction set_error_handlerretournelenomdelanciennefonctionchargedelagestiondeserreurs(chanevidesilnyenavait pas)ouFALSEencasderreur. Lafonctiondegestiondeserreursdoitaccepterauminimumdeuxparamtres,lepremierpourleniveaudelerreuretledeuxime pourlemessagederreur.Troisparamtressupplmentairespeuventtrespcifispourlenomdufichierdanslequellerreurest apparue,lenumrodelaligneolerreuratgnreetlecontextedelerreur(tableaudetouteslesvariablesquiexistaientau momentdelerreur).

ENI Editions - All rigths reserved

- 3-

partirdumomentoungestionnairederreursestspcifi,plusaucunmessagenestaffichparPHP,quellequesoitlavaleurde error_reporting. De plus, par dfaut, le gestionnaire derreurs est appel pour toutes les erreurs, quel que soit leur niveau et quellequesoitlavaleurdeerror_reporting.Leparamtreniveauxpermetdespcifierlesniveauxconcerns.LesniveauxE_ERROR, E_PARSE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERRORetE_COMPILE_WARNINGnepeuventpastregrsdecettefaon. Exemple <?php // Dfinir le gestionnaire derreurs. function gestionnaire_erreurs ($niveau,$message,$fichier,$ligne) { // Afficher le fichier concern, avec le numro de ligne. echo "Fichier = $fichier<br />"; echo "Ligne = $ligne<br />"; // Afficher le niveau et le message. echo "Niveau = $niveau <br />"; echo "Message = $message<br />"; } // Spcifier le gestionnaire utiliser. set_error_handler(gestionnaire_erreurs); // Gnrer une erreur. readfile(/tmp/infos.txt); // Afficher un message de fin. echo Fin; ?> Rsultat Fichier = /app/scripts/index.php Ligne = 15 Niveau = 2 Message = readfile(/tmp/infos.txt) [function.readfile]: failed to open stream: No such file or directory Fin Cet exemple montre que si lerreur ne provoque pas linterruption du script, ce dernier se poursuit aprs lappel au gestionnaire derreurs il est donc de sa responsabilit, darrter lexcution du script, laide de linstruction exit ou de la fonction die (cf. chapitreIntroductionPHPLesbasesdulangagePHP). Exemple <?php // Dfinir le gestionnaire derreurs. function gestionnaire_erreurs ($niveau,$message,$fichier,$ligne) { // Afficher le fichier concern, avec le numro de ligne. echo "Fichier = $fichier<br />"; echo "Ligne = $ligne<br />"; // Afficher le niveau et le message. echo "Niveau = $niveau <br />"; echo "Message = $message<br />"; // I n t e r r o m p r e l e s c r i p t exit; } // Spcifier le gestionnaire utiliser. set_error_handler(gestionnaire_erreurs); // Gnrer une erreur. readfile(/tmp/infos.txt); // Afficher un message de fin. echo Fin; ?> Rsultat Fichier = /app/scripts/index.php Ligne = 15 Niveau = 2 Message = readfile(/tmp/infos.txt) [function.readfile]: failed to open stream: No such file or directory Danslegestionnairederreurs,ilestpossibledutiliser la fonction header(cf.chapitreGrerlesliensetlesformulairesavecPHP Aller sur une autre page) pour rediriger lutilisateur vers une page HTML ou un script PHP charg de laffichage des messages derreurs. Cettetechniqueesttrspratiquecarellepermetdecentraliserlagestiondeserreurs(lafonctionpeuttredfiniedansunfichier inclus)etdesparerclairementlecodechargdutraitementnormal,ducodechargdegrerleserreurs.

- 4-

ENI Editions - All rigths reserved

restore_error_handler La fonction restore_error_handler permet de restaurer lancien gestionnaire derreurs aprs un changement effectu avec set_error_handler. Syntaxe restore_error_handler() Exemple <?php // Dfinir un premier gestionnaire derreurs. function gestionnaire1 ($numro,$message) { // Affiche un simple message echo => gestionnaire n 1<br />; } // Dfinir un deuxime gestionnaire derreurs. function gestionnaire2 ($numro,$message) { // Affiche un simple message echo => gestionnaire n 2<br />; } // Dfinir une fonction qui gnre une erreur. function gnrer_erreur() { // Afficher un message. echo Gnrer une erreur<br />; // Lire un fichier qui nexiste pas. readfile(/tmp/infos.txt); } // Premire squence : pas de gestionnaire. echo <b>Pas de gestionnaire</b><br />; gnrer_erreur(); // Deuxime squence : gestionnaire numro 1. set_error_handler(gestionnaire1); echo <b>Utiliser le gestionnaire n 1</b><br />; gnrer_erreur(); // Troisime squence : gestionnaire numro 2. set_error_handler(gestionnaire2); echo <b> Utiliser le gestionnaire n 2</b><br />; gnrer_erreur(); // Quatrime squence : restaurer lancien gestionnaire. restore_error_handler(); echo <b>Premier restore_error_handler()</b><br />; gnrer_erreur(); // Cinquime squence : restaurer lancien gestionnaire. restore_error_handler(); echo <b>Deuxime restore_error_handler()</b><br />; gnrer_erreur(); ?> Rsultat Pas de gestionnaire Gnrer une erreur W a r n i n g : readfile(/tmp/infos.txt) [function.readfile]: failed to open stream: No such file or directory in / a p p / s c r i p t s / i n d e x . p h p on line 1 7 Utiliser le gestionnaire n 1 Gnrer une erreur => gestionnaire n 1 Utiliser le gestionnaire n 2 Gnrer une erreur => gestionnaire n 2 Premier restore_error_handler() Gnrer une erreur => gestionnaire n 1 Deuxime restore_error_handler() Gnrer une erreur W a r n i n g : readfile(/tmp/infos.txt) [function.readfile]: failed to open stream: No such file or directory in / a p p / s c r i p t s / i n d e x . p h p on line 1 7 Cetexempleillustrelapossibilitdempileretdedsempilerlesgestionnairesderreursgrceauxfonctions set_error_handleret restore_error_handler.

ENI Editions - All rigths reserved

- 5-

Si une partie dun script a besoin dun gestionnaire diffrent de celui utilis dans le reste du script, il suffit dappeler set_error_handleraudbutdelasectionconcernepourdfinirlegestionnairepuis restore_error_handlerlafindelasection pourremettrelancien. Par ailleurs, il faut noter que le gestionnaire par dfaut, cestdire celui de PHP, est systmatiquement replac la fin de lexcutiondunscript ilnestdoncpasncessairedappelerrestore_error_handlerenfindescript. trigger_error(ousonaliasuser_error) Lafonction trigger_errorpermetdedclencheruneerreurdfinieparledveloppeurcommesicetteerreuravaittdclenche nativementparPHP. Syntaxe trigger_error( chane message, entier niveau) message Messagedelerreur. niveau NiveaudelerreurparmiE_USER_EROR,E_USER_WARNINGetE_USER_NOTICE(touteautrevaleurgnreuneerreur !) Lerreur dclenche par trigger_error est traite par le gestionnaire interne de PHP (affichage du message) ou le gestionnaire ventuellement dfini par set_error_handler. Dans le premier cas, le script est interrompu si le niveau de lerreur est gal E_USER_ERROR (sinon il se poursuit). Dans le deuxime cas, le script se poursuit quel que soit le niveau de lerreur (cest au gestionnairedinterromprelescriptsibesoin). Exempleaveclegestionnaireinterne <?php // Dclencher une erreur E_USER_NOTICE. trigger_error(*** mon message ***,E_USER_NOTICE); // Dclencher une erreur E_USER_WARNING. trigger_error(*** mon message ***,E_USER_WARNING); // Dclencher une erreur E_USER_ERROR. trigger_error(*** mon message ***,E_USER_ERROR); // Afficher un message de fin. echo Fin; ?> Rsultat N o t i c e : *** mon message *** in / a p p / s c r i p t s / i n d e x . p h p on line 3 W a r n i n g : *** mon message *** in / a p p / s c r i p t s / i n d e x . p h p on line 5 F a t a l e r r o r : *** mon message *** in / a p p / s c r i p t s / i n d e x . p h p on line 7 Cetexemplemontrequelesdeuxpremireserreurs(niveauxE_USER_NOTICEetE_USER_WARNING)neprovoquentpaslarrtduscript, ladiffrencedelatroisime(niveauE_USER_ERROR). Exempleavecungestionnaireexterne <?php // Dfinir le gestionnaire derreurs. function gestionnaire_erreurs($niveau,$message) { // Afficher simplement le niveau et le message. echo "Niveau = $niveau <br />"; echo "Message = $message<br />"; // Ne pas interrompre le script. // exit; } // Spcifier le gestionnaire utiliser. set_error_handler(gestionnaire_erreurs); // dclencher une erreur E_USER_NOTICE trigger_error(*** mon message ***,E_USER_NOTICE); // dclencher une erreur E_USER_WARNING trigger_error(*** mon message ***,E_USER_WARNING); // dclencher une erreur E_USER_ERROR trigger_error(*** mon message ***,E_USER_ERROR); // afficher un message de fin echo Fin; ?>

- 6-

ENI Editions - All rigths reserved

Rsultat Niveau = 1024 Message = *** mon message *** Niveau = 512 Message = *** mon message *** Niveau = 256 Message = *** mon message *** Fin

error_get_last Lafonctionerror_get_lastretournedesinformationssurladernireerreurrencontredanslescript.Cettefonctionestapparueen version5.2.3. Syntaxe tableau error_get_last() Lafonctionerror_get_lastretourneuntableauassociatifcontenantlesclstype,message,fileetline. Exemple <?php // Gnrer une erreur (sans lafficher : @...). @readfile(/tmp/infos.txt); // Poursuivre le script. echo suite ...<br />; // Afficher des informations sur la dernire erreur. foreach (error_get_last() as $cl => $valeur) { echo "$cl => $valeur<br />"; } ?> Rsultat suite ... type => 2 message => readfile(/tmp/infos.txt) [function.readfile]: failed to open stream: No such file or directory file => /app/scripts/index.php line => 3

Lavariable$php_errormsg Si la directive de configuration track_errors est on, le message de la dernire erreur est disponible dans la variable $php_errormsg. Lutilisationdecettevariabledirectementdansunscriptestunsubstitutpossiblelamiseenplacedungestionnairederreurs. lexistedenombreusesdirectivesdeconfigurationrelativesauxerreurs,enplusdecellesprsentesdanscechapitre.Pour I plusdinformations,reportezvousladocumentationdePHP.

ENI Editions - All rigths reserved

- 7-

Vuedensemble
1.Introduction
DanslessitesWebdynamiquesetinteractifs,ilesttrssouventncessairedinteragiraveclutilisateur. EnHTML,ilexisteprincipalementdeuxmthodespourinteragiravecunutilisateur:
q

lesliens(balise<a>) lesformulaires(balise<form>).

DesscriptsPHPpeuventtreutilisspourtraiterleclicdelutilisateursurunlienoulasaisiedelutilisateurdansun formulaire.

2.Lesliens
Lelienestlatechniquedebasequipermetunutilisateurdenaviguerentrelesdiffrentespagesdunsite. UnlienHTMLestdfinientrelesbalises<a>et</a>. Syntaxesimplifie <a [ action="url" ] [ id="identifiant_lien" ] [ target="cible" ] > ... </a> Lesattributsdelabalise<a>sontlessuivants : action URL(UniformResourceLocator)relativeouabsoluequiestappeleparlelien,encequinousconcerne,unscriptPHP. id Identifiantdulien.SilapageHTMLcontientplusieursliens,lidentifiantpermetdelesdiffrencier.Encequinous concerne,cetidentifiantneprsentepasdintrtcarilnestpasrcuprdanslescriptdetraitementdulien.Par contre,ilpeuttreutilisctclient,enJavaScriptparexemple. target Cible(parexempleuneautrefentre)danslaquelleouvrirlURLcible.Pardfaut,lURLciblesaffichedanslamme fentre. LURLpeutcontenirdesparamtresquipermettentdepasserdesinformationsdunepageuneautre. Syntaxe url_classique?nom=valeur[&...] Lepointdinterrogation(?)introduitlalistedesparamtresdelURLsparsparlecaractreperluette( &) chaque paramtreestconstituparuncouplenom/valeursouslaformenom=valeur : www.monsite.com/info/accueil.php?prenom=Olivier chercher.php?prenom=Olivier&nom=HEURTEL Exemple

ENI Editions - All rigths reserved

- 1-

Scriptpage1.php

<?php // Initialisation dune variable. $nom=Olivier; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <!-- lien vers la page 2 en passant la valeur de $nom dans lURL --> <a href=" p a g e 2 . p h p ? n o m = < ? p h p e c h o $ n o m ; ? > ">Page 2</a> </div> </body> </html>
q

Sourcedelapagedanslenavigateur

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <!-- lien vers la page 2 en passant la valeur de $nom dans lURL --> <a href=" p a g e 2 . p h p ? n o m = O l i v i e r ">Page 2</a> </div> </body> </html>
q

Scriptpage2.php

<?php echo "Page 2 - Bonjour $ n o m "; ?> Rsultat


q

Affichagedelapage1

Rsultatduclicsurlelien

- 2-

ENI Editions - All rigths reserved

Pourlinstant,aucunnomnestaffichdansladeuximepage.Lavariable $nomdfiniedanslescript page1.phpnest pasdisponibledanslescript page2.php(cf.chapitreIntroductionPHPLesbasesdulangagePHPsurlaporteetla duredeviedesvariables).Deplus,notrescriptnecontientaucuneinstructionpermettantdercuprerlesdonnes passesdanslURL nousverronscommentprocderlasectionRcuprerlesdonnesduneURLoudunformulaire.

3.Lesformulaires
a.Petitrappelsurlesformulaires
Le formulaire est un outil de base indispensable pour les sites Web dynamiques puisquil permet lutilisateur de saisirdesinformationsetdoncdinteragiraveclesite. UnformulaireHTMLestdfinientrelesbalises<form>et</form>. Syntaxesimplifie <form [ action="url_de_traitement" ] [ method="GET"|"POST" ] [ id="identifiant_formulaire" ] [ target="cible" ] > ... </form> Lesattributsdelabalise<form>sontlessuivants : action URLrelativeouabsolue(UniformResourceLocator)quivatraiterleformulaire,encequinousconcerne,unscriptPHP. CetattributestobligatoirepourseconformerlarecommandationXHTMLstricte. method Modedetransmissionversleserveurdesinformationssaisiesdansleformulaire.GET(valeurpardfaut) :les donnesduformulairesonttransmisesdanslURL.POST :lesdonnesduformulairesonttransmisesdanslecorpsde larequte. id Identifiantduformulaire.SilapageHTMLcontientplusieursformulaires,lidentifiantpermetdelesdiffrencier.Ence quinousconcerne,cetidentifiantneprsentepasdintrtcarilnestpasrcuprdanslescriptdetraitementdu formulaire.Parcontre,ilpeuttreutilisctclient,enJavaScriptparexemple. target Cible(parexempleuneautrefentre)danslaquelleouvrirlURLcible. Entrelesbalises<form>et</form>,ilestpossibledeplacerdesbalises<input>, <select>ou<textarea>pourdfinir deszonesdesaisies. Exemple(formulaireHTMLcomplet) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
ENI Editions - All rigths reserved - 3-

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Saisie</title> </head> <body> <form action=" " method="post"> <div> Nom : <input type="text" name="nom" value="" size="20" maxlength="20" /> Mot de passe : <input type="password" name="mot_de_passe" value="" size="20" maxlength="20" /> <br />Sexe : <input type="radio" name="sexe" value="M" />Masculin <input type="radio" name="sexe" value="F" />Feminin <input type="radio" name="sexe" value="?" checked="checked" />Ne sait pas <br />Photo : <input type="file" name="photo" value="" size="50" /> <br />Couleurs prfres : <input type="checkbox" name="couleurs[bleu]" />Bleu <input type="checkbox" name="couleurs[blanc]" />Blanc <input type="checkbox" name="couleurs[rouge]" />Rouge <input type="checkbox" name="couleurs[pas]" checked="checked" />Ne sait pas <br />Langue : <select name="langue"> <option value="E">Espagnol</option> <option value="F" selected="selected" >Francais</option> <option value="I">Italien</option> </select> <br />Fruits prfres :<br /> <select name="fruits[]" multiple="multiple" size="8"> <option value="A">Abricots</option> <option value="C">Cerises</option> <option value="F">Fraises</option> <option value="P">Pches</option> <option value="?" selected="selected"> Ne sait pas</option> </select> <br />Commentaire :<br /> <textarea name="commentaire" rows="4" cols="50"></textarea> <br /> <input type="hidden" name="invisible" value="123" /><br /> <input type="submit" name="soumettre" value="OK" /> <input type="image" name="valider" src="valider.gif" /> <input type="reset" name="effacer" value="Effacer" /> <input type="button" name="action" value="Ne fait rien" /> </div> </form> </body> </html> Rsultat

- 4-

ENI Editions - All rigths reserved

PHPpeutintervenirdeuxendroitsparrapportauformulaire :
q

pourlaconstructionduformulaire,sicedernierdoitcontenirdesinformationsdynamiques pourletraitementduformulaire(cestdiredesdonnessaisiesparlutilisateurdansleformulaire).

b.Construireunformulairedynamiquement
Commetoutlerestedelapage,toutoupartiedunformulairepeuttreconstruitdynamiquement.Troiscasseront abordsdansceparagraphe :
q

gnrerlatotalitduformulaire gnrerdesvaleursinitialesdansleszonesdesaisie gnrerunelistedoptions.

Gnrerlatotalitduformulaire Silexisteunedescriptionduformulairesousuneformeousousuneautre,ilestpossibledegnrerlatotalitdu formulaire. Dans lexemple simplifi suivant, nous supposons que nous rcuprons (dans un fichier, dans une base...) une description du formulaire sous la forme dun tableau deux dimensions : chaque ligne du tableau contient une descriptiondelazonesouslaformeduntableauavecletitre,letype,lenometlavaleur. <?php // Tableau contenant la description du formulaire. $formulaire = array( array(Nom : ,text,nom,HEURTEL), array(,submit,ok,OK) ); // Gnration du formulaire laide dune boucle // sur le tableau. echo <form action="saisie.php" method="POST">; foreach($formulaire as $zone) {

ENI Editions - All rigths reserved

- 5-

echo "$zone[0]<input type=\"$zone[1]\" ", "name=\"$zone[2]\" value=\"$zone[3]\"><br />"; } echo </form>; ?> Rsultatlcran

Rsultatdanslesourcedunavigateur <form action="saisie.php" method="POST">Nom : <input type="text" name="nom" value="HEURTEL"><br /><input type="submit" name="ok" value="OK"><br /></form>

Gnrerdesvaleursinitialesdansleszonesdesaisie Nousavonsdjtudicettepossibilitdansdiffrentsexemples. Exemple <form action="saisie.php" method="POST"> Nom : <input type="text" name="nom" value=" < ? p h p e c h o $ n o m ? > "><br /> <input type="submit" name="ok" value="OK"> </form> Ici,noussupposonsque$nomestunevariableinitialiseparailleursdanslescriptPHP. Gnrerunelistedoptions DucodePHPpeuttreutilispourgnrerdeslistesdoptions,soitdansunezone<select>(listeslectionunique ou multiple), soit une zone <input> de type radio (groupe de boutons radio) soit dans une zone <input> de type checkbox(casescocher). Lesdonnesaffichesproviennenttrssouventdunebasededonnesetilestintressantdepouvoirconstruire cettezoneduformulairedynamiquementpartirdesdonnesextraitesdelabase. Exempleavecunelisteslectionmultiple <?php // Liste des fruits afficher dans la liste, sous la // forme dun tableau associatif donnant le code du // fruit (cl du tableau) et lintitul du fruit. $fruits_du_march = array( A => Abricots, C => Cerises, F => Fraises, P => Pches, ? => Ne sait pas); // Liste des fruits prfrs de lutilisateur, sous la // forme dun tableau donnant le code des fruits concerns. $fruits_prfrs = array(A,F); // Remarque : nous verrons ultrieurement comment rcuprer // ces informations dans une base. ?> <!-- construction du formulaire --> <form action="saisie.php" method="POST"> Fruits prfrs :<br /> <select name="fruits[]" multiple size="8"> <?php // Code PHP gnrant la partie dynamique du formulaire. // Parcourir la liste afficher et rcuprer le code // et lintitul. foreach($fruits_du_march as $code => $intitul) {

- 6-

ENI Editions - All rigths reserved

// Dterminer si la ligne doit tre slectionne // - oui si le code figure dans la liste des fruits // prfrs de lutilisateur => recherche de $code // dans $fruits_prfrs avec la fonction in_array // - si cest le cas, mettre lattribut "selected" dans // la balise "option", sinon ne rien mettre. $slection = in_array($code,$fruits_prfrs)?selected="selected":; // Gnrer la balise "option" avec la variable $code pour // lattribut "value", la variable $slection pour // lindication de slection et la variable $intitul // pour le texte affich dans la liste. echo "<option value=\"$code\" $slection>$intitul</option>"; } ?> </select> </form> Rsultatlcran

Sourcedanslenavigateur <!-- construction du formulaire --> <form action="saisie.php" method="POST"> Fruits prfrs :<br /> <select name="fruits[]" multiple size="8"> <option value="A" selected="selected">Abricots</option><option value="C" >Cerises</option><option value="F" selected="selected">Fraises</option><option value="P" >Pches</option><option value="?" >Ne sait pas</option></select> </form> Cetexempleesttrsfacileadaptersilattributvaluenestpasutilis. Exempleavecunelisteslectionunique <?php // Liste des langues afficher dans la liste, sous la // forme dun tableau associatif donnant le code de // la langue (cl du tableau) et lintitul de la langue. $langues_disponibles = array( E => Espagnol, F => Franais, I => Italien); // Code de la langue de lutilisateur $langue = F; ?> <!-- construction du formulaire --> <form action="saisie.php" method="POST"> Langue :<br /> <select name="langue"> <?php // Code PHP gnrant la partie dynamique du formulaire. // Parcourir la liste afficher et rcuprer le code // et lintitul. foreach($langues_disponibles as $code => $intitul) {

ENI Editions - All rigths reserved

- 7-

// Dterminer si la ligne doit tre slectionne // - oui si le code est gal au code de la langue de // lutilisateur // - si cest le cas, mettre lattribut "selected" dans // la balise "option", sinon ne rien mettre $slection = ($code == $langue)?selected="selected":; // Gnrer la balise "option" avec la variable $code pour // loption "value", la variable $slection pour // lindication de slection et la variable $intitul // pour le texte affich dans la liste. echo "<option value=\"$code\" $slection>$intitul</option>"; } ?> </select> </form> Rsultatlcran

Sourcedanslenavigateur <!-- construction du formulaire --> <form action="saisie.php" method="POST"> Langue :<br /> <select name="langue"> <option value="E" >Espagnol</option><option value="F" selected="selected">Franais</option><option value="I" >Italien</option></select> </form> Destechniquessimilairespeuventtreutilisespourconstruireunelistedecasescocher,ungroupedeboutons radio,etc.

c.TraiterunformulairelaidedunscriptPHP
IlexisteprincipalementtroismthodespourtraiterunformulairelaidedunscriptPHP :
q

placerleformulairedansundocumentHTML"pur"(.htmou .html)etindiquerlenomduscriptquidoittraiter leformulairedanslattribut actiondelabalise <form> :danscecasleformulairenecontientaucunlment dynamique placer le formulaire dans un script PHP (par exemple, pour construire une partie du formulaire dynamiquement)etfairetraiterleformulaireparunautrescriptPHP(mentionndanslattribut actiondela balise<form>) Placer le formulaire dans un script PHP (par exemple, pour construire une partie du formulaire dynamiquement), et le faire traiter par le mme script PHP (mentionn dans loption action de la balise <form>).

Parailleurs,quelquepartsuruneautrepage,unlien(Saisieparexemple)peuttreinsrpourappelerleformulaire desaisie :
q

FormulaireHTML:

<a href=" s a i s i e . h t m ">Saisie</a>


q

FormulairePHP:

- 8-

ENI Editions - All rigths reserved

<a href=" s a i s i e . p h p ">Saisie</a>

Premiremthode DocumentHTMLsaisie.htm <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Saisie</title></head> <body> <form action="traitement.php" method="post"> <div> Nom : <input type="text" name="nom" value="" /> <input type="submit" name="ok" value="OK" /> </div> </form> </body> </html> ScriptPHPtraitement.php <?php /* A faire ... - rcuprer les informations saisies - faire le traitement - afficher une nouvelle page */ ?> Rsultat
q

Affichageinitialduformulaire :

Saisieduneinformation :

LersultatduclicsurleboutonOKestunepagevide,car,pourlinstant,lescriptdetraitementnefaitrien.

Deuximemthode DocumentPHPsaisie.php UnpeudecodePHP(engras)estutilispourgnrerunepartiedynamiqueduformulaire. <?php // Inclure un fichier qui contient des dfinitions de // constantes, dont le titre de la page (TITRE_PAGE_SAISIE). require(constantes.inc); // Initialisation dune variable qui contient la valeur // initiale de la zone de saisie (dans la pratique, cette // valeur vient sans doute dailleurs et nest pas code // en dur). $nom = X; // Dans le code HTML qui suit, inclusion de deux petits // bouts de code PHP pour afficher respectivement le titre // de la page et la valeur initiale de la zone de saisie. ?>

ENI Editions - All rigths reserved

- 9-

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> < ? p h p e c h o T I T R E _ P A G E _ S A I S I E ; ? > </title> </head> <body> <form action="traitement.php" method="post"> <div> Nom : <input type="text" name="nom" value=" < ? p h p e c h o $ n o m ; ? > " /> <input type="submit" name="ok" value="OK" /> </div> </form> </body> </html> ScriptPHPtraitement.php <?php /* A faire ... - rcuprer les informations saisies - faire le traitement - afficher une nouvelle page */ ?> Rsultat
q

Affichageinitialduformulaire(unevaleurinitialedynamiqueestproposepourlazonedesaisie) :

Saisieduneinformation :

LersultatduclicsurleboutonOKestunepagevide,car,pourlinstant,lescriptdetraitementnefaitrien.

Troisimemthode DocumentPHPsaisie.php Cest le mme script que prcdemment, en ayant simplement chang lattribut action de la balise <form> pour indiquerqueleformulairedoittretraitparlemmescriptsaisie.php. <?php // Inclure un fichier qui contient des dfinitions de // constantes, dont le titre de la page (TITRE_PAGE_SAISIE). require(constantes.inc); // Initialisation dune variable qui contient la valeur // initiale de la zone de saisie (dans la pratique, cette // valeur vient sans doute dailleurs et nest pas code // en dur). $nom = X; // Dans le code HTML qui suit, inclusion de deux petits // bouts de code PHP pour afficher respectivement le titre // de la page et la valeur initiale de la zone de saisie. ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>

- 10 -

ENI Editions - All rigths reserved

<title><?php echo TITRE_PAGE_SAISIE; ?></title> </head> <body> <form action=" s a i s i e . p h p " method="post"> <div> Nom : <input type="text" name="nom" value="<?php echo $nom; ?>" /> <input type="submit" name="ok" value="OK" /> </div> </form> </body> </html> Rsultat
q

Affichageinitialduformulaire(unevaleurinitialedynamiqueestproposepourlazonedesaisie) :

Saisieduneinformation :

Le rsultat du clic sur le bouton OK est la mme page de nouveau affiche, car, pour linstant,lescriptde traitementnefaitriendeplus :

Quechoisir ? Lechoixdetelleoutellemthodedpenddelacomplexitdusiteetdesprfrencesdechacun. Quelquesconsidrationsgnrales :


q

SparerlapageHTML(oulescriptPHPquignreleformulaire)duscriptPHPquiletraiteauninconvnient auniveaudelamaintenance :sidesmodificationssontapportesauformulaire,ilyadeuxfichiersmodifier (avecdesrisquesderreur,doubli). Inversement,sileformulairenaaucunepartiedynamique,lcriredansunfichierHTMLsparduscriptPHP quiletraitepermetdebiensparerlinterfaceutilisateur(lacouche"prsentation")dutraitement. Dans la pratique, pour faciliter la maintenance, il est souhaitable de dfinir certaines valeurs affiches plusieurs reprises (nom de socit par exemple) dans des constantes ou des variables et dutiliser ces constantes/variables dans les pages : toutes les pages deviennent un peu dynamiques et la troisime mthodenousparaitoptimale.

Danslasuitedecechapitre,nousallonsrentrerdansledtaildutraitementduformulaireenPHP,enutilisantdes exemplesconstruitssurlemodledelatroisimemthode.

4.RcuprerlesdonnesduneURLoudunformulaire
ladiffrencedesscriptsCGI,ilnypasbesoindefairedesanalysescomplexesdechanesdecaractres("parser") pourrcuprerlesvaleurspassesdansuneURLousaisiesparlutilisateurdansunformulaire cesvaleursvonttre rcuprestrssimplementdanslescriptdetraitement.

a.Premiremthode:lestableaux$_POST,$_GETet$_REQUEST
Par dfaut, toutes les zones de formulaire sont automatiquement enregistres dans le script PHP qui traite le

ENI Editions - All rigths reserved

- 11 -

formulaire, dans un tableau associatif $_POST pour les formulaires POSTet $_GETpourlesformulaires GET :lacldu tableauestgaleaunomdelazonedansleformulaire(option namedelabalise<input>,<select>ou <textarea>)et lavaleurgalelavaleursaisiedanslazone. Demme,touslesparamtresdelURLsontenregistrsdansletableauassociatif $_GET :lacldutableauestgale aunomduparamtreetlavaleurgalelavaleurpassedanslURL. Encomplment,cesinformationssontaussidisponiblesdansletableauassociatif$_REQUESTquiregroupelecontenu destableaux$_GETet $_POST(etnousleverronsplustarddutableau$_COOKIEquicontientdesinformationssurles cookies). es tableaux $_GET, $_POST et $_REQUEST sont apparus en version 4.1. Avant la version 4.1, $_GETet $_POST L sappelaient $HTTP_GET_VARS et $HTTP_POST_VARS, et $_REQUEST navait pas dquivalent. Pour des raisons de compatibilitascendante,cesvariables"longues"sonttoujoursdisponiblesconditiondepositionnerladirective deconfigurationregister_long_arrayon(offpardfaut).

Exempleavecunformulaire DocumentHTMLsaisie.htm <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Saisie</title></head> <body> <form action="traitement.php" method="post"> <div> Nom : <input type="text" n a m e = " n o m " value="" /> <input type="submit" name="ok" value="OK" /> </div> </form> </body> </html> ScriptPHPtraitement.php <?php // Affichage des informations contenues dans les // tableaux $_POST et $_REQUEST. echo $_POST[\nom\] -> , $ _ P O S T [ n o m ] ,<br \>; echo $_REQUEST[\nom\] -> , $ _ R E Q U E S T [ n o m ] ,<br \>; ?> Rsultat
q

Affichageinitialduformulaire

Saisiedunevaleur

RsultatduclicsurleboutonOK

$_POST[nom] -> Olivier $_REQUEST[nom] -> Olivier

ExempleavecuneURL Scriptpage1.php

- 12 -

ENI Editions - All rigths reserved

<?php // Initialisation dune variable. $nom=Olivier; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <!-- lien vers la page 2 en passant la valeur de $nom dans lURL --> <a href="page2.php? n o m = < ? p h p e c h o $ n o m ; ? > ">Page 2</a> </div> </body> </html> Scriptpage2.php <?php // Affichage des informations contenues dans les // tableaux $_GET et $_REQUEST. echo $_GET[\nom\] -> , $ _ G E T [ n o m ] ,<br \>; echo $_REQUEST[\nom\] -> , $ _ R E Q U E S T [ n o m ] ,<br \>; ?> Rsultat
q

Affichagedelapage1

Rsultatduclicsurlelien

$_GET[nom] -> Olivier $_REQUEST[nom] -> Olivier

b.Deuximemthode:lafonctionimport_request_variables
LesinformationspassesdansuneURLousaisiesdansunformulairepeuventtreautomatiquementimportesdans desvariablesPHPgrcelafonctionimport_request_variables. Syntaxe import_request_variables( chane types, chane prfixe) types Typedinformationdsire :Goug :informationsenvoyesparlamthodeGET Poup :informationsenvoyespar lamthodePOST Couc :informationsenvoyesparuncookie(cf.chapitreGrerlessessionsUtiliserdescookies). prfixe Prfixeajouterdevantlenomdelavariable.

ENI Editions - All rigths reserved

- 13 -

Lorsque cette fonction est appele dans le script de traitement dune URL, PHP cre une variable pour chaque paramtredelURL :lenomdelavariableestgalaunomduparamtredanslURLprcdduprfixe,etlavaleur delavariableestgalelavaleurpassedanslURL. Lorsquecettefonctionestappeledanslescriptdetraitementdunformulaire,PHPcreunevariablepourchaque zone du formulaire : le nom de la variable est gal au nom de la zone dans le formulaire prcd du prfixe, et la valeurdelavariableestgalelavaleursaisiedansleformulaire. LeprfixeestoptionnelmaisuneerreurdeniveauE_NOTICEestgnresilnestpasrenseign. Vous pouvez utiliser une combinaison des diffrentes lettres de types pour importer en une seule fois des informationsdoriginesdiffrentes.Parexemple,spcifierPGpermetdercuprerlesinformationsenvoyesparune mthodePOSTouparunemthodeGET. Exempleavecunformulaire DocumentHTMLsaisie.htm <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Saisie</title></head> <body> <form action="traitement.php" method="post"> <div> Nom : <input type="text" n a m e = " n o m " value="" /> <input type="submit" name="ok" value="OK" /> </div> </form> </body> </html> ScriptPHPtraitement.php <?php // Importer les informations du formulaire : // - mthode POST // - prfixe form_ import_request_variables(P,form_); // Afficher la variable importe. echo $form_nom = , $ f o r m _ n o m ,<br />; ?> Rsultat
q

Affichageinitialduformulaire

Saisiedunevaleur

RsultatduclicsurleboutonOK

$form_nom = Olivier

ExempleavecuneURL Scriptpage1.php <?php // Initialisation dune variable.


- 14 ENI Editions - All rigths reserved

$nom=Olivier; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <!-- lien vers la page 2 en passant la valeur de $nom dans lURL --> <a href="page2.php? n o m = < ? p h p e c h o $ n o m ; ? > ">Page 2</a> </div> </body> </html> Scriptpage2.php <?php // Importer les informations de lURL : // - mthode GET // - prfixe url_ import_request_variables(G,url_); // Afficher la variable importe. echo $url_nom = , $ u r l _ n o m ,<br />; ?> Rsultat
q

Affichagedelapage1

Rsultatduclicsurlelien

$url_nom = Olivier

c.Troisimemthode(nonrecommande)
La troisime mthode est non recommande car elle est dpendante dune directive de configuration et elle peut poserdesproblmesdeperformanceetdescurit.Elleestnanmoinsvoquebrivementdanscettepartiecar vouspouvezlarencontrerdansducodePHP"ancien". Si la directive de configuration register_globals est on, toutes les zones de formulaire sont automatiquement enregistres dans des variables dans le script PHP qui traite le formulaire. Les variables hritent du nom (attribut namedelabalise <input>, <select> ou <textarea>)delazonecorrespondanteduformulaire.Cecomportementest valablequellequesoitlamthode(GETouPOST). Demme,touteslesdonnesdelURLsontautomatiquementenregistresdansdesvariablesdanslescriptPHPqui traitelURL.LesvariableshritentdunomduparamtrecorrespondantdelURL.

d.Quechoisir ?
Unedesdeuxpremiresmthodes.

ENI Editions - All rigths reserved

- 15 -

LesvolutionssuccessivesdePHPvontdanslesensduneutilisationdestableaux$_POSTou$_GET,oudelafonction import_request_variables.Dansunefutureversion(la5.3ou6),ladirectivedeconfiguration register_globalssera dfinitivementpasse offetneserapasmodifiabledanslefichier php.ini.Dansunetellehypothse,latroisime mthodeneseraplusdisponible. LacommunautPHPconseillevivementdutiliserunedesdeuxpremiresmthodespourdesraisonsdescurit :en interrogeant le tableau adquat, ou en important explicitement les variables, on est certain que linformation vient biendelendroitprvuetquilnyapaseusubstitutionparunutilisateurmalintentionn. Dans la suite de ce chapitre, nous allons prsenter plus en dtail lutilisation de ces mthodes pour rcuprer des donnespassesdanslURLoudesdonnessaisiesdansunformulaire(utilisantlamthodePOST). es tableaux $_POST, $_GETet $_REQUEST sont des tableaux superglobaux. Ils sont disponibles dans tous les L contextesdexcution.

ans le chapitre Accder une base de donnes MySQL, aprs avoir vu dautres tableaux similaires, nous D feronsunepetitesynthsesurlesvariablesGPCS(Get/Post/Cookie/Session).

- 16 -

ENI Editions - All rigths reserved

RcuprerlesdonnespassesparlURL
1.Considrations
a.Quesepassetilsideuxparamtresportentlemmenom ?
CesttoutsimplementledernierparamtrerencontrdanslURLquifixelavaleur. Exemple <a href="page2.php? n o m =Olivier& n o m =Xavier">Page 2</a> Cette URL donne une seule variable nom gale Xavier dans le tableau $_GET ou lors de limport avec import_request_variables.

b.UtiliseruntableaupourpasserdesdonnesdanslURL
IlestpossibledutiliserunenotationdetypetableaudanslenomduparamtrepassdanslURL. Exemple <a href="page2.php? d a t a [ ] =HEURTEL& d a t a [ ] =Olivier">Page 2</a> CetteURLdonneunevariabledata,detypetableau,quicontientleslignessuivantes : Cl Valeur

0 1

HEURTEL Olivier

PHPremplitletableauenajoutantunelignepourchaqueparamtre,avecunindiceentierconscutifcommenant0 (commepourlanotation[]tudiedanslechapitreIntroductionPHPLesbasesdulangagePHP). Cettetechniqueestintressante,mais,danslecode,ilfautsavoirquelindice0correspondaunometlindice1au prnom.Parailleurs,unproblmepeutseprsentersilordredesparamtreschange. Pouramliorercettetechnique,ilestpossibledefixersoimmelacl,soitavecunnumro,soitavecunechanede caractres. Exemple <a href="page2.php? d a t a [ n o m ] =HEURTEL& d a t a [ p r n o m ] =Olivier"> Page 2</a> CetteURLdonnelersultatsuivantdansletableaudata : Cl Valeur

nom prnom

HEURTEL Olivier

2.Transmettredescaractresspciaux
Si la valeur transmettre ne contient pas de caractres spciaux (espace, perluette (&), point dinterrogation (?), etc.), elle peut tre place directement dans lURL comme indiqu prcdemment. Dans le cas contraire, il est ncessairedelencoderpourviterquecescaractresparticulierssoientmalinterprts. Parexemple,siladonnespassedanslURLcontient "Olivier & Xavier",seulOlivierserarcuprlarrivecar le&estinterprtcommelesparateurdeparamtres. Lencodagencessairepeuttreralistrsfacilementgrceauxfonctionsurlencodeourawurlencode.

ENI Editions - All rigths reserved

- 1-

Syntaxe chane urlencode( chane valeur) chane rawurlencode( chane valeur) valeur Chaneencoder. Ces deux fonctions retournent la chane aprs encodage. Lencodage consiste remplacer tous les caractres non alphanumriques par une squence %xy, xy tant un nombre hexadcimal gal au code ASCII du caractre. La diffrenceentrelesdeuxfonctionsestsubtileetconcernejustelecaractreespace :lafonction urlencoderemplace lesespacesparlecaractreplus(+),levraicaractre"plus"tantluimmeencod,alorsquelafonctionrawurlencode remplace les espaces par la squence %20 (code ASCII 32 en hexadcimal). La fonction urlencode est conforme au typeMIMEapplication/x-www-form-urlencoded(typeutilispourtransmettrelesvaleursdesformulaires)alorsquela fonctionrawurlencodeestconformelaRFC1738 apriori,ilfautpluttutiliserlafonctionrawurlencode. Exemple <?php // Initialisation dune variable. $nom=Olivier & Xavier; echo urlencode($nom),<br />; echo rawurlencode($nom),<br />; ?> Rsultat Olivier+%26+Xavier Olivier%20%26%20Xavier Exemplecomplet
q

Lescriptpage1.phppeuttremodifidelamaniresuivante :

<?php // Initialisation dune variable. $nom= O l i v i e r & X a v i e r ; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <!-- lien vers la page 2 en passant la valeur de $nom dans lURL --> <a href= " p a g e 2 . p h p ? n o m = < ? p h p e c h o r a w u r l e n c o d e ( $ n o m ) ; ? > "> Page 2</a> </div> </body> </html>
q

Sourcedelapagedanslenavigateur

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <!-- lien vers la page 2 en passant la valeur de $nom dans lURL --> <a href=" p a g e 2 . p h p ? n o m = O l i v i e r % 2 0 % 2 6 % 2 0 X a v i e r "> Page 2</a> </div>

- 2-

ENI Editions - All rigths reserved

</body> </html>
q

Scriptpage2.php

<?php // Affichage linformation passe dans lURL // (utilisation du tableau $_GET). echo $_GET[nom]; ?>
q

Rsultataffichlarrive

Olivier & Xavier Lachanedelarequtepeutaussitreconstruitelaidedelafonctionhttp_build_queryapparueenversion5. Syntaxe chane http_build_query( tableau donnes [, chane prfixe]) donnes Tableaucontenantlesdonnesutiliserpourconstruirelachanedelarequte.Lindiceoulacldutableausont utilisscommenomduparamtrepourlavaleurassocie. prfixe Prfixeutiliserpourlenomdesparamtres,lorsquilsagitdunindicenumrique.Permetdavoirlarriveunnom exploitablecommenomdevariable(unnomdevariablePHPnepeutpascommencerparunchiffre). Cettefonctionconstruit,puisencode,unechanederequtesouslaformecl1=valeur1&cl2=valeur2&...enutilisant lescls(ouindices)etvaleurstrouvesdansletableaudonnes.Silestsaisi,leparamtreprfixeestajoutdevant lesindicesnumriques. Exemple <?php // Initialisation du tableau contenant les donnes. $donnes=array(nom => Olivier & Xavier,David + Thomas); // Construction de la chane de la requte : // - sans prfixe echo http_build_query($donnes),<br />; // - avec prfixe echo http_build_query($donnes,v_),<br />; ?> Rsultat nom=Olivier+%26+Xavier& 0 =David+%2B+Thomas nom=Olivier+%26+Xavier& v _ 0 =David+%2B+Thomas

l existe deux fonctions, urldecode et rawurldecode, qui permettent de dcoder une chane pralablement I encode, respectivement par urlencode ou rawurlencode. Ces fonctions de dcodage nont pas besoin dtre appeles lorsque des donnes encodes sont transmises par lURL. En effet, ces donnes sont automatiquement dcodeslarrive.

ENI Editions - All rigths reserved

- 3-

Rcuprerlesdonnessaisiesdansleformulaire
1.Considrations
a.Quesepassetilsideuxzonesportentlemmenom ?
Cesttoutsimplementladernirezonerencontredansleformulairequifixelavaleur. Exemple <form action="saisie.php" method="POST"><div> Nom : <input type="text" name=" n o m "><br /> Prnom : <input type="text" name=" n o m "><br /> <input type="submit" name="ok" value="OK"> </div></form> La saisie de HEURTEL dans la premire zone et de Olivier dans la deuxime donne une seule variable gale Olivierdansletableau$_POSToulorsdelimportavecimport_request_variables.

b.QuesepassetilsilyadeuxformulairesdanslapageHTML ?
Lesvariablesneserontcresetrenseignesquepourleformulairequiatvalid. Exemple < f o r m action="saisie.php" method="POST"><div> Nom 1 : <input type="text" name=" n o m 1 "><br /> <input type="submit" name="ok1" value="OK1"> </div></form> < f o r m action="saisie.php" method="POST"><div> Nom 2 : <input type="text" name=" n o m 2 "><br /> <input type="submit" name="ok2" value="OK2"> </div></form> Si lutilisateur valide le premier formulaire, la variable nom1 sera disponible. Si lutilisateur valide le deuxime formulaire,cestlavariablenom2quiseradisponible

c.Utiliseruntableaupourrcuprerlesdonnessaisies
Ilestpossibledutiliserunenotationdetypetableaudanslattributnamedesbalises<input>,<select>et<textarea>. Exemple <form action="saisie.php" method="POST"><div> Nom : <input type="text" name=" s a i s i e [ ] "><br /> Prnom : <input type="text" name=" s a i s i e [ ] "><br /> <input type="submit" name="ok" value="OK"> </div></form> LasaisiedeHEURTELdanslapremirezoneetdeOlivierdansladeuximedonneuneseulevariablesaisie,detype tableau,quicontientleslignessuivantes : Cl Valeur

0 1

HEURTEL Olivier

PHPremplitletableauenajoutantunelignepourchaquezoneetavecunindiceentierconscutifcommenant0 (commepourlanotation[]tudiedanslechapitreIntroductionPHPLesbasesdulangagePHP). Cettetechniqueestintressante,mais,danslecode,ilfautsavoirquelindice0correspondaunometlindice1au prnom.Parailleurs,unproblmepeutseprsentersilordredeszoneschange.

ENI Editions - All rigths reserved

- 1-

Pouramliorercettetechnique,ilestpossibledefixersoimmelacl,soitavecunnumro,soitavecunechanede caractre. Exemple <form action="saisie.php" method="POST"><div> Nom : <input type="text" name=" s a i s i e [ n o m ] "><br /> Prnom : <input type="text" name=" s a i s i e [ p r n o m ] "><br /> <input type="submit" name="ok" value="OK"> </div></form> LasaisiedeHEURTELdanslapremirezoneetdeOlivierdonnelersultatsuivantdansletableausaisie : Cl Valeur

nom prnom

HEURTEL Olivier

Nousverronsultrieurementdessituationsocetypedenotationestobligatoire.

d.Passerdesinformationsdansunezonedeformulairecache
Lesinformationssaisiesdansunformulairesonttransmisesauscriptchargdutraitementetpouvantensuitetre affichesdansunenouvellepage. Cette mthode peut tre utilise pour transmettre au passage dautres informations non saisies par lutilisateur, typiquementenlesplaantdansunezonedeformulairecache. Exemple
q

Scriptpage1.php

<?php // Initialisation dune variable. $nom=Olivier & Xavier; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <!-- lien vers la page 2 avec un bouton de formulaire --> <form action="page2.php" method="post"> <!-- linformation transmettre est cache --> <input type="hidden" name="nom" value="<?php echo $nom; ?>" /> <input type="submit" name="page2" value="Page 2" /> </form> </div> </body> </html>
q

Sourcedelapagedanslenavigateur

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <!-- lien vers la page 2 avec un bouton de formulaire --> <form action="page2.php" method="post"> <!-- linformation transmettre est cache --> <input type="hidden" name="nom" value=" O l i v i e r & X a v i e r " /> <input type="submit" name="page2" value="Page 2" /> </form> </div>

- 2-

ENI Editions - All rigths reserved

</body> </html>
q

Scriptpage2.php

<?php // Affichage de linformation cache passe // dans le formulaire. echo $_POST[nom]; ?> Rsultat
q

Affichagedelapage1

Rsultatduclicsurlebouton

2.Lesdiffrentstypesdezone
a.Vuedensemble
PrenonsnotreformulairecompletdedpartetvoyonsquellessontlesinformationsrcupresdanslescriptPHP. Scriptsaisie.htm <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Saisie</title> </head> <body> <form action=" s a i s i e . p h p " method="post"> <div> Nom : <input type="text" name=" n o m " value="" size="20" maxlength="20" />

ENI Editions - All rigths reserved

- 3-

Mot de passe : <input type="password" name=" m o t _ d e _ p a s s e " value="" size="20" maxlength="20" /> <br />Sexe : <input type="radio" name=" s e x e " value=" M " />Masculin <input type="radio" name=" s e x e " value=" F " />Feminin <input type="radio" name=" s e x e " value=" ? " checked="checked" />Ne sait pas <br />Photo : <input type="file" name=" p h o t o " value="" size="50" /> <br />Couleurs prfres : <input type="checkbox" name=" c o u l e u r s [ b l e u ] " />Bleu <input type="checkbox" name=" c o u l e u r s [ b l a n c ] " />Blanc <input type="checkbox" name=" c o u l e u r s [ r o u g e ] " />Rouge <input type="checkbox" name=" c o u l e u r s [ p a s ] " checked="checked" />Ne sait pas <br />Langue : <select name=" l a n g u e "> <option value=" E ">Espagnol</option> <option value=" F " selected="selected" >Francais</option> <option value=" I ">Italien</option> </select> <br />Fruits prfrs :<br /> <select name=" f r u i t s [ ] " multiple="multiple" size="8"> <option value=" A ">Abricots</option> <option value=" C ">Cerises</option> <option value=" F ">Fraises</option> <option value=" P ">Pches</option> <option value=" ? " selected="selected"> Ne sait pas</option> </select> <br />Commentaire :<br /> <textarea name=" c o m m e n t a i r e " rows="4" cols="50"></textarea> <br /> <input type="hidden" name=" i n v i s i b l e " value=" 1 2 3 " /><br /> <input type="submit" name=" s o u m e t t r e " value=" O K " /> <input type="image" name=" v a l i d e r " src="valider.gif" /> <input type="reset" name=" e f f a c e r " value="Effacer" /> <input type="button" name=" a c t i o n " value="Ne fait rien" /> </div> </form> </body> </html> Scriptsaisie.php <?php // Inclusion dun fichier contenant des fonctions gnriques // (dont la fonction afficher_tableau dfinie dans le // chapitre 8) include(fonctions.inc) ; afficher_tableau($_POST,$_POST :); ?> Rsultat
q

Affichageinitialetsaisiedediffrentesvaleurs :

- 4-

ENI Editions - All rigths reserved

RsultatduclicsurleboutonOK(affichageducontenude$_POST) :

$_POST : nom = HEURTEL mot_de_passe = olivier sexe = M photo = identit.jpg couleurs = bleu = on rouge = on langue = F fruits = 0 = A 1 = F commentaire = Consultant en systme dinformation invisible = 123 soumettre = OK Surlabasedecetexemple,nousallonsapporterquelquesexplications.

b.Zonecontenantdutexte
Pourleszonescomportantdutexte,cestdireleszones <input>detypetext, password, fileet hidden,ainsique pourlazone<textarea>,lesvariablesassociescontiennentletextesaisi. Exemple $_POST : nom = HEURTEL mot_de_passe = olivier photo = identit.jpg commentaire = Consultant en systme dinformation invisible = 123

ourlinstant,aveclezonedetype file,nousavonsjustercuprlenomdufichier,paslefichierluimme P (cf.danscechapitrechangerunfichierentreleclientetleserveurTlchargerunfichierpartirduclient:

ENI Editions - All rigths reserved

- 5-

"fileupload").

c.Groupedeboutonsradio
Pouravoirungroupedeboutionsradio,leszonesdoiventporterlemmenom. Pourungroupedeboutonsradio,cestdirepourdeszones<input>detype radio,lavariableassociecontientla valeurcontenuedanslattributvaluedelabaliseinputduboutonslectionn.Silattributvalueestabsent,lavaleur pardfauteston,cequiestgnantpuisquilestalorsimpossibledeconnatreloptionslectionne.Danslapratique, ilfautrenseignerlattributvalue. Exemple <br />Sexe : <input type="radio" name=" s e x e " value=" M " /> Masculin <input type="radio" name=" s e x e " value=" F " /> Feminin <input type="radio" name=" s e x e " value=" ? " checked="checked" /> Ne sait pas Optionslectionne Rsultat $_POST : sexe = M

d.Casecocher
Pourdescasescocher,cestdirepourdeszones <input>detypecheckbox,lavariableassociecontientlavaleur contenuedanslattribut valuedelabalise input.Silattribut valueestabsent,lavaleurpardfauteston.Dansles deuxcas,lavariableassocieestdfinieuniquementpourlescasescoches. Exemple <br />Couleurs preferees : <input type="checkbox" name=" b l e u " value=" b "/> Bleu <input type="checkbox" name=" b l a n c " /> Blanc <input type="checkbox" name=" r o u g e " /> Rouge <input type="checkbox" name=" n e s a i t p a s " checked="checked" />Ne sait pas Optionsslectionnes Rsultat $_POST : bleu = b rouge = on Aveclacasecocher,lattribut valueagnralementmoinsdimportance, car il est possible de dterminer quune caseestcocheuniquementparlefaitquelavariableassocieaunevaleur(peuimportecettevaleur).Parcontre,il estimportantquechaquecasecocheraitunnomdiffrent. Plusieursapprochessontpossiblesvisvisdelavaleurdelattributvalue :
q

Lattribut value stocke la valeur souhaite au niveau de la logique applicative dans le cas o la case est coche(1,oui...),sachantque,silacasenestpascoche,lavariablenexistepas. Lattribut value est omis et le code interprte lexistence de la variable selon les besoins de la logique applicative.

- 6-

ENI Editions - All rigths reserved

Dans le code, si vous souhaitez rcuprer le fait dune case soit coche sous la forme dun boolen, vous pouvez crireuneinstructiondustyle : $case_est_coche = isset($_POST[nom_case])?TRUE:FALSE; Sivouslesouhaitez,vouspouvezutiliseruntableaupournepasavoirunevariableparcasecocher.Pourtreen mesurededterminerquellessontlescasescoches,vousavezdeuxpossibilits :
q

Utiliseruntableausansindicemaisrenseignerlattributvalue :

<br />Couleurs preferees : <input type="checkbox" name=" c o u l e u r s [ ] " value=" b l e u " /> Bleu <input type="checkbox" name=" c o u l e u r s [ ] " value=" b l a n c " /> Blanc <input type="checkbox" name=" c o u l e u r s [ ] " value=" r o u g e " /> Rouge <input type="checkbox" name=" c o u l e u r s [ ] " value=" n e s a i t p a s " checked="checked" />Ne sait pas
q

Nepasrenseignerlattributvaluemaisdfinirsoimmedesindicesoudesclsdansletableau :

// indices numriques <br />Couleurs preferees : <input type="checkbox" name=" c o u l e u r s [ 1 ] " /> <input type="checkbox" name=" c o u l e u r s [ 2 ] " /> <input type="checkbox" name=" c o u l e u r s [ 3 ] " /> <input type="checkbox" name=" c o u l e u r s [ 4 ] " checked="checked"

Bleu Blanc Rouge />Ne sait pas

// cls alphanumriques <br />Couleurs preferees : <input type="checkbox" name=" c o u l e u r s [ b l e u ] " /> Bleu <input type="checkbox" name=" c o u l e u r s [ b l a n c ] " /> Blanc <input type="checkbox" name=" c o u l e u r s [ r o u g e ] " /> Rouge <input type="checkbox" name=" c o u l e u r s [ n e s a i t p a s ] " checked="checked" />Ne sait pas Avec ce dernier exemple, si les cases "Bleu" et "Rouge" sont coches, le tableau couleur contiendra les lignes suivantes : $_POST : couleurs = bleu = on rouge = on Siuntableauestutilispourlensembleduformulaire,vouspouvezutiliserdiffrentessolutionsparmislesquelles :
q

Utiliseruntableausansindicemaisrenseignerlattributvalue :

<br />Couleurs preferees : <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ ] " <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ ] " <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ ] " <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ ] " checked="checked" />Ne
q

value=" b l e u " /> Bleu value=" b l a n c " /> Blanc value=" r o u g e " /> Rouge value=" n e s a i t p a s " sait pas

Nepasrenseignerlattributvaluemaisdfinirsoimmedesindicesoudesclsdansletableau :

// indices numriques <br />Couleurs preferees : <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ 1 ] " /> <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ 2 ] " /> <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ 3 ] " /> <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ 4 ] " checked="checked" />Ne sait // cls alphanumriques

Bleu Blanc Rouge pas

ENI Editions - All rigths reserved

- 7-

<br />Couleurs preferees : <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ b l e u ] " /> Bleu <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ b l a n c ] " /> Blanc <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ r o u g e ] " /> Rouge <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ n e s a i t p a s ] " checked="checked" />Ne sait pas Avec ce dernier exemple, si les cases "Bleu" et "Rouge" sont coches, le tableau saisie contiendra les lignes suivantes : $_POST : saisie = couleurs = bleu = on rouge = on

e.Listeslectionunique
Pour les listes slection unique, cestdire pour une zone <select> sans attribut multiple, la variable associe contient la valeur contenue dans lattribut value de la balise <option>, ou, silny a pas dattribut value, la valeur affichedanslaliste(derrirelabalise<option>). Exemple(avecattributvalue) <br />Langue : <select name=" l a n g u e "> <option value=" E ">Espagnol</option> <option value=" F " selected="selected" >Francais</option> <option value=" I ">Italien</option> </select> Optionslectionne Rsultat $_POST : langue = F Exemple(sansattributvalue) <br />Langue : <select name=" l a n g u e "> <option> E s p a g n o l </option> <option selected="selected" > F r a n c a i s </option> <option> I t a l i e n </option> </select> Optionslectionne Rsultat $_POST : langue = Franais Luneoulautredespossibilitspeuttrechoisieenfonctiondesbesoinsdelalogiqueapplicative.Souvent,loption valueestutilisepourmettreuncodequiserastockdanslabaselaplacedelavaleuraffiche.Cetteapproche prsentelinconvnientsuivant:lapartieinterfaceutilisateur(coucheprsentation)doitconnatrelescodes,cequi nestpasunebonneide.Lasolutionoptimaleconsistealorsgnrerdynamiquementleformulairepartirdela base.

f.Listeslectionmultiple
- 8 ENI Editions - All rigths reserved

Pourleslistesslectionmultiple,cestdirepourunezone <select> avec attribut multiple,lavariableassocie contient la valeur contenue dans lattribut value de la balise <option>, ou, silny a pas dattribut value, la valeur affiche dans la liste (derrire la balise <option>). Attention, ceci est valable uniquement pour la dernire option slectionne, si la variable est une variable scalaire. En consquence, pour une liste slection multiple, il faut obligatoirementutiliseruntableau. Exemple(avecattributvalue) <br />Fruits prfrs :<br /> <select name=" f r u i t s [ ] " multiple="multiple" size="8"> <option value=" A ">Abricots</option> <option value=" C ">Cerises</option> <option value=" F ">Fraises</option> <option value=" P ">Pches</option> <option value=" ? " selected="selected"> Ne sait pas</option> </select> Optionsslectionnes

Rsultat $_POST : fruits = 0 = A 1 = F Commenouslavonsdjvu,PHPremplitletableauavecunelignepourchaqueoptionslectionneetnumrotelui mmeleslignes.Danslecasdelalisteslectionmultiple,cemodedefonctionnementneposepasdeproblme. Exemple(sansoptionvalue) <br />Fruits prfrs :<br /> <select name=" f r u i t s [ ] " multiple="multiple" size="8"> <option>Abricots</option> <option>Cerises</option> <option>Fraises</option> <option>Pches</option> <option selected="selected"> Ne sait pas</option> </select> Rsultat(aveclammeslectionqueprcdemment) $_POST : fruits = 0 = Abricots 1 = Fraises Luneoulautredespossibilitspeuttrechoisieenfonctiondesbesoinsdelalogiqueapplicative(mmeprincipes quepourlalisteslectionunique). Utiliseruntableaupourlensembleduformulaireneposepasdeproblme. Exemple(avecattributvalue)

ENI Editions - All rigths reserved

- 9-

<br />Fruits prfrs :<br /> <select name=" s a i s i e [ f r u i t s ] [ ] " multiple="multiple" size="8"> <option value=" A ">Abricots</option> <option value=" C ">Cerises</option> <option value=" F ">Fraises</option> <option value=" P ">Pches</option> <option value=" ? " selected="selected"> Ne sait pas</option> </select> Rsultat(aveclammeslectionqueprcdemment) $_POST : saisie = fruits = 0 = A 1 = F

g.Boutondevalidation
Pourunboutondevalidation,cestdirepourunezone <input> de type submit,PHPcreunevariableportantle nomdubouton(attributname)etayantcommevaleur,lavaleurdelattributvalue,uniquementsileboutonestcliqu. Exemple <input type="submit" name=" s o u m e t t r e " value=" O K " /> Rsultat(sileboutonestcliqu) $_POST : soumettre = OK Sileboutonneportepasdenom,aucunevariablenestcre.Cenestpasgravesi :
q

Ilnestpasncessairedesavoircommentlescriptestappel(affichageinitialoutraitementduformulaire). Ilnyaquunseulboutondevalidation.

Danslesautrescas,ilfautnommerle(s)bouton(s). Pour faire la diffrence entre lappel du script pour affichage initial et lappel du script pour traiter le formulaire (cf. danscechapitreVuedensembleLesformulaires),ilsuffitdetesterlexistencedelavariable,parexempleavecla fonctionPHPisset. Exemple <?php ... // Tester comment le script est appel if (isset($_POST[soumettre])) { // Une ligne existe dans la variable $_POST // correspondant au bouton OK nomm soumettre : // le script est appel sur la validation du formulaire. // => Traiter le formulaire ... ... } else { // Le script nest pas appel par le clic sur le // bouton OK. Sil ny pas dautre bouton "submit", le // script est donc appel pour laffichage initial. // => Initialiser le formulaire ... ... } ?> Unproblmeseposesileformulairepossdeuneseulezonedetexte,aucunboutonetquelutilisateurtape ENTER ouRETURN.Danscecas,leformulaireestbiensoumismaisilnexistepasdeboutondevalidationpourraliserletest danslescriptPHP.Lasolutionconsistetestersilavariable $_POST(ou$_GET,ou $_REQUEST)estvideoupas(avec
- 10 ENI Editions - All rigths reserved

emptymaispasissetcarletableauexistetoujours). Si le formulaire contient deux boutons de validation nomms diffremment (attribut name), le premier ok et le deuximeannuler,ilestpossiblededterminerdansquelcontextelescriptestappel. Exemple // Tester comment le script est appel if (isset($_POST[ok])) { // bouton OK } elseif (isset($_POST[annuler])) { // bouton Annuler } else { // affichage initial } Sileformulairecontientdeuxboutonsdevalidationportantlemmenom(attribut name="soumettre"parexemple), maisdesvaleurs(attributvalue)diffrentes,lepremier OKetledeuximeAnnuler,ilestpossiblededterminerdans quelcontextelescriptestappel. Exemple // Tester comment le script est appel if ($_POST[soumettre] == OK) { // bouton OK } elseif ($_POST[soumettre] == Annuler) { // bouton Annuler } else { // affichage initial }

h.Boutonimage
Pourunboutonimage,cestdirepourunezone <input>detypeimage,PHPcredeuxvariablesportantlenomdu bouton (attribut name) suivi de _xet _y, et donnant la position relative, en pixels, du clic par rapport au coin haut gauche de limage (uniquement si limage est clique). Si le bouton ne porte pas de nom, les deux variables sont nommesxety. Exemple <input type="image" name=" v a l i d e r " src="valider.gif" /> Rsultat(silimageestclique) $_POST : valider_x = 5 valider_y = 8 Ilestalorspossibledetraiterlapositionduclicsielleestsignificativedupointdevuedelalogiqueapplicative. Siplusieursboutonsimagessontprsentsdansleformulaire,ilestpossiblededterminerquelboutonaprovoqula soumissionduformulaire. // Tester comment le script est appel if (isset($_POST[valider_x])) { // bouton Valider } else ...

i.Bouton"reset"ou"button"
Unclicsurdesboutonscorrespondantdeszones <input>detype resetou buttonneprovoquepaslasoumission duformulaire,nilappelduscriptdetraitement.Cesboutonspermettentdefaireunesimpleactionctnavigateur (enJavaScriptparexemple).

3.Synthse

ENI Editions - All rigths reserved

- 11 -

Il faut prendre lhabitude de bien nommer (attribut name) toutes les zones du formulaire avec des noms distincts ou dutiliserunnommagedetypetableau,pluttassociatif,pourfaciliterlamaintenanceetlalisibilitducode. Pourlesgroupesdeboutonsradio,ilfautmettreunattributvaluedistinctchaquebouton. Pourlescasescocher,ilfaututiliserdesnomsdistincts(attribut name),et/oudesvaleursdistinctes(attribut value), pourtrecertaindepouvoirfaireladiffrencelarrive encasdutilisationduntableaunelaissezpasPHPeffectuer lanumrotation(pasde[]). Pour les listes slection multiple, il faut utiliser un nommage de type tableau pour pouvoir rcuprer la liste des valeurs slectionnes employez lattribut value pour rcuprer une valeur diffrente de celle qui apparat dans la liste. De mme, Il faut nommer le(s) bouton(s) de validation pour tre en mesure de savoir comment le script PHP est appel.Siplusieursboutonssontutiliss,ilestpossibledemployerlemmenomdumomentquelesvaleurs(attribut value)sontdiffrentes. Le formulaire utilis tout au long de ce soustitre 2 est un bon exemple de lapplication de ces diffrentes recommandations. Mmeexempleavecuntableau <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Saisie</title> </head> <body> <form action=" s a i s i e . p h p " method="post"> <div> Nom : <input type="text" name=" s a i s i e [ n o m ] " value="" size="20" maxlength="20" /> Mot de passe : <input type="password" name=" s a i s i e [ m o t _ d e _ p a s s e ] " value="" size="20" maxlength="20" /> <br />Sexe : <input type="radio" name=" s a i s i e [ s e x e ] " value=" M " /> Masculin <input type="radio" name=" s a i s i e [ s e x e ] " value=" F " /> Feminin <input type="radio" name=" s a i s i e [ s e x e ] " value=" ? " checked="checked" /> Ne sait pas <br />Photo : <input type="file" name=" s a i s i e [ p h o t o ] " value="" size="50" /> <br />Couleurs prfres : <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ b l e u ] " />Bleu <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ b l a n c ] " />Blanc <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ r o u g e ] " />Rouge <input type="checkbox" name=" s a i s i e [ c o u l e u r s ] [ p a s ] " checked="checked" />Ne sait pas <br />Langue : <select name=" s a i s i e [ l a n g u e ] "> <option value=" E ">Espagnol</option> <option value=" F " selected="selected" >Francais</option> <option value=" I ">Italien</option> </select> <br />Fruits prfrs :<br /> <select name=" s a i s i e [ f r u i t s ] [ ] " multiple="multiple" size="8"> <option value=" A ">Abricots</option> <option value=" C ">Cerises</option> <option value=" F ">Fraises</option> <option value=" P ">Pches</option> <option value=" ? " selected="selected"> Ne sait pas</option> </select> <br />Commentaire :<br /> <textarea name=" s a i s i e [ c o m m e n t a i r e ] " rows="4" cols="50"></textarea> <br /> <input type="hidden" name=" s a i s i e [ i n v i s i b l e ] " value="123" /> <br />

- 12 -

ENI Editions - All rigths reserved

<input <input <input <input </div> </form> </body> </html>

type="submit" name=" s o u m e t t r e " value=" O K " /> type="image" name=" v a l i d e r " src="valider.gif" /> type="reset" name=" e f f a c e r " value="Effacer" /> type="button" name=" a c t i o n " value="Ne fait rien" />

Rsultat(aveclammesaisiequedanslexempleinitial) $_POST : saisie = nom = HEURTEL mot_de_passe = olivier sexe = M photo = identit.jpg couleurs = bleu = on rouge = on langue = F fruits = 0 = A 1 = F commentaire = Consultant en systme dinformation invisible = 123 soumettre = OK

ENI Editions - All rigths reserved

- 13 -

Contrlerlesdonnesrcupres
1.Vuedensemble
Dans la premire partie de ce chapitre, nous avons vu comment rcuprer les donnes passes dans une URL ou saisiesdansunformulaire. Ensuite,ilfautvrifierquelesdonnesrcupressontcorrectes,cestdirequellesrespectentlesrglesdegestion dfiniespourlapplication. ourlascuritdusite,ilconvientdtresuspicieuxvisvisdesdonnesquiviennentdelextrieur(formulaire, P URL,maisaussinousleverronsplustard,cookie,etc.).Cesdonnesdoiventtrecontrles,filtres,pourviter lesattaquespotentiellesdunutilisateurmalintentionn. LobjectifdecettepartieestdevousfournirquelquespistessurlestechniquescourammentutilisesenPHPpourcette vrification.Danslecasdunformulaire,uneautreapprochepossibleconsisteraliseruncontrleenJavaScriptdans lenavigateur,lintrttantdviterunallerretouravecleserveur. es diffrents exemples prsents dans cette partie utilisent des formulaires. Les mmes vrifications doivent L treeffectuessurlesdonnespassesdansuneURL.

2.Vrificationsclassiques
a.Nettoyagedesespacesquitranent
Lafonction trim(cf.chapitreUtiliserlesfonctionsPHP Manipulerleschanesdecaractres)peuttreutilisepour supprimer les "blancs" indsirables en dbut et/ou en fin de chane. Dans le cas dun formulaire, ce traitement sappliquenotammentauxzonesensaisielibre( <input>detypetextoupassword,<textarea>). Exemple // Rcuprer la valeur saisie dans la zone "nom" et nettoyer // les espaces qui tranent (au dbut et la fin) $nom = t r i m ($_POST[nom]);

b.Donneobligatoire
Testersiunedonneobligatoireestprsenteservletrssimple :ilsuffitdetestersilavariableassociecontient unevaleur. Exemple $nom = trim($_POST[nom]); if ( $ n o m = = ) { // $nom vide = zone "nom" non saisie => faire quelque chose }

c.Longueurmaximumdunechane
La longueur des donnes rcupres peut tre contrle avec la fonction strlen (cf. chapitre Utiliser les fonctions PHP Manipuler les chanes de caractres). Dans le cas dun formulaire, ce traitement sapplique notamment aux zonesensaisielibre( <input>detypetextoupassword,<textarea>). Exemple $nom = trim($_POST[nom]); if ( s t r l e n ( $ n o m ) > 2 0 ) { // $nom trop long => faire quelque chose }

ENI Editions - All rigths reserved

- 1-

Dansunformulaire,lattribut maxlengthdelabalise inputpermetdefaireuncontrlecomplmentaireaumomentde lasaisie(cestlenavigateurquisencharge).

d.CaractresautorisspourunechaneFormat
Encasdebesoin,lutilisationdesexpressionsrgulires(cf.chapitreUtiliserlesfonctionsPHPManipulerleschanes decaractres)permetdecontrlertrsfacilementqueseulscertainscaractressontprsentsetventuellementque lachanesaisierespecteunformatspcifique. titredexemple,supposonsquunmotdepassedoiventvrifierlarglesuivante :commencerparunelettre,suivie delettres,dechiffresoudescaractres_#*$avecunelongueurminimalede4. Exemple $mot_de_passe = trim($_POST[mot_de_passe]); if ( ! e r e g i ( ^ [ a - z ] [ a - z 0 - 9 _ # * $ ] { 3 , } , $ m o t _ d e _ p a s s e ) ) { // Mot de passe non valide. } Quelquesexplicationssurlexpressionrgulireutilise(^[a-z][a-z0-9_#*$]{3,}) :
q

eregiautoriseindiffremmentlesmajusculesetminuscules ^=commencepar... [a-z]=unelettreentreaetz(ouAetZcareregiestutilise)... [a-z0-9_#*$]{3,}=suividaumoins3({3,})caractresparmiceuxindiqus : a z(etdonc AZ), 0 9et lescaractres_#*$

Dautresexemplesserontprsentsdanslasuiteaveclesdatesetlesnombres.

e.ValiditdunedatePlagedevaleurs
Gnralement,deuxvrificationsdoiventtrefaitessurunedate
q

respectdunformat(JJ/MM/AAAAparexemple) validit(pasde32/13/2001).

Lavrificationdurespectduformatetdescaractresautorissesttrssimpleavecuneexpressionrgulire. Exemple $date_naissance = trim($_POST[date_naissance]); $format_date = ^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}$; if ( ! e r e g ( $ f o r m a t _ d a t e , $ d a t e _ n a i s s a n c e ) ) { // Mauvais format pour la date. } Quelquesexplicationssurlexpressionrgulireutilise(^([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})$) :
q

^=commencepar... [0-9]{1,2}=unoudeuxchiffres... /=suividucaractre"/"... [0-9]{1,2}=unoudeuxchiffres...

- 2-

ENI Editions - All rigths reserved

/=suividucaractre"/"... [0-9]{4}=suivide4chiffres... $=suivide...riendutout.Lachanedoitseterminerimmdiatement.

Pourvrifierlavaliditdeladate,ilestpossibledutiliserlafonction checkdate(cf.chapitreUtiliserlesfonctionsPHP Manipulerlesdates). Dansunpremiertemps,ilfautrcuprerlescomposantesdeladatesaisie.Plusieursmthodessontapplicables :


q

aveclafonctionexplode :

$jma = explode(/,$date_naissance); // $jma[0] contient le jour // $jma[1] contient le mois // $jma[2] contient lanne if ( ! c h e c k d a t e ( $ j m a [ 1 ] , $ j m a [ 0 ] , $ j m a [ 2 ] ) ) { // Date non valide. }
q

varianteaveclesfonctionsexplodeetlist :

list($jour,$mois,$anne) = explode(/,$date_naissance); // Rcupration des composantes dans des variables // indpendantes. if ( ! c h e c k d a t e ( $ m o i s , $ j o u r , $ a n n e ) ) { // Date non valide. }
q

avec le troisime paramtre de la fonction ereg qui permet de rcuprer des portions de la chane, et cela directementdansletestdeconformitduformat :

$format_date = ^ ( [0-9]{1,2} ) / ( [0-9]{1,2} ) / ( [0-9]{4} ) $; if ( ! e r e g ( $ f o r m a t _ d a t e , $ d a t e _ n a i s s a n c e , $ j m a ) ) { // Mauvais format pour la date . } else { // Bon format pour la date // $jma contient les diffrentes composantes avec des // indices diffrents par rapport lexemple prcdent : // $jma[ 1 ] contient le jour // $jma[ 2 ] contient le mois // $jma[ 3 ] contient lanne if (! checkdate($jma[ 2 ],$jma[ 1 ],$jma[ 3 ])) { // Date non valide. } } Pour tester la plage de valeurs, le plus simple est de faire une comparaison numrique (ou alphabtique) sur un nombre(unechane)construitsurlaformeAAAAMMJJ(20071211pourle11/12/2007). Exemple // Rcuprer les composantes de la date. list($jour,$mois,$anne) = explode(/,$date_naissance); // Contruire une chane au format AAAAMMJJ $aaaammjj = sprintf(%04d%02d%02d,$anne,$mois,$jour); // Dfinir les dates mini et maxi selon le mme format. $date_mini = 19000101; // 01/01/1900 $date_maxi = date(Ymd); // date du jour // Comparer. if ($aaaammjj < $date_mini or $aaaammjj > $date_maxi) { // Date hors de la plage autorise }

ENI Editions - All rigths reserved

- 3-

f.ValiditdunnombrePlagedevaleurs
Plusieurstechniquespeuventtreutilisespourvrifierquunnombreestbienform :
q

lesexpressionsrgulires lafonctionis_numeric laconversiondelasaisieetletestdursultatobtenu.

Exemplesaveclesexpressionsrgulires // Vrifier quune donne est un nombre entier. ereg(^[+|-]?[0-9]+$,$variable) // Vrifier quune donne est un nombre entier et contrler // le nombre de chiffres (entre 1 et 3 par exemple) ereg(^[+|-]?[0-9]{1,3}$,$variable) // Vrifier quune donne est un nombre dcimal (sur cet // exemple la virgule et le point sont accepts comme // sparateur dcimal). ereg(^[+|-]?[0-9] + [.|,]?[0-9]*$,$variable) Pourlaplagedevaleurs,unsimpletestdutypesuivantsuffit. Exemple if ($variable < minimum or $variable > maximum ) { // $variable en dehors de la plage autorise }

g.Validitduneadresseemail
Lencore,lesexpressionsrguliresvonttreutiles.DenombreuxexemplespeuventtretrouvssurInternet. Lasolutionsuivantefonctionnecorrectementpourlesstructuresdadressescourantes : eregi( ^[a-z0-9]+([._-]?[a-z0-9]+)*. // dbut @. // suite [a-z0-9]+([.-]?[a-z0-9]+)*\.[a-z]{2,4}$, // fin $adresse_mail ) Pourfaciliterlalecture,lexpressionrgulireestconstruiteparconcatnationdetroischanes. Quelquesexplicationssurlexpressionrgulireutilise :
q

eregipourautoriserindiffremmentlesmajusculesetlesminuscules. ^=commencepar... [0-9a-z]+=unesquencecomportantdeslettresoudeschiffres... ([._-]?[a-z0-9]+)* = suivi ventuellement dune ou plusieurs squences commenant chacune optionnellementparuntiret,unsoulignouunpointsuividelettresoudechiffres... @=suividun@... [0-9a-z]+=suividunesquencecomportantdeslettresoudeschiffres... ([.-]?[a-z0-9]+)* = suivi ventuellement dune ou plusieurs squences commenant chacune optionnellementparuntiretouunpointsuividelettresoudechiffres...

- 4-

ENI Editions - All rigths reserved

\.=suividunpoint... [a-z]{2,3}=suividedeuxquatrelettres... $=suivide...riendutout.Lachanedoitseterminer.

expression rgulire permet de vrifier que ladresse est syntaxiquement correcte, mais pas de contrler L quelleexisterellement.

ENI Editions - All rigths reserved

- 5-

Lesproblmessurlesdonnesrcupres
1.Lafonctionnalitde"magicquotes"
CommenouslavonsvudanslechapitreUtiliserlesfonctionsPHPGrerles"guillemetsmagiques"("magicquotes"), PHPproposeunefonctionnalit,appele"magicquotes"("guillemetsmagiques")quiprotgelesdonnessaisiesdans unformulaireoutransmisesdansuneURL. Pourmmoire,siladirectivedeconfiguration magic_quotes_gpcest on,touteslesdonnesarrivantparunemthode GETou POSTsontautomatiquementprotgesavecunantislash( \) devant les caractres apostrophe ( ),guillemet ("),antislash(\)etnul(\0). ConsidronslescriptPHPsaisie.phpsuivantquisecontentedafficherunezonedesaisiepuisderafficherensuitela valeursaisiedanslazoneduformulaireetdirectementdanslapage. <?php // Rcuprer la donne saisie. $saisie = isset($_POST[saisie])?$_POST[saisie]:; // La rafficher ensuite dans la zone de saisie et // directement dans la page. ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Saisie</title></head> <body> <form action="saisie.php" method="post"> <div> Saisie : <input type="text" name="saisie" value="<?php e c h o $ s a i s i e ; ?>" /> <input type="submit" name="ok" value="OK" /> <br /><?php e c h o $ s a i s i e ; ?> </div> </form> </body> </html> Rsultat
q

Affichageinitial :

Saisiedunevaleur :

RsultataprsunclicsurleboutonOKsimagic_quotes_gpc = on :

RsultataprsunclicsurleboutonOKsimagic_quotes_gpc = off :

UnproblmesimilairepeutseposeraveclesdonnestransmisesdanslURL.

ENI Editions - All rigths reserved

- 1-

Exemple
q

Scriptpage1.php :

<?php // Initialisation dune variable. $data="lt \ lhiver"; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <!-- lien vers la page 2 en passant la valeur dans lURL --> <a href= " p a g e 2 . p h p ? d a t a = < ? p h p e c h o r a w u r l e n c o d e ( $ d a t a ) ; ? > "> Page 2</a> </div> </body> </html>
q

Scriptpage2.php :

<?php // Affichage linformation passe dans lURL. echo $_GET[data]; ?>


q

Rsultataprsunclicsurleliensimagic_quotes_gpc = on :

l\t \\ l\hiver Pourseconformerlastratgiequiconsistenepasavoirdedonneprotgedanslesvariables(cf.chapitreUtiliser les fonctions PHPGrerles"guillemetsmagiques"("magicquotes")),ilfautsystmatiquementappelerunefonction lorsdelarcuprationdunedonneGPCpourenleverlaprotection"magicquotes"sicettedernireestactive. Exemple <?php function supprimer_encodage_MQ($valeur) { // Si magic quotes est actif, retourner la valeur aprs // la valeur aprs suppression de lencodage // (=> appel stripslashes), sinon, retourner // la valeur. return (get_magic_quotes_gpc())?stripslashes($valeur):$valeur; } ?>

ppelez cette fonction uniquement sur des donnes GPC pour ne pas risquer denlever des caractres A dchappementquinesontpaslisuneprotection"magicquotes". Larcuprationdesdonnesdunformulaireprendalorslalluresuivante : <?php // Inclusion du fichier qui contient les dfinitions de nos // fonctions gnrales include(fonctions.inc); // Rcupration des valeurs saisies dans le formulaire. $nom = s u p p r i m e r _ e n c o d a g e _ M Q (trim($_POST[nom])); $mot_de_passe = s u p p r i m e r _ e n c o d a g e _ M Q (trim($_POST[mot_de_passe])); $date_naissance =

- 2-

ENI Editions - All rigths reserved

s u p p r i m e r _ e n c o d a g e _ M Q (trim($_POST[date_naissance])); // ... ?> Pourleszonesquinesontpasensaisielibre(listeslectionuniqueoumultiple,groupedeboutonsradio,cases cocher),ilnestpasforcmentncessairedappelerlafonctioncarladonneretourneestmatriseetvouspouvez faireensortequellenecontiennepasdapostrophe dansledoute,appelezlasystmatiquement(enladaptantau casolavariableestuntableau). UnappelsimilairepeuttreeffectulorsdelarcuprationdesdonnestransmisesdansuneURL : <?php // Affichage linformation passe dans lURL. $nom = s u p p r i m e r _ e n c o d a g e _ M Q ($_GET[nom]); ?> Vouspouvezaussicrireunefonctionquisupprimesystmatiquementetenunseulappellaprotection"magicquotes" detouslestableauxGPC. Exemple function supprimer_encodage_MQ_GPC() { // Si magic quotes est actif ... if (get_magic_quotes_gpc()) { // Dfinir une fonction "strip_slashes" qui accepte un // paramtre par rfrence (important) et qui lui // applique la fonction "stripslashes". function strip_slashes(&$valeur) { $valeur = stripslashes($valeur); } // Appliquer cette fonction "strip_slashes" de faon // rcursive tous les tableaux GPC. array_walk_recursive($_POST, strip_slashes); array_walk_recursive($_GET, strip_slashes); array_walk_recursive($_REQUEST, strip_slashes); array_walk_recursive($_COOKIE, strip_slashes); } } LarcuprationdesdonnessaisiesdansunformulaireoutransmisesdansuneURLprendalorslalluresuivante : <?php // Inclusion du fichier qui contient les dfinitions de nos // fonctions gnrales. include(fonctions.inc); // Appel de la fonction qui supprime lencodage // "magic quotes" de tous les tableaux GPC. supprimer_encodage_MQ_GPC(); // Rcupration des valeurs saisies dans le formulaire. $nom = trim($_POST[nom]); $mot_de_passe = trim($_POST[mot_de_passe]); $date_naissance = trim($_POST[date_naissance]); // ... ?> Cettedeuximesolutionprsentedeuxavantages:
q

touteslesdonnesGPCsonttraitesenunseulappel lamigrationverslaversiondePHPquidsactiveradfinitivementlafonctionnalit"magicquotes"serafacilite (uneseulelignedecodesupprimer).

2.Autresproblmessurlesdonnesexternes
Unautreproblmedaffichagedansunezonedeformulairepeutseproduiresiladonneaffichecontientunguillemet (").

ENI Editions - All rigths reserved

- 3-

Exemple

Sourcedelapagedanslenavigateur(extrait) <form action="saisie.php" method="post"> <div> Saisie : <input type="text" name="saisie" v a l u e = " i l d i t : " b o n j o u r ! " " /> <input type="submit" name="ok" value="OK" /> <br />il dit : "bonjour !" </div> </form> EnHTML,danslesattributs(value,name...)desbalises,ledlimiteurdechaneestleguillemet.Danslattributvalue,la squence "il dit : "estconsidrecommelavaleurdelattributetlerestedelachaneestignor.Leproblmese produit mme si le guillemet est chapp par le caractre \ car ce dernier nest pas un caractre dchappementen HTML. UnautreproblmedaffichageseproduitdanslapagesiladonneaffichecontientdesbalisesHTML. Exemple

Lasaisie Olivier <b>Heurtel donne le mot Heurtel en gras lors de laffichage dans la page HTML. La squence <b> saisieparlutilisateurseretrouvetellequelledanslecodesourcedelapageetestdoncinterprteparlenavigateur commelabalisedemiseengras. Enfin,nouspouvonsrencontreruntroisimeproblmelorsdelasaisiedansunezonedecommentaire. Exemple

Unesaisiesurplusieurslignesdanslazone <textarea>estbienraffichetellequelledanslazonemaisestaffiche sanslessautsdelignesdanslapageHTML.Letexteestbienprsentavecdessautsdelignesdanslecodesourcede lapage,maislesautdeligne,endehorsdunezone<textarea>,nestpasinterprtparlenavigateur :ilfautmettre unebalise<br />. NousvoyonsdoncapparatretroisproblmesrelatifslaffichagedanslapageHTMLdedonnesenprovenancedune sourceexterne(formulaire,URL,etc.) :


q

prsence du caractre guillemet qui peut poser un problme lors de lutilisation de la donne dans un formulaire(attributvalue) prsencedebalisesHTMLvalidesquisontinterprtescommetellesparlenavigateur : nonpriseencomptedessautsdelignesprsentsdansuntexte.

Le deuxime "problme" peut prsenter un intrt dans les situations o vous souhaitez offrir la possibilit un utilisateurdesaisiruntexteavecunpeudemiseenformepourunaffichageultrieurdansunepage. Pour rsoudre ces trois problmes, PHP propose quatre fonctions : htmlspecialchars, htmlentities, nl2br et strip_tags.

- 4-

ENI Editions - All rigths reserved

Lafonction htmlspecialcharsprendunechanedecaractresetlaretourneenremplaantcertainscaractresparleur quivalentHTML : Syntaxe chane htmlspecialchars( chane texte [, entier option [, chane jeu [, boolen double_encodage]]]) texte Chanetraiter. option Fonctionnementvisvisdescaractresguillemets(")etapostrophe( ). jeu Jeudecaractresutiliserpourlaconversion. double_encodage Indiquesilfaut(TRUE,valeurpardfaut)ounon(FALSE)encoderlesentitsHTMLdjencodes.Apparuenversion 5.2.3. Lescaractresconvertissontlessuivants : Entre Sortie

& " < >

&amp; &quot; &#039; &lt; &gt;

Ledeuximeparamtrepermetdeprciserlefonctionnementvisvisdescaractresguillemets(")etapostrophe( ) : Valeur Comportement Conversionduguillemetmaispasdelapostrophe(par dfaut) Aucuneconversion Conversiondesdeuxcaractres

ENT_COMPAT ENT_NOQUOTES ENT_QUOTES

Letroisimeparamtrepermetdedfinirlejeudecaractresutiliserpourlaconversion : ISO88591 (pardfaut), ISO885915 ,UTF8 ,etc. Depuislaversion5.1.0,ilexisteunefonctionhtmlspecialchars_decodequieffectuelaconversioninversedelafonction htmlspecialchars. Exemple <?php $texte = Olivier & Co. a dclar : "c\est l\t !"; echo htmlspecialchars($texte,ENT_QUOTES); ?> Rsultatdanslecodesourcedelapage(leslmentsconcernssontengras) Olivier & a m p ; Co. a dclar : & q u o t ; c & # 0 3 9 ; est l & # 0 3 9 ; t ! & q u o t ; La fonction htmlentities prsente un comportement identique celui de htmlspecialchars mais pour tous les caractresayantunquivalentenHTML(caractresaccentusnotamment). Syntaxe
ENI Editions - All rigths reserved - 5-

chane htmlentities( chane texte [, entier option [, chane jeu [, boolen double_encodage]]]) texte Chanetraiter. option Fonctionnementvisvisdescaractresguillemets(")etapostrophe(). jeu Jeudecaractresutiliserpourlaconversion. double_encodage Indiquesilfaut(TRUE,valeurpardfaut)ounon(FALSE)encoderlesentitsHTMLdjencodes.Apparuenversion 5.2.3. Lesdeuximeettroisimeparamtresontlammesignificationquepourlafonctionhtmlspecialchars. Exemple <?php $texte = Olivier & Co. a dclar : "c\est l\t !"; echo htmlentities($texte,ENT_QUOTES); ?> Rsultatdanslecodesourcedelapage(leslmentsconcernssontengras) Olivier & a m p ; Co. a d & e a c u t e ; clar & e a c u t e ; : & q u o t ; c & # 0 3 9 ; est l& # 0 3 9 ; & e a c u t e ; t& e a c u t e ; !& q u o t ; Lafonction nl2brprendunechanedecaractresetlaretourneaprsavoirinsrunebaliseHMTLdesautdeligne devant chaque saut de ligne : la balise est <br /> (compatibilit XHTML) partir de la version 4.0.5 de PHP et <br> avant. Syntaxe chane nl2br( chane texte) texte Chanetraiter. Exemple <?php $texte = "Premire ligne.\nDeuxime ligne."; echo nl2br($texte); ?> Rsultatdanslecodesourcedelapage(leslmentsconcernssontengras) Premire ligne. < b r / > Deuxime ligne. Enfin, la fonction strip_tags prend une chane de caractres et la retourne aprs avoir supprim toutes les balises HTMLquellecontient. Syntaxe chane strip_tags( chane texte[, chane balises_autorises]) texte

- 6-

ENI Editions - All rigths reserved

Chanetraiter. balises_autorises Listedesbalisesconserverdanslachane. Ledeuximeparamtrepermetdindiquerlesbalisesconserver. Exemple <?php $texte = "<b>Olivier</b> <i>Heurtel</i>"; echo $texte,<br/>; echo strip_tags($texte),<br/>; echo strip_tags($texte,<b>),<br/>; ?> Rsultat O l i v i e r Heurtel Olivier Heurtel O l i v i e r Heurtel Cesfonctionsvontdoncpermettredegrerlesdiffrentsproblmesvoqusprcdemment. Pourvitertoutproblmedaffichagedanslenavigateur,lideestdappliquerunetransformationauxdonnesavant oudanslinstructionecho. Desfonctionspersonnellespeuventtredveloppespoureffectuercetteopration. Exemple <?php // Fonction permettant dafficher des donnes dans un formulaire. // Encoder tous les caractres HTML spciaux. function vers_formulaire($valeur) { return htmlentities($valeur,ENT_QUOTES); } // Fonction permettant dafficher des donnes dans une page. // Encoder tous les caractres HTML spciaux. // Transformer les sauts de lignes en <br />. function vers_page($valeur) { return nl2br(htmlentities($valeur,ENT_QUOTES)); } ?> Cesfonctionspeuventensuitetreutilisesdansunscriptdetraitementdunformulaire. Exemple <?php // Inclusion du fichier qui contient les dfinitions de nos // fonctions gnrales. include(fonctions.inc); // Tester si la page est appele aprs validation du formulaire if (isset($_POST[ok])) { // Appel de la fonction qui supprime lencodage // "magic quotes" de tous les tableaux GPC. supprimer_encodage_MQ_GPC(); // Rcupration de la valeur saisie dans le formulaire $nom = isset($_POST[nom])?$_POST[nom]:; // La valeur saisie est raffiche dans le formulaire et // dans la page ... } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Saisie</title></head> <body>

ENI Editions - All rigths reserved

- 7-

<form action="saisie.php" method="post"> <div> Nom : <input type="text" name="nom" value="<?php echo v e r s _ f o r m u l a i r e ( $ n o m ) ; ?>" /> <input type="submit" name="ok" value="OK" /><br /> <?php echo v e r s _ p a g e ( $ n o m ) ; ?> </div> </form> </body> </html> Rsultat

Aveccetteapproche,lasaisieestrestituetellequelle :silutilisateurasaisiunebalise,illaretrouve(cellecinestpas interprteparlenavigateur).Sibesoin,lesfonctionspeuventtremodifiespoursupprimerlesbaliseslaidedela fonctionstrip_tags. afonctionnl2brdoittreappeleaprslesfonctionshtmlentitiesou htmlspecialchar.Danslecascontraire, L labalise<br />ajouteparnl2brestencode(en&lt;br /&gt;)avantdtreinsredanslecodesourcedela page et nestdoncpasinterprteparlenavigateur(letexte <br /> apparat dans la page affiche). La fonction nl2brnedoitpastreappelepourdutextedestinunezone <textarea>(souspeine,lencore,davoirletexte <br />danslazone).

3.Synthse
La gestion des formulaires et des URL, avec laffichage et/ou lenregistrement des donnes rcupres, peut rapidementdeveniruncassettecomptetenudesdiffrentsproblmespotentielsetdesdirectivesdeconfiguration associes. Nanmoins,avecunpeuderigueuretdeuxoutroisfonctionscritesunefoispourtoute,cettegestionpeutsefaire sanssoucis. Lastratgieprconiseestrsumeparleschmasuivant :

- 8-

ENI Editions - All rigths reserved

Lecasdesbasesdedonnesetdescookiesesttraitendtaildansleschapitresultrieurs lecasdesfichiersat prsentdanslechapitreUtiliserlesfonctionsPHP. Les fonctions supprimer_encodage_MQ, supprimer_encodage_MQ_GPC, vers_formulaire, et vers_page proposes en exemplesdanscechapitrepermettentdegrerlesdonnesexternessansproblmeselonlastratgieprconiseci dessus.

ENI Editions - All rigths reserved

- 9-

Utilisationdesfiltres
1.Principes
Depuislaversion5.2.0,unenouvelleextensionpermetdefiltreretvaliderdesdonnes,notammentcellesprovenant delasaisiedesutilisateursouduneURL. Chaque filtre est dfini par un numro (identifiant), un nom et, ventuellement, des options et des indicateurs qui prcisentlecomportementdufiltre.Chaqueoptionestdfinieparunnomquiestutiliscommecldansuntableau associatif.Chaqueindicateurestdfiniparuneconstante pourspcifierplusieursindicateurs,ilsuffitdesommerles constantescorrespondantes. Quelquesexemplesdefiltres(voirladocumentationpourladescriptiondetouslesfiltres) : Identifiant(constanteprdfinie) Description Valideunevaleurentantquentier.Lesoptions min_rangeetmax_rangepermettentdedfinirun intervalledevalidit. Valideunevaleurentantquenombrevirgule flottante. Valideunevaleurlaideduneexpressionrgulire compatiblePERL.LesexpressionsrguliresPERL sontlgrementdiffrentesdesexpressions rgulires"PHP"prsentesdanscetouvrage(voirla documentationpourlesdiffrences).Lexpression rgulireutiliserestspcifiegrceloption regexp. Valideunevaleurentantquadresselectronique. Supprimelesbalisescontenuesdansunechaneet encodelescaractreset".Plusieursindicateurssont disponiblespoursupprimerouencoderdescaractres supplmentaires(voircidessous). EncodeenHTMLlescaractres,",<,>et&ainsique touslescaractresdecodeASCIIinfrieur32. Plusieursindicateurssontdisponiblespoursupprimer ouencoderdescaractressupplmentaires(voirci dessous). chappelescaractres,"et\(appliquelafonction addslashes). tre utiliss avec les filtres FILTER_SANITIZE_STRING et

FILTER_VALIDATE_INT

FILTER_VALIDATE_FLOAT

FILTER_VALIDATE_REGEXP

FILTER_VALIDATE_EMAIL

FILTER_SANITIZE_STRING

FILTER_SANITIZE_SPECIAL_CHARS

FILTER_SANITIZE_MAGIC_QUOTES
Les indicateurs suivants peuvent FILTER_SANITIZE_SPECIAL_CHARS : FILTER_FLAG_STRIP_LOW SupprimelescaractresdecodeASCIIinfrieur32. FILTER_FLAG_STRIP_HIGH SupprimelescaractresdecodeASCIIsuprieur127. FILTER_FLAG_ENCODE_HIGH

EncodeenHTMLlescaractresdecodeASCIIsuprieur127. Encomplment,lesindicateurssuivantspeuventtreutilissaveclefiltreFILTER_SANITIZE_STRING :
ENI Editions - All rigths reserved - 1-

FILTER_FLAG_NO_ENCODE_QUOTES Nencodepaslescaractreset". FILTER_FLAG_ENCODE_AMP EncodeenHTMLlecaractre&. FILTER_FLAG_ENCODE_LOW EncodeenHTMLlescaractresdecodeASCIIinfrieur32. Deplus,lindicateurFILTER_NULL_ON_FAILUREpeuttreutilisavectouslesfiltrespourquelesfonctionsretournentla valeurNULLaulieudelavaleurFALSEencasdchec. Cesfiltrespeuventtreutilissdanslesfonctionsfilter_var,filter_var_array,filter_inputetfilter_input_array. Fonctionsfilter_varetfilter_var_array Lafonctionfilter_varpermetdefiltrerunedonne. Syntaxe mixte filter_var( mixte donne[, entier filtre[, mixte options_indicateurs]]) donne Donnefiltrer. filtre Identifiantdufiltreappliquer(FILTER_SANITIZE_STRINGpardfaut). options_indicateurs Optionset/ouindicateursventuelsdufiltre(voircidessous). Cettefonctionretourneladonnefiltre,ouFALSEsilefiltreachou(ou NULLsilindicateur FILTER_NULL_ON_FAILURE estutilis). Dans le cas le plus gnral, le paramtre options_indicateurs est spcifi sous la forme dun tableau associatif comportantuneoudeuxlignes,aveclesclssuivantes :flagspourlesindicateursetoptionspourlesoptions.Comme indiqu prcdemment, plusieurs indicateurs peuvent tre fournis en sommant les constantes correspondantes. La valeurdesoptionsestelleaussidfiniesouslaformeduntableauassociatifdanslequellenomdeloptionestutilis commecl. Danslecasoleparamtre options_indicateursnedfinitquedesindicateurs,lavaleurcorrespondantepeuttre passedirectement,sansutiliserdetableau. Exemple1 <?php echo "<b>Filtrer un nombre entier</b><br />"; $valeurs = array(123,abc,1.2,NULL); foreach ($valeurs as $x) { echo "$x => "; var_export(filter_var($x,FILTER_VALIDATE_INT)); echo "<br />"; } echo "<b>+ NULL au lieu de FALSE en cas derreur</b><br />"; $x = abc; // indicateur pass en option directement $options = FILTER_NULL_ON_FAILURE; echo "$x => "; var_export(filter_var($x,FILTER_VALIDATE_INT,$options)); echo "<br />"; echo "<b>Filtrer un nombre entier (0-100)</b><br />"; // options du filtre dfinies via un tableau associatif $options = array

- 2-

ENI Editions - All rigths reserved

( options => array(min_range => 0,max_range => 100) ); $valeurs = array(0,100,101); foreach ($valeurs as $x) { echo "$x => "; var_export(filter_var($x,FILTER_VALIDATE_INT,$options)); echo "<br />"; } echo "<b>+ NULL au lieu de FALSE en cas derreur</b><br />"; // indicateur ajout dans le tableau des options $options = array ( options => array(min_range => 0,max_range => 100), flags => FILTER_NULL_ON_FAILURE ); $x = 101; echo "$x => "; var_export(filter_var($x,FILTER_VALIDATE_INT,$options)); echo "<br />"; echo "<b>Filtrer avec une expression rgulire</b><br />"; $regexp = <^[0-9]{2}/[0-9]{2}/[0-9]{4}$>; $options = array ( options => array(regexp => $regexp) ); $valeurs = array(01/01/2007,01/01/07); foreach ($valeurs as $x) { echo "$x => "; var_export(filter_var($x,FILTER_VALIDATE_REGEXP,$options)); echo "<br />"; } ?> Rsultat Filtrer un nombre entier 123 => 123 abc => false 1.2 => false + NULL au lieu de FALSE en cas derreur abc => NULL Filtrer un nombre entier (0-100) 0 => 0 100 => 100 101 => false + NULL au lieu de FALSE en cas derreur 101 => NULL Filtrer avec une expression rgulire 01/01/2007 => 01/01/2007 01/01/07 => false Exemple2 <?php $texte = "<b>cest lt</b>"; echo "// texte affich sans prcaution<br />\n"; echo $texte,"<br />\n"; echo "// FILTER_SANITIZE_SPECIAL_CHARS<br />\n"; echo filter_var ( $texte, FILTER_SANITIZE_SPECIAL_CHARS ), "<br />\n"; echo "// + option FILTER_FLAG_ENCODE_HIGH<br />\n";
ENI Editions - All rigths reserved - 3-

echo filter_var ( $texte, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH ), "<br />\n"; echo "// FILTER_SANITIZE_STRING<br />\n"; echo filter_var($texte,FILTER_SANITIZE_STRING),"<br />\n"; echo "// + option FILTER_FLAG_ENCODE_HIGH<br />\n"; echo filter_var ($texte, FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_HIGH ), "<br />\n"; echo "// FILTER_SANITIZE_MAGIC_QUOTES<br />\n"; echo filter_var ( $texte, FILTER_SANITIZE_MAGIC_QUOTES ), "<br />\n"; ?> Rsultatdanslenavigateur // texte affich sans prcaution cest lt // FILTER_SANITIZE_SPECIAL_CHARS <b>cest lt</b> // + option FILTER_FLAG_ENCODE_HIGH <b>cest lt</b> // FILTER_SANITIZE_STRING cest lt // + option FILTER_FLAG_ENCODE_HIGH cest lt // FILTER_SANITIZE_MAGIC_QUOTES c\est l\t Rsultatdanslesourcedelapage // texte affich sans prcaution<br /> <b>cest lt</b><br /> // FILTER_SANITIZE_SPECIAL_CHARS<br /> &#60;b&#62;c&#39;est l&#39;t&#60;/b&#62;<br /> // + option FILTER_FLAG_ENCODE_HIGH<br /> &#60;b&#62;c&#39;est l&#39;&#233;t&#233;&#60;/b&#62;<br /> // FILTER_SANITIZE_STRING<br /> c&#39;est l&#39;t<br /> // + option FILTER_FLAG_ENCODE_HIGH<br /> c&#39;est l&#39;&#233;t&#233;<br /> // FILTER_SANITIZE_MAGIC_QUOTES<br /> <b>c\est l\t</b><br /> Lafonctionfilter_var_arraypermetdefiltreruntableaudedonnes. Syntaxe mixte filter_var_array( tableau donnes[, mixte filtres]) donnes Tableauassociatifcontenantlesdonnesfiltrer.Lesclssontdeschanesdecaractresquiidentifientchaque donnevalider.

- 4-

ENI Editions - All rigths reserved

filtres Dfinitiondesfiltresappliquerchaquedonnedutableaudedonnes. Lafonctionretourneletableaudesdonnesfiltres leslignespourlesquelleslefiltreachousontFALSE(ouNULL silindicateurFILTER_NULL_ON_FAILUREestutilis)etcellespourlesquellesladonnenexistepassontNULL. Danslecasleplusgnral,leparamtrefiltresestspcifisouslaformeduntableauassociatifquireprendlescls du tableau de donnes (la correspondance entre les tableaux donneset filtresseffectue par lintermdiaire de la cl).Chaquevaleurdutableau filtrespeuttreunsimpleidentifiantdefiltreouuntableauassociatifdonnantune descriptionpluscompltedufiltreappliquer.Danscecas,lesclsdutableau filtressontfilterpourlidentifiantdu filtre, flags pour les indicateurs appliquer au filtre et options pour les options appliquer au filtre les valeurs associesauxclsflagsetoptionssedfinissentcommepourlafonctionfilter_var. Danslecasolemmefiltredoittreappliqutouteslesdonnes,sansindicateurnioption,leparamtre filtres peuttreunsimpleentiergallidentifiantdufiltre. Exemple <?php echo <b>Filtrer un tableau de nombres entier</b><br />; $valeurs = array(123,abc); var_export($valeurs); echo <br /> => ; // Mme filtre appliquer toutes les donnes, // sans indicateur ni option. var_export (filter_var_array($valeurs,FILTER_VALIDATE_INT)); echo <br />; echo <b>Filtrer un tableau de donnes diverses (1)</b><br />; $valeurs = array ( age => 123, taille => abc, mail => contact@olivier-heurtel.fr ); // Filtre diffrent mais "simple" (sans indicateur // ni option) appliquer aux donnes. $filtres = array ( age => FILTER_VALIDATE_INT, taille => FILTER_VALIDATE_INT, mail => FILTER_VALIDATE_MAIL ); var_export($valeurs); echo <br /> => ; var_export(filter_var_array($valeurs,$filtres)); echo <br />; echo <b>Filtrer un tableau de donnes diverses (2)</b><br />; $valeurs = array ( age => 123, taille => abc, mail => contact@olivier-heurtel.fr ); // Filtre avec options et indicateur appliquer une // des donnes. $filtre_age = array ( filter => FILTER_VALIDATE_INT, options => array(min_range => 0,max_range => 100), flags => FILTER_NULL_ON_FAILURE ); // Noter la mention dun filtre pour une donne // qui nexiste pas. $filtres = array ( age => $filtre_age, taille => FILTER_VALIDATE_INT, poids => FILTER_VALIDATE_INT, // nexiste pas
ENI Editions - All rigths reserved - 5-

mail => FILTER_VALIDATE_MAIL ); var_export($valeurs); echo <br />; var_export(filter_var_array($valeurs,$filtres)); ?> Rsultat Filtrer un tableau de nombres entier array ( 0 => 123, 1 => abc, ) => array ( 0 => 123, 1 => false, ) Filtrer un tableau de donnes diverses (1) array ( age => 123, taille => abc, mail => contact@olivier-heurtel.fr, ) => array ( age => 123, taille => false, mail => contact@olivier-heurtel.fr, ) Filtrer un tableau de donnes diverses (2) array ( age => 123, taille => abc, mail => contact@olivier-heurtel.fr, ) => array ( age => NULL, taille => false, poids => NULL, mail => contact@olivier-heurtel.fr, ) Dans le dernier exemple, notez la valeur NULL qui a t associe la donne poids (mentionne dans le filtre mais absentedesdonnes). Fonctionsfilter_inputetfilter_input_array Lesfonctions filter_inputet filter_input_arraysontsimilairesauxfonctions filter_var et filter_var_arraymais sappliquentdesdonnesextrieuresPHP(donnesdunformulaireparexemple)etnondesvariablesduscript. Syntaxe mixte filter_input( entier source, chane nom_variable[, entier filtre[, mixte options_indicateurs]]) source Sourcedesdonnes.UnedesconstantesINPUT_GET(donnespassesparlamthodeGET),INPUT_POST(donnes passesparlamthodePOST),INPUT_COOKIE(donnespassesparuncookie). nom_variable Nomdelavariabletraiter. filtre Identifiantdufiltreappliquer(FILTER_DEFAULTpardfaut). options_indicateurs Optionset/ouindicateursventuelsdufiltre(identiquelafonctionfilter_var). Cettefonctionretourneladonnefiltre,FALSEsilefiltreachououNULLsilavariablenestpasdfinie.Silindicateur FILTER_NULL_ON_FAILURE est utilis, la fonction retourne NULL si le filtre a chou ou FALSE si la variable nest pas dfinie. Syntaxe mixte filter_input_array( entier source[, mixte filtres]) source Sourcedesdonnes(identiquelafonctionfilter_input). filtres Dfinitiondesfiltresappliquerchaquedonnedutableaudedonnes(identiquelafonctionfilter_var_input).

- 6-

ENI Editions - All rigths reserved

Cette fonction est quivalente un appel la fonction filter_var_array effectu sur le tableau $_GET, $_POST ou $_COOKIEcorrespondantlasource( INPUT_GET,INPUT_POSTouINPUT_COOKIE). Lafonctionretourneletableaudesdonnesfiltresou NULLsilasourcenecontientaucunedonne leslignespour lesquelles le filtre a chou sont FALSE (ou NULL si lindicateur FILTER_NULL_ON_FAILURE est utilis) et celles pour lesquelleslavariablenexistepassontNULL. Unexempledutilisationdecesfonctionsestdonndanslasuite(cf.Applicationauxformulaires).

2.Applicationauxformulaires
Lesfiltrespeuventtreutilisspourimplmentertoutoupartiedestraitementsrelatifslagestiondesformulaires :
q

rcuprationdesdonnessaisies(fonctionsfilter_inputetfilter_input_array) vrificationdesdonnessaisies(filtresFILTER_VALIDATE_*) traitementdesproblmesrelatifsauxdonnessaisies(filtresFILTER_SANITIZE_*).

Il faut noter notamment que les filtres FILTER_SANITIZE_* effectuent des transformations similaires celles des fonctions htmlspecialchars, html_entities et strip_tags, prsentes prcdemment (cf. E Les problmes sur les donnessaisies),etpeuventdonclesremplacerdansnosexemples. Exemple <?php // Inclusion du fichier qui contient les dfinitions de nos // fonctions gnrales. include(fonctions.inc); // Tester si la page est appele aprs validation du formulaire if (filter_has_var(INPUT_POST, ok)) { // Dfinir les filtres pour les donnes saisies. $filtres = array ( nom => array(filter=> FILTER_SANITIZE_STRING, flags => FILTER_FLAG_ENCODE_HIGH + FILTER_FLAG_ENCODE_LOW) ); // Rcuprer la saisie filtre. $saisie = filter_input_array(INPUT_POST,$filtres); $nom = $saisie[nom]; // La valeur saisie est raffiche dans le formulaire et // dans la page ... } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Saisie</title></head> <body> <form action="saisie.php" method="post"> <div> Nom : <input type="text" name="nom" value="<?php echo $nom; ?>" /> <input type="submit" name="ok" value="OK" /><br /> <?php echo $nom; ?> </div> </form> </body> </html> Saisie

ENI Editions - All rigths reserved

- 7-

Rsultat

Sur cet exemple, le filtre FILTER_SANITIZE_STRING est utilis pour rcuprer les donnes saisies, supprimer les ventuellesbalisesetencoderlescaractrespouvantposerunproblmeencasderaffichage(danslapageoudans leformulaire).

- 8-

ENI Editions - All rigths reserved

Allersuruneautrepage
DansletraitementeffectuparunscriptPHP,ilpeuttrencessairedafficheruneautrepage. Le cas peut se produire par exemple, la fin du traitement du formulaire, la situation pouvant varier selon que le formulaireesttraitparlescriptquilafficheouparunscriptindpendant. Variantespossibles :
q

Pagedjbonne Allersuruneautrepage

OK

Allersuruneautrepage
q

Rafficherleformulaire avecunmessage
q

Rafficherleformulaire avecunmessage Allersurunepagederreur spcifique Afficherlerreurdansla pagecourante

Problme
q

Allersurunepagederreur spcifique
q

Rediriger lutilisateur vers une autre page en cours de script est possible en utilisant la fonction header qui permet denvoyerdesenttesHTTPaveclapageHTML(cf.UtiliserlesfonctionsPHPManipulerlesenttesHTTP). Nousallonsutiliserlenttelocationquiredirigelarequteversuneautreadresse. Syntaxedeladirectivelocation location: URL absolue ou relative Syntaxeaveclafonctionheader header(location: URL absolue ou relative ) Exemples // Redirection vers un script PHP situ au mme niveau. header(location: erreur.php); // Redirection vers une page HTML situe un sous-niveau. header(location: ./erreur/message.htm); // Redirection vers un autre site. header(location: http://www.olivier-heurtel.fr); LeprotocoleHTTP1.1requiertuneURLabsoluedansladirective location.Pourcela,vouspouvezutiliserlesvariables globales$_SERVER[HTTP_HOST]et$_SERVER[PHP_SELF](cf.chapitreAnnexesVariablesPHPprdfinies). Exemple <?php $url_relative = erreur.php; echo $url_relative = ,$url_relative,<br />; echo $_SERVER[\HTTP_HOST\] = , $_SERVER[HTTP_HOST],<br />; echo $_SERVER[\PHP_SELF\] = , $_SERVER[PHP_SELF],<br />; echo dirname($_SERVER[\PHP_SELF\]) = , dirname($_SERVER[PHP_SELF]),<br />; $url_absolue = http:// . $_SERVER[HTTP_HOST] . rtrim(dirname($_SERVER[PHP_SELF]), /\\) . / . $url_relative; echo $url_absolue = ,$url_absolue,<br />; ?>

ENI Editions - All rigths reserved

- 1-

Exemple $url_relative = erreur.php $_SERVER[HTTP_HOST] = xampp $_SERVER[PHP_SELF] = /eni/index.php dirname($_SERVER[PHP_SELF]) = /eni $url_absolue = http://xampp/eni/erreur.php Exemplesimpledutilisationsurunscriptinfo.php <?php // Affecter une valeur $nom si un nombre tir alatoirement // entre 0 et 1 est gal 1. $nom = (rand(0,1)==1)?Olivier:; // Tester si $nom est renseign. if ($nom == ) { // La variable $nom est vide, ce nest pas normal : // => rediriger lutilisateur vers une page derreur. header(location: erreur.htm); // Interrompre lexcution de ce script. exit; } // La variable $nom nest pas vide, laisser le script se poursuivre. $message = "Bonjour $nom !"; // prparer un message ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Saisie</title></head> <body> <p><?php echo $message; ?></p> </body> </html> Pageerreur.htm <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Erreur</title></head> <body> <div> Le site est actuellement indisponible ; essayez plus tard.<br /> Merci de votre comprhension.<br /> <!-- Lien pour une nouvelle tentative --> <a href="info.php">Essayer de nouveau</a> </div> </body> </html> Statistiquement,unefoissurdeux,lappelduscriptinfo.phpdonneralersultatsuivant : Bonjour Olivier ! Etdonc,unefoissurdeux,lesuivant : Le site est actuellement indisponible ; essayez plus tard. Merci de votre comprhension. Essayer de nouveau

aufcasparticulier,lafonctionheaderdoittreappeleavanttouteinstruction(PHPouHTML)quiapoureffetde S commencerconstruirelapageHTML(cfchapitreUtiliserlesfonctionsPHPManipulerlesenttesHTTP).

Premierexempledelogiquedenchanement

- 2-

ENI Editions - All rigths reserved

Unscript saisie.phpassurelaffichageinitialduformulaireetsontraitement.Encasderreur,leformulaireestpropos de nouveau pour correction (avec les valeurs saisies), accompagn dun message derreur en cas de succs du traitement,uneautrepageestappele. <?php // Inclure le fichier qui contient les dfinitions de nos // fonctions gnrales. include(fonctions.inc); // Tester comment le script est appel. if (isset($_POST[ok])) { // Traitement du formulaire. // Appeller la fonction qui supprime lencodage // "magic quotes" de tous les tableaux GPC. supprimer_encodage_MQ_GPC(); // Rcuprer les valeurs saisies dans le formulaire. $nom = trim($_POST[nom]); // Contrler les valeurs saisies. if ($nom == ) { $message .= "Le nom est obligatoire.\n"; } if (strlen($nom) > 10) { $message .= "Le nom doit avoir au plus 10 caractres.\n"; } // Tester sil y a des erreurs. if ($message == ) { // Pas derreur. // Rediriger lutilisateur vers une autre page et interrompre // lexcution du script. header(location: accueil.php); exit; } else { // Erreur. // Prparer le message pour laffichage. $message = vers_page($message); } } else { // Affichage initial. // Sur cet exemple simple, rien faire. } // Dans le code HTML qui suit, inclusion de deux petits bouts de // code PHP pour afficher respectivement la valeur des zones de // saisie et le message. ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Saisie</title></head> <body> <form action="saisie.php" method="post"> <div> Nom : <input type="text" name="nom" value="<?php echo vers_formulaire($nom); ?>" /> <input type="submit" name="ok" value="OK" /><br /> <?php echo $message; ?> </div> </form> </body> </html>

Deuximeexempledelogiquedenchanement Unscriptsaisie.htmassurelaffichageinitialduformulaireetunscript traitement.phpletraitement.Encasderreur,un message derreur est affich et lutilisateur est invit revenir en arrire. En cas de succs du traitement, une autre pageestaffiche. Fichiersaisie.htm <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">
ENI Editions - All rigths reserved - 3-

<head><title>Saisie</title></head> <body> <form action="traitement.php" method="post"> <div> Nom : <input type="text" name="nom" value="" /> <input type="submit" name="ok" value="OK" /> </div> </form> </body> </html> Scripttraitement.php <?php // Inclure le fichier qui contient les dfinitions de nos // fonctions gnrales. include(fonctions.inc); // Tester comment le script est appel. if (isset($_POST[ok])) { // Traitement du formulaire. // Appeller la fonction qui supprime lencodage // "magic quotes" de tous les tableaux GPC. supprimer_encodage_MQ_GPC(); // Rcuprer les valeurs saisies dans le formulaire. $nom = trim($_POST[nom]); // Contrler les valeurs saisies. if ($nom == ) { $message .= "Le nom est obligatoire.\n"; } if (strlen($nom) > 10) { $message .= "Le nom doit avoir au plus 10 caractres.\n"; } // Tester sil y a des erreurs. if ($message == ) { // Pas derreur. // Rediriger lutilisateur vers une autre page et interrompre // lexcution du script. header(location: accueil.php); exit; } else { // Erreur. // Prparer le message pour laffichage. $message = vers_page($message); } } // Dans le code HTML qui suit, inclusion dun petit bout de // code PHP pour afficher le message. ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Erreur</title></head> <body> <!-- Petit formulaire contenant un bouton permettant ---- de revenir en arrire (avec du JavaScript) pour corriger. --> <form> <div> <?php echo $message; ?><br /> <input type="button" value="Corriger" onClick="self.history.back()"> </div> </form> </body> </html> Dautres logiques denchanement peuvent exister, la fonction header permettant denvisager diffrents cas de figure (voirladocumentationPHP). Lersultatdutraitementpeutaussitreaffichdansuneautrefentregrcelattributtargetdelabalise<form> :

- 4-

ENI Editions - All rigths reserved

<form action="traitement.php" method="post" t a r g e t = " t r a i t e m e n t " > Silafentrenexistepas,elleseracreparlenavigateur.

ENI Editions - All rigths reserved

- 5-

changerunfichierentreleclientetleserveur
1.Vuedensemble
Certains sites peuvent proposer aux utilisateurs de transfrer des documents de leur poste vers le serveur Web : dposerunCVsurunsite(sitederecherchedemploi),mettreunepicejointedansunmessage(sitedemessagerie) ousimplementstockerledocumentsurleserveur(sitedestockage). Danslaterminologieanglosaxonne,cettefonctionnalitsappellele"fileupload". Inversement, beaucoup de sites permettent aux utilisateurs de tlcharger ("download") des documents du serveur Webversleurposte. Cesdeuxfonctionnalitssontdesapplicationsparticuliresdestechniquesprsentesdanscechapitre.

2.Tlchargerunfichierpartirduclient :"fileupload"
Cettefonctionnalit,trssimplemettreen uvreenPHP,ncessitedeuxoprations :
q

dansunformulaire,proposerunezonepermettantlutilisateurdedsignerlemplacementdufichiersurson poste danslescriptdetraitementduformulaire,rcuprerlefichierenvoyparlutilisateuretenfairequelquechose.

Danslapremirepartiedecechapitre,nousavionsvulapossibilitdemettredansunformulaireunezonepermettant dindiquerlemplacementdunfichiersursonposte(type="file"). Mettre une zone de ce type nest pas suffisant. Pour provoquer le transfert du fichier, il faut ajouter lattribut enctype="multipart/form-data"danslabalise<form> : <form action="saisie.php" method="post" enctype="multipart/form-data">

C ettetechniquenefonctionnequaveclesformulairesquiutilisentlamthodePOST.

En complment, il est possible dajouter une zone cache dans le formulaire afin de limiter la taille des fichiers qui peuvent tre envoys vers le serveur. Cette zone cache, obligatoirement situe avant la zone de type file doit sappelerMAX_FILE_SIZE(attributname)etprciserlataillemaximumenoctetsdanslattributvalue : Exempledezonecachepourlimiterlatailledesfichiers10ko : <input type="hidden" name="MAX_FILE_SIZE" value="10240"> La valeur prcise dans cette zone ne peut pas tre suprieure la valeur de la directive de configuration upload_max_filesize(2Mopardfaut).Silazonecachenestpasprsente,cestlataillespcifiedansladirective upload_max_filesizequisapplique. Parailleurs,letlchargementnestpossiblequesiladirectivedeconfigurationfile_uploadseston. Exempledeformulairecomplet <form action="saisie.php" method="post" enctype="multipart/form-data"> <div> Fichier : <input type="file" name="fichier" value="" /> <input type="submit" name="ok" value="OK" /> </div> </form> Lorsquun fichier est envoy avec un formulaire, des informations sur ce fichier sont accessibles dans le script PHP grcelavariable$_FILES lavaleursaisieparlutilisateurnestplusdisponibledans$_POST.

ENI Editions - All rigths reserved

- 1-

$_FILES est un tableau associatif multidimensionnel la premire cl est gale au nom de la zone de type file du formulaire(fichiersurnotreexemple)etletableauassociatifassociprsentecinqlignes : Cl Valeur Nomdufichier(sanschemindaccs) TypeMIMEdufichier(fourniparlenavigateur) Tailledufichierenoctets Nomdufichiertemporairecrsurleserveur(chemin complet) Codederreur.Unedesconstantessuivantes : UPLOAD_ERR_OK(0) :pasderreur UPLOAD_ERR_INI_SIZE(1) :tailledufichiersuprieure latailledfinieparladirectivedeconfiguration upload_max_filesize UPLOAD_ERR_FORM_SIZE(2) :tailledufichiersuprieure latailledfinieparloptionMAX_FILE_SIZEdu formulaire

name type size tmp_name

error

UPLOAD_ERR_PARTIAL(3) :lefichieratcharg partiellement UPLOAD_ERR_NO_FILE(4) :aucunfichiersaisi UPLOAD_ERR_NO_TMP_DIR(6) :pasderpertoire temporaire.Introduitenversion5.0.3. UPLOAD_ERR_CANT_WRITE(7) :erreurlorsdelcrituredu fichiersurdisque.Introduitenversion5.1.0. UPLOAD_ERR_EXTENSION(8) :transfertstopppar lextension.Introduitenversion5.2.0.

elonlesversions,ilexisteuncodeerreur5,sansnomdeconstante,encasderreurdanslefichiersaisi(nom, S chemin).Cecodederreurnexisteplusdepuislaversion5.2. Surleserveur,lefichiertransfrestunfichiertemporaireportantunnomdutypephp*.tmp,situdanslerpertoire dfiniparladirectivedeconfigurationupload_tmp_dir. La structure de $_FILES permet davoir plusieurs zones de type file dans le formulaire et donc dautoriser le chargementdeplusieursfichiers. Exemple: Leformulairecomportedeuxzonesdetypefilenommesfichier1etfichier2) :

fichier1

fichier2

name type tmp_name size name type tmp_name size

Photo.gif image/gif d:\temp\phpB.tmp 2376 cv.pdf application/pdf d:\temp\php12.tmp 52147

Si le fichier temporaire cr sur le serveur nest pas exploit (renomm/copi/dplac) par le script PHP qui traite le formulaire,ilestsupprimautomatiquementlafinduscript.DanslescriptPHP,ilconvientdoncdemanipulerlefichier temporaireselonlesbesoinsdelapplication. Exemplecomplet

- 2-

ENI Editions - All rigths reserved

<?php // Inclusion du fichier qui contient les fonctions gnrales. include(fonctions.inc); // Initialisation de la variable de message. $message = ; // Traitement du formulaire. if (isset($_POST[ok])) { // Rcuprer les informations sur le fichier. $informations = $_FILES["fichier"]; // En extraire : // - son nom $nom = valeur_saisie($informations[name]); // - son type MIME $type_mime = $informations[type]; // - sa taille $taille = $informations[size]; // - lemplacement du fichier temporaire $fichier_temporaire = $informations[tmp_name]; // - le code derreur $code_erreur = $informations[error]; // Contrles et traitement switch ($code_erreur) { case UPLOAD_ERR_OK : // Fichier bien reu. // Dterminer sa destination finale $destination = "/app/documents/$nom"; // Copier le fichier temporaire (tester le rsultat). if (copy($fichier_temporaire,$destination)) { // Copie OK => mettre un message de confirmation. $message = "Transfert termin - Fichier = $nom - "; $message .= "Taille = $taille octets - "; $message .= "Type MIME = $type_mime."; } else { // Problme de copie => mettre un message derreur. $message = Problme de copie sur le serveur.; } break; case UPLOAD_ERR_NO_FILE : // Pas de fichier saisi. $message = Pas de fichier saisi.; break; case UPLOAD_ERR_INI_SIZE : // Taille fichier > upload_max_filesize. $message = "Fichier $nom non transfr "; $message .= (taille > upload_max_filesize).; break; case UPLOAD_ERR_FORM_SIZE : // Taille fichier > MAX_FILE_SIZE. $message = "Fichier $nom non transfr "; $message .= (taille > MAX_FILE_SIZE).; break; case UPLOAD_ERR_PARTIAL : // Fichier partiellement transfr. $message = "Fichier $nom non transfr "; $message .= (problme lors du tranfert).; break; case UPLOAD_ERR_NO_TMP_DIR : // Pas de rpertoire temporaire. $message = "Fichier $nom non transfr "; $message .= (pas de rpertoire temporaire).; break; case UPLOAD_ERR_CANT_WRITE : // Erreur lors de lcriture du fichier sur disque. $message = "Fichier $nom non transfr "; $message .= (erreur lors de l\criture du fichier sur disque).; break; case UPLOAD_ERR_EXTENSION : // Transfert stopp par lextension. $message = "Fichier $nom non transfr ";

ENI Editions - All rigths reserved

- 3-

$message .= (transfert stopp par l\extension).; break; default : // Erreur non prvue ! $message = "Fichier non transfr "; $message .= " (erreur inconnue : $code_erreur )."; } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Upload</title></head> <body> <form action="upload.php" method="post" enctype="multipart/form-data"> <div> Fichier : <input size="100" type="file" name="fichier" value="" /> <input type="submit" name="ok" value="OK" /><br /> <?php echo vers_page($message); ?> </div> </form> </body> </html> Rsultat
q

Affichageinitialduformulaireetslectiondunfichier(laideduboutonParcourir...) :

RsultatduclicsurleboutonOK :

Surcetexemple,lefichierestcopidansunrpertoiresurleserveur.DanslechapitreAccderunebasededonnes MySQL,nousverronscommentstockerlefichierdansunebasededonnesMySQL.

3.Tlchargerunfichierpartirduserveur :"download"
Pourtlchargerunfichierpartirduserveur,ilestpossibledutiliserlamthodeclassiquequiconsisteutiliserun lien(balise<a>). Exemple <a href="cv.pdf">Tlcharger</a> Cettetechniquepeutposeruncertainnombredeproblmes :
q

Cestlenavigateurquidcidedeproposerlutilisateurundialoguedenregistrementoudafficherdirectement ledocumentsilsaitcommentfaire Lesfichiersquisontinterprtsparleserveur(.phpparexemple)ouparlenavigateur(.htmparexemple)ne peuventpastrechargsdecettemanire.

Une autre technique est utilisable si vous souhaitez forcer le navigateur proposer lutilisateur un dialogue denregistrement,etce,pournimportequeltypededocument. Cettetechniqueconsisteenvoyercertainsenttesparticulierslaidedelafonction header(cf.Utiliserlesfonctions PHPManipulerlesenttesHTTP),suividudocumentproprementdit.
- 4 ENI Editions - All rigths reserved

l nest pas garanti que cette technique fonctionne correctement, ou de la mme manire, avec tous les I navigateurs.IlyanotammentdesproblmesconnusaveccertainesversionsdInternetExplorer. Lesenttesminimumsenvoyersontlessuivants : Content-Disposition: attachment; filename=... Cetenttesuggreaunavigateurdetraiterledocumentcommeunepicejointe(attachment)etdeproposer lutilisateurdelenregistrersouslenomdfiniparfilename. Content-Type: ... CetenttecommuniqueaunavigateurletypeMIMEdudocument. QuelquestypesMIMEcourants : TypeMIME Naturedudocument DocumentMicrosoftWord Gnrique DocumentPDF DocumentMicrosoftExcel DocumentMicrosoftPowerPoint DocumentZip Imageauformatbitmap ImageauformatGIF ImageauformatJPEG ImageauformatTIFF ImageauformatPNG DocumentHMTL Documenttexte

application/msword application/octetstream application/pdf application/vnd.ms-excel application/vnd.ms-powerpoint application/zip image/bmp image/gif image/jpeg image/tiff image/png text/html text/plain

En mettant nimporte quoi comme type MIME (x/y par exemple), le navigateur doit normalement se dbrouiller avec lextensiondudocument. Aprslenvoidesenttes,ilneresteplusquenvoyerledocument"directement"danslapage,parexemplelaide delafonctionreadfile(cf.chapitreUtiliserlesfonctionsPHPManipulerlesfichierssurleserveur). Cette technique va tre illustre laide dun script download.php qui propose une liste de documents en tlchargement.Nousprsenteronsdeuxexemples:unexemplequiutiliseunformulaireetunexemplequiutilisedes liens. Danslesdeuxcas,lalistedesdocumentsquipeuventtretlchargsestcodeendurdanslescript.Dansunevraie application,cettelistededocumentviendraitsansdoutedunebasededonnes(cf.chapitreAccderunebasede donnesMySQL). Utilisationdunformulaire Danscepremierexemple,lescriptgnreunformulairequicomporteunboutondetype"image"(type="image")pour chaquefichierproposentlchargement,lenomduboutontantgalaunumrodudocument. Comme nous lavonsvudanslechapitreUtiliserlesfonctionsMySQL,nousrcupreronsdans $_POST deux variables
ENI Editions - All rigths reserved - 5-

n_xetn_ydonnantrespectivementlapositionrelativehorizontaleetverticaleducliclintrieurdelimage(ntantle nomdelimageclique,dansnotrecasunnumro). Exemple <?php // Liste des documents (viendrait sans doute dune // base de donnes dans une vraie application). $documents = array(cv.pdf,photo.gif); // Traitement du formulaire si $_POST non vide if (! empty($_POST)) { // Rcuprer le numro du document. // Prendre la cl de la premire ligne de $_POST // (normalement du type n_x, n tant le numro du document). list($numro) = each($_POST); // Convertir la chane en entier => seul le n reste. $numro = (integer) $numro; // En dduire le nom du document. $nom_fichier = $documents[$numro]; // Envoyer len-tte dattachement. $header = "Content-Disposition: attachment; "; $header .= "filename=$nom_fichier\n" ; header($header); // Envoyer len-tte du type MIME (ici, "inconnu"). header("Content-Type: x/y\n"); // Envoyer le document. // Pas dencodage magic quotes avant de lire le fichier. set_magic_quotes_runtime(0); readfile($nom_fichier); } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Download</title></head> <body> <form action="Download.php" method="post"> <table border="1" cellpadding="4" cellspacing="0"> <tr align="center"> <th>document</th><th>tlcharger</th> </tr> <?php // Un petit bout de code PHP pour gnrer les lignes du // tableau prsentant la liste des documents. // Parcourir la liste des documents et utiliser le nom // pour laffichage et le numro comme nom de limage. foreach($documents as $numro => $document) { echo sprintf ( "<tr><td>%s</td><td align=\"center\">%s</td></tr>\n", $document, "<input type=\"image\" name=\"$numro\" src=\"download.gif\" />" ); } ?> </table> </form> </body> </html> Rsultat(dansFirefox)
q

Affichageinitialdelapage

- 6-

ENI Editions - All rigths reserved

Aprsclicsurlimageassocieaudocumentcv.pdf

Utilisationdeliens Dans ce deuxime exemple, le script gnre un tableau qui comporte un lien pour chaque fichier propos en tlchargement.LelienappelledenouveaulescriptenpassantlenumrodudocumentenparamtredanslURL. Exemple <?php // Liste des documents (viendrait sans doute dune // base de donnes dans une vraie application). $documents = array(cv.pdf,photo.gif); // Traitement du formulaire si $_GET non vide if (! empty($_GET)) { // Rcuprer le numro du document. $numro = $_GET[no]; // En dduire le nom du document. $nom_fichier = $documents[$numro]; // Envoyer len-tte dattachement. $header = "Content-Disposition: attachment; "; $header .= "filename=$nom_fichier\n" ; header($header); // Envoyer len-tte du type MIME (ici, "inconnu"). header("Content-Type: x/y\n"); // Envoyer le document. // Pas dencodage magic quotes avant de lire le fichier. set_magic_quotes_runtime(0); readfile($nom_fichier); } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Download</title></head> <body> <table border="1" cellpadding="4" cellspacing="0"> <tr align="center"><th>document</th></tr> <?php

ENI Editions - All rigths reserved

- 7-

// Un petit bout de code PHP pour gnrer les lignes du // tableau prsentant la liste des documents. // Parcourir la liste des documents et utiliser le nom // pour laffichage et le numro dans. foreach($documents as $numro => $document) { echo sprintf ( "<tr><td>%s</td></tr>\n", "<a href=\"download.php?no=$numro\">$document</a>" ); } ?> </table> </body> </html> Rsultat(dansFirefox)
q

Affichageinitialdelapage

Aprsclicsurlelienassociaudocumentcv.pdf

- 8-

ENI Editions - All rigths reserved

Introduction
1.Vuedensemble
LutilisationdunebasededonnesSQLestsouventindispensablepourmettreenplaceunsiteWebdynamique.Cest eneffetunmoyenstandardisdestockerdesdonnesutilespourlesite :
q

listedesutilisateursavecleursprfrences cataloguedeproduits tracedestransactionseffectues...

PHPproposeunsupportnatifpourungrandnombredebasesdedonnes,parmilesquellesMySQL,Oracle,Microsoft SQL Server, Informix, Sybase, SQLite. Par ailleurs, PHP supporte ODBC (Open DataBase Connectivity) et peut donc accdertoutebasededonnessupportantODBC. Danscetouvrage,noustudieronslaccsunebasededonnesMySQL. Typiquement, lors de lutilisationdune base de donnes, le script PHP aura besoin deffectuer une ou plusieurs des tchessuivantes :
q

seconnecteretsedconnecter liredesdonnes(uneligneouplusieurslignes) mettrejourdesdonnes(ajout,modificationousuppression).

Lesdiffrentestchestypesseronttudiesdanscechapitre. Pour les diffrents exemples, nous utiliserons la base de donnes eni cre dans le chapitre Introduction MySQL. Pourobtenirlesmmesrsultatsqueceuxprsentsdanscechapitre,vousdevezrcrerlabasededonnes. Exemple [root@xampp ~]# m y s q l - u r o o t < c r e e r - b a s e - e n i . s q l

2.QuelleextensionutiliserpouraccderMySQL ?
Depuislaversion5,PHPproposedeuxextensionspouraccderunebasededonnesMySQL :
q

MySQL(prfixemysql_) MySQLi(prfixemysqli_).

LextensionMySQLestlancienneextension,prsentedanslesversionsantrieuresdePHP.Cetteextensionpeuttre utilisepouraccdernimportequelleversiondeMySQL,maisellenesupportepaslesnouvellesfonctionnalitsdela version4.1deMySQL. Pour utiliser les nouvelles fonctionnalits de la version 4.1 de MySQL, il faut utiliser lextension MySQLi, apparue en version5dePHP.CetteextensionpeutaussitreutilisepouraccderuneversionplusanciennedeMySQL,sous rservedenepasutiliserlesfonctionnalitsapparuesdanslaversion4.1deMySQL. Mispartlesnouvellesfonctionnalitsdelaversion4.1deMySQL,lesdeuxextensionssonttrsprochesentermes defonctionnalits.Trssouvent,ellesproposentlesmmesfonctions,avecdessyntaxesidentiquesoucompatibles. Saufexception,pourpasserdelutilisationdeMySQLMySQLi,ilsuffitderemplacerleprfixemysql_danslenomdela fonctionparleprfixemysqli_. NouscommenceronsparprsenterdemaniredtaillelutilisationdelextensionMySQLi.Ensuite,noustablironsune correspondanceentrelextensionMySQLietlextensionMySQL,ensefocalisantsurlesprincipalesdiffrences. NousprsenteronsaussibrivementlextensionPHPDataObjects(PDO)quidfinituneinterfaceuniformepouraccder

ENI Editions - All rigths reserved

- 1-

auxbasesdedonnesenPHP.Cetteextensionestapparueenversion5.1.

3.Lanotiondefetch
Dans la suite, nous verrons que linstruction dexcution dune requte SELECT (en vue de lire des donnes) se contente dexcuter la requte mais ne retourne aucune donne. Aprs excution de la requte, il faut extraire les lignesdursultat :cestlanotionde"fetch". Pour rsumer le fonctionnement, linstruction dexcutiondune requte SELECT identifie un rsultat et positionne un pointeurinternesurlapremirelignedecersultat :

Uneinstructionsupplmentairepermetdelirelalignecourantedursultat,deramenerlesvaleursdansdesvariables PHPetdefaireavancerlepointeursurlalignesuivante :

- 2-

ENI Editions - All rigths reserved

UtilisationdelextensionMySQLi
1.Introduction
LextensionMySQLipeuttreutilisesoitsousuneformeprocdurale,soitsousuneformeobjet. Danssaformeorienteobjet,lextensionMySQLiproposetroisclasses : mysqli ConnexionentrePHPetMySQL. mysqli_stmt Requteprpare. mysqli_result Rsultatdelexcutiondunerequte. Ces diffrentes classes proposent des mthodes qui permettent deffectuer les diffrentes actions (excution dune requte, rcuprationdursultat,etc.). Dans sa forme procdurale, lextension MySQLi propose des fonctions qui permettent deffectuer les mmes actions. De faon transparente,plusieursdecesfonctionsretournentouacceptentenparamtresdesobjetsdetypemysqlioumysqli_result. Danscetouvrage,nousprsenteronsuniquementlaformeprocduraledelextensionMySQLi. LaprincipalenouveautdeMySQL4.1,utilisableaveclextensionMySQLi,estlanotionderequteprpare. Unerequteprpareestunerequtequicontientdesparamtresmatrialissparunpointdinterrogation(?). Exemples SELECT * FROM collection WHERE id = ? INSERT INTO collection(nom,prix_ht) VALUES( ? , ? ) linverse,unerequtenonprpareestunerequtedanslaquelletouteslesvaleurssontspcifies. Exemples SELECT * FROM collection WHERE id = 1 INSERT INTO collection(nom,prix_ht) VALUES( T e c h N o t e , 1 0 . 4 8 ) Dans la suite de ce chapitre, nous prsenterons comment excuter des requtes de lecture et de mise jour, dabord avec des requtes non prpares (cf. dans cette section Utiliser des requtes non prpares) puis avec des requtes prpares (cf. dans cettesectionUtiliserdesrequtesprpares).

2.Connexionetdconnexion
a.Connexion
Lafonctionmysqli_connectpermetdtabliruneconnexionavecunebaseMySQL. Syntaxe objet mysqli_connect([ chane hte [, chane utilisateur [, chane mot_de_passe [, chane nom_base [, entier port ]]]]]) Avec hte Nom(ouadresseIP)delhteauquelilfautseconnecter(machinelocalepardfaut). utilisateur Nomdelutilisateurutiliserpourtablirlaconnexion.Valeurpardfaut :lepropritaireduprocessusduserveurWeb. mot_de_passe Motdepasseutiliserpourtablirlaconnexion.Valeurpardfaut :chanevide(pasdemotdepasse).

ENI Editions - All rigths reserved

- 1-

nom_base BasededonnesMySQLslectionnepardfaut(aucunepardfaut). port NumroduportpourlaconnexionauserveurMySQL(portstandard3306pardfaut). Lafonction mysqli_connectretourneunidentifiantdeconnexion(objet mysqli)ou,encasderreur,lavaleur FALSEaccompagne dun message dalerte envoy laffichage (cf. chapitre Grer les erreurs dans un script PHP pour grer cette situation correctement). Plusieurs directives de configuration permettent de dfinir des valeurs par dfaut pour les diffrents paramtres de la fonction mysqli_connect(voirladocumentation).

b.Dconnexion
Lesconnexionsouvertesdansunscriptsontautomatiquementfermeslafinduscript,saufdconnexionexpliciteavantavecla fonctionmysqli_close. Lafonctionmysqli_closepermetdefermeruneconnexionencoursdescript. Syntaxe boolen mysqli_close( objet connexion) connexion Identifiantdeconnexionretournparlafonctionmysqli_connect. Lafonctionmysql_closeretourneTRUEencasdesuccsetFALSEencasderreur(accompagndunealerte).

c.ObtenirdesinformationssurleserveurMySQL
Lesfonctionsmysqli_get_host_infoetmysqli_get_server_infopermettentdobtenirdesinformationssurleserveurMySQL. Syntaxe chane mysqli_get_host_info( objet connexion) chane mysqli_get_server_info( objet connexion) connexion Identifiantdeconnexionretournparlafonctionmysqli_connect. Lafonctionmysqli_get_host_inforetournedesinformationssurletypedeconnexionutilise. Lafonctionmysqli_get_server_inforetournelaversionduserveurMySQL.

d.Obtenirdesinformationsencasderreurdeconnexion
Lesfonctionsmysqli_connect_errnoetmysqli_connect_errorpermettentdercuprerdesinformationssurlerreurventuelledela dernireconnexioneffectueaveclafonctionmysqli_connect. Syntaxe entier mysqli_connect_errno() chane mysqli_connect_error() Lafonctionmysqli_connect_errnoretourneunnumroderreur(0siaucuneerreur)etlafonctionmysqli_connect_errorlemessage associ(chanevidesiaucuneerreur).

e.Exemple
Danscetexemple,nousutilisonsloprateur@pournepasafficherlesalertesgnresparlesfonctionsencasderreur(cf.Grer leserreursdansunscriptPHPLesfonctionsdegestiondeserreurs). Exemple <?php // Dfinition dune petite fonction qui ouvre une connexion. function connecter($hte,$utilisateur,$mot_de_passe) {

- 2-

ENI Editions - All rigths reserved

$db = @mysqli_connect($hte,$utilisateur,$mot_de_passe); if ($db) { echo Connexion russie.<br />; echo Informations sur le serveur : , mysqli_get_host_info($db),<br />; echo Version du serveur : , mysqli_get_server_info($db),<br />; } else { printf( Erreur %d : %s.<br />, mysqli_connect_errno(),mysqli_connect_error()); } return $db; } // Dfinition dune petite fonction qui ferme une connexion. function dconnecter($connexion) { if ($connexion) { $ok = @mysqli_close($connexion); if ($ok) { echo Dconnexion russie.<br />; } else { echo Echec de la dconnexion. <br />; } } else { echo Connexion non ouverte.<br />; } } // Premier test de connexion/dconnexion. echo <b>Premier test</b><br />; $db = connecter(localhost,eniweb,web); dconnecter($db); // Deuxime test de connexion/dconnexion. echo <b>Deuxime test</b><br />; $db = connecter(xampp,inconnu,inconnu); dconnecter($db); ?> Rsultat Premier test Connexion russie. Informations sur le serveur : Localhost via UNIX socket Version du serveur : 5.0.45 Dconnexion russie. Deuxime test Erreur 1045 : Access denied for user inconnu@xampp (using password: YES). Connexion non ouverte.

3.Slectionnerunebasededonnes
La fonction mysqli_connect prsente prcdemment permet de slectionner une base de donnes ds la connexion (quatrime paramtredelafonction). Lafonctionmysqli_select_dbpermetdeslectionneroumodifierlabasededonnesutiliserpouruneconnexiondonne. Syntaxe boolen mysqli_select_db ( objet connexion, chane nom_base) Avec connexion Identifiantdeconnexionretournparlafonctionmysqli_connect. nom_base Nomdelabasededonnes. Lafonctionmysqli_select_dbretourne TRUEencasdesuccsetFALSEencasderreur.Lafonction mysqli_select_dbnegnrepas dalerteencasderreur. Exemple <?php

ENI Editions - All rigths reserved

- 3-

// Connexion. $db = mysqli_connect(localhost,eniweb,web); if (! $db) { exit(Echec de la connexion.); } echo Connexion russie.<br />; // Slection de la base de donnes. $ok = mysqli_select_db($db,eni); if ($ok) { echo Base de donnes slectionne.<br />; } else { echo Echec de la slection de la base de donnes.; } // Dconnexion. $ok = mysqli_close($db); if ($ok) { echo Dconnexion russie.; } else { echo Echec de la dconnexion.; } ?> Rsultat Connexion russie. Base de donnes slectionne. Dconnexion russie.

4.Utiliserdesrequtesnonprpares
a.Vuedensemble
Lestapesdutilisationdunerequtenonprparesontlessuivantes : Requtedelecture(SELECT) Excuterlarequte=mysqli_query Connatrelenombredelignesdanslersultat= mysqli_num_rows Extraireleslignesdursultat=mysqli_fetch_arrayou mysqli_fetch_assocoumysqli_fetch_objectou mysqli_fetch_row. Connatrelenombredelignestraites= mysqli_affected_rows Requtedemisejour(INSERT,UPDATE,DELETE)

Connatrelavaleurdudernieridentifiantgnrpourune colonneayantletypeAUTO_INCREMENT=mysqli_insert_id

Encomplment,lesfonctions mysqli_errnoet mysqli_errorpermettentdercuprerdesinformationssurlerreurventuelledela dernireoprationeffectuedansunesession.

b.Excuterunerequte
Lafonctionmysqli_querypermetdexcuterunerequtesurunebasededonnes. Syntaxe objet mysqli_query( objet connexion, chane requte [, entier mode]) Avec connexion Identifiantdeconnexionretournparlafonctionmysqli_connect. requte Textedelarequteexcuter. mode Indiquesilersultatdoittremisenbuffer(constanteMYSQLI_STORE_RESULT,valeurpardfaut)ounon(constante MYSQLI_USE_RESULT).

- 4-

ENI Editions - All rigths reserved

Danslecasdune requte SQL qui retourne un rsultat (comme SELECT, SHOW ou DESCRIBE), la fonction mysqli_query retourne un identifiantdersultatderequteencasdesuccs(objetmysqli_result)etFALSEencasdchec.PourlesautresordresSQL,cette fonctionretourneTRUEencasdesuccsetFALSEencasdchec.Lafonctionmysqli_querynegnrepasdalerteencasderreur. Dans le cas dune requte SQL qui retourne un rsultat, la fonction mysqli_query excute la requte, indique si la requte sest excute correctement mais ne renvoie aucune donne. Il va falloir extraire les lignes du rsultat. Le troisime paramtre de la fonction mysqli_queryindiquesilersultatdelarequteestmisenbuffer(constante MYSQLI_STORE_RESULT,valeurpardfaut)ou non (MYSQLI_USE_RESULT). Pour les requtes volumineuses, lutilisation de MYSQLI_USE_RESULT consomme beaucoup moins de mmoireetpermetdextrairelapremirelignebeaucoupplusrapidement :ilnyapasbesoindattendrequelatotalitdursultat soitmisenbuffer.Parcontre,aprsexcutiondelarequteavec MYSQLI_USE_RESULT,ilnestpaspossibledeconnatrelenombre de lignes du rsultat, ni dexcuter une autre requte avant davoir extrait la totalit des lignes ou libr le rsultat (fonction mysqli_free_result). Exemple(avecunerequteSELECT) <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Excution dune requte SELECT. $requte = mysqli_query($db,SELECT * FROM collection); if ($requte === FALSE) { echo Echec de l\excution de la requte; } else { echo Excution russie.; } // Dconnexion. $ok = mysqli_close($db); ?> Rsultat Excution russie.

c.Connatrelenombredelignesdanslersultatdunerequtedelecture
Lafonctionmysqli_num_rowspermetdeconnatrelenombredelignesdanslersultat. Syntaxe entier mysqli_num_rows( objet rsultat) Avec rsultat Identifiantdersultatderequteretournparlafonctionmysqli_query. Cette fonction est utilisable uniquement pour les requtes qui retournent un rsultat (comme SELECT, SHOWou DESCRIBE) et pour lesquelleslersultatatmisenbuffer(voirlafonctionmysqli_query). Exemple <?php // Connexion (avec slection de la base de donnes). $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Excution dune requte $requte = mysqli_query($db,SELECT * FROM collection); if ($requte === FALSE) { echo Echec de l\excution de la requte; } else { // Affichage du nombre de lignes dans le rsultat echo Nombre de collections : ,mysqli_num_rows($requte); } // Dconnexion. $ok = mysqli_close($db); ?> Rsultat

ENI Editions - All rigths reserved

- 5-

Nombre de collections : 4

d.Extrairelersultatdunerequtedelecture
Lersultatdelexcutiondunerequtequiretourneunrsultat(comme SELECT, SHOWou DESCRIBE)peuttreluparlesfonctions mysqli_fetch_array,mysqli_fetch_assoc,mysqli_fetch_objectoumysqli_fetch_row. Cesfonctionsfontlammechose :elleslisentlalignecourantedursultatetfontavancerlepointeursurlalignesuivante(voir lintroduction). Cesfonctionsdiffrentsurletypededonneutilispourretournerlersultat. Syntaxe tableau mysqli_fetch_array( objet rsultat[, entier type]) tableau mysqli_fetch_assoc( objet rsultat) objet mysqli_fetch_object( objet rsultat) tableau mysqli_fetch_row( objet rsultat) Avec rsultat Identifiantdersultatderequteretournparlafonctionmysqli_query. type Typedersultatgalunedesconstantessuivantes :MYSQLI_ASSOC,MYSQLI_NUM,MYSQLI_BOTH(valeurpardfaut). Lesfonctions mysqli_fetch_array, mysqli_fetch_assocet mysqli_fetch_rowretournentlalignecourantedursultatsouslaforme duntableau,chaquelignedutableaucorrespondantunecolonnedursultat.Lafonction mysqli_fetch_objectretournelaligne courantesouslaformedunobjet. Silnyaplusdeligneliredanslersultat,cesfonctionsretournentNULL. Pour la fonction mysqli_fetch_assoc, le tableau est un tableau associatif dont la cl est le nom de la colonne. Pour la fonction mysqli_fetch_row, il sagitduntableauindicesentiers,lindice0correspondantlapremirecolonne,lindice1ladeuxime, etc.Enfinpourlafonctionmysqli_fetch_array,letypedutableaudpenddudeuximeparamtre : MYSQLI_NUM Tableauindicesentiers(commelafonctionmysqli_fetch_row). MYSQLI_ASSOC Tableauassociatif(commelafonctionmysqli_fetch_assoc). MYSQLI_BOTH(valeurpardfaut) Lesdeuxlafois.Chaquecolonneestprsentedeuxfois,unefoisavecunindiceentiercorrespondantsapositionetunefois avecuneclcorrespondantsonnom. Exemple Requte Colonnes 1relignedursultat Rsultatdunfetchavec :

SELECT id,nom,prix_ht FROM collection id 1 nom Ressources Informatiques prix_ht 24.44

- 6-

ENI Editions - All rigths reserved

Lafonction mysqli_fetch_objectretourneunobjet,avecunattributparcolonne,lenomdelattributcorrespondantaunomdela colonne. Exemple Attribut Valeur

id nom prix_ht

1 Ressources Informatiques 24.44

Encasdutilisation,dunaliasdecolonnedanslarequte SELECT(exempleSELECT AVG(prix_ht) prix_moyenFROM collection),cest laliasdecolonnequiestutiliscommeclounomdattribut. Exemple <?php // Inclusion du fichier qui contient la dfinition de // la fonction afficher_tableau. require(fonctions.inc); // Connexion (avec slection de la base de donnes). $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Excution dune requte $sql = SELECT id,nom,prix_ht FROM collection LIMIT 4; $requte = mysqli_query($db,$sql); // Premier fetch avec mysqli_fetch_row. $ligne = mysqli_fetch_row($requte); afficher_tableau($ligne,mysql_fetch_row); // Deuxime fetch avec mysql_fetch_assoc. $ligne = mysqli_fetch_assoc($requte); afficher_tableau($ligne,mysql_fetch_assoc); // Troisime fetch avec mysql_fetch_array : // -> sans deuxime paramtre = MYSQLI_BOTH $ligne = mysqli_fetch_array($requte); afficher_tableau($ligne,mysql_fetch_array); // Quatrime fetch avec mysql_fetch_object. $ligne = mysqli_fetch_object($requte); echo "<p /><b>mysql_fetch_object</b><br />"; echo "\$ligne->id = $ligne->id<br />"; echo "\$ligne->nom = $ligne->nom<br />"; echo "\$ligne->prix_ht = $ligne->prix_ht<br />"; // Cinquime fetch de nouveau avec mysql_fetch_row : // -> normalement, plus de ligne. $ligne = mysqli_fetch_row($requte); if ($ligne === NULL) { echo <p /><b>Cinquime fetch : plus rien</b>; }

ENI Editions - All rigths reserved

- 7-

// Dconnexion. $ok = mysqli_close($db); ?> Rsultat mysql_fetch_row 0 = 1 1 = Ressources Informatiques 2 = 24.44 mysql_fetch_assoc id = 2 nom = TechNote prix_ht = 9.48 mysql_fetch_array 0 = 3 id = 3 1 = Les TP Informatiques nom = Les TP Informatiques 2 = 25.59 prix_ht = 25.59 mysql_fetch_object $ligne->id = 4 $ligne->nom = Coffret Technique $ligne->prix_ht = 46.45 Cinquime fetch : plus rien En cas dutilisationdun identifiant de rsultat non valide, les fonctions mysqli_fech_* retournent NULLetaffichentunealerte(cf. Grerleserreurs). Toutes les mthodes se valent, notamment du point de vue des performances. Les fonctions mysqli_fetch_assoc et mysqli_fetch_objectpermettentdemployerlenomdescolonnesdelarequteetderendrelecodepluslisible. Exempledelecturedelatotalitdursultat <?php // Connexion (avec slection de la base de donnes). $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Excution dune requte $sql = SELECT id,titre FROM livre WHERE id_collection = 1; $requte = mysqli_query($db,$sql); // Lecture du rsultat. while ($ligne = mysqli_fetch_assoc($requte)) { echo $ligne[id], - ,$ligne[titre],<br />; } // Dconnexion. $ok = mysqli_close($db); ?> Rsultat 1 2 4 7 8 PHP 4 PHP 5.2 Oracle 10g BusinessObjects 6 MySQL 5

our obtenir des informations sur les colonnes du rsultat (nom de table, nom de colonne, type de donnes, etc.), vous P pouvezutiliserlesfonctionsmysqli_fetch_fieldoumysqli_fetch_fields.Pourensavoirplus,consultezladocumentation.

e.Obtenirdesinformationssurlersultatdunerequtedemisejour
Commenouslavonsindiquenprambule,mettrejourdesdonnesconsisteexcuterdesrequtes INSERT(cration), UPDATE (modification)ouDELETE(suppression)laidedelafonctionmysqli_query,commepourunerequteSELECT. Encomplment,deuxfonctionssontintressantes :mysqli_affected_rowsetmysqli_insert_id. Lafonction mysqli_affected_rowspermetdeconnatrelenombredelignesconcernes(insres,modifiesousupprimes)parla dernirerequteINSERT,UPDATEouDELETEexcutedansunesession. Syntaxe

- 8-

ENI Editions - All rigths reserved

entier mysqli_affected_rows( objet connexion) Avec connexion Identifiantdeconnexionretournparlafonctionmysqli_connect. Siladernirerequteachou,lafonctionmysql_affected_rowsretourne1. P ourunerequtedeslection,lafonctionmysqli_affected_rowsdonnelemmersultatquelafonctionmysqli_num_rows.

ans le cas dunordre UPDATE, mysqli_affected_rows ne compte pas les lignes non modifies lorsque les valeurs avant et D aprssontlesmmes.

Lafonction mysqli_insert_idretournelavaleurdudernieridentifiantgnrpourunecolonneayantletype AUTO_INCREMENTpar unerequteINSERTdansunesession. Syntaxe entier mysqli_insert_id( objet connexion) connexion Identifiantdeconnexionretournparlafonctionmysqli_connect. Siaucunidentifiantnatgnrautomatiquementparladernirerequte,lafonctionmysqli_insert_idretourne0. Exemples <?php // Dfinition dune petite fonction daffichage de la liste // des collections. function afficher_collections($db) { $sql = SELECT * FROM collection; $requte = mysqli_query($db,$sql); echo "<b>Liste des collections :</b><br />"; while ($ligne = mysqli_fetch_assoc($requte)) { echo $ligne[id], - ,$ligne[nom], - ,$ligne[prix_ht],<br />; } } // Connexion (avec slection de la base de donnes). $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Affichage de contrle. afficher_collections ($db); // Requte INSERT. $sql = "INSERT INTO collection(nom,prix_ht) " . "VALUES(Coffret Solutions,55.92)"; $requte = mysqli_query($db,$sql); $identifiant = mysqli_insert_id($db); echo Identifiant de la nouvelle collection = , $identifiant,<br />; // Requte UPDATE. $sql = "UPDATE collection SET prix_ht = prix_ht * 1.05 " . "WHERE prix_ht < 25"; $requte = mysqli_query($db,$sql); $nombre = mysqli_affected_rows($db); echo "$nombre collections(s) augmente(s).<br />"; // Affichage de contrle. afficher_collections($db); ?> Rsultat Liste des collections : 1 - Ressources Informatiques - 24.44 2 - TechNote - 9.48 3 - Les TP Informatiques - 25.59 4 - Coffret Technique - 46.45

ENI Editions - All rigths reserved

- 9-

Identifiant de la nouvelle collection = 5 2 collections(s) augmente(s). Liste des collections : 1 - Ressources Informatiques - 25.66 2 - TechNote - 9.95 3 - Les TP Informatiques - 25.59 4 - Coffret Technique - 46.45 5 - Coffret Solutions - 55.92

f.Grerleserreurs
Les fonctions mysqli_errno et mysqli_error permettent de rcuprer des informations sur lerreur ventuelle de la dernire oprationeffectuedansunesession. Syntaxe entier mysqli_errno( objet connexion) chane mysqli_error( objet connexion) Avec connexion Identifiantdeconnexionretournparlafonctionmysqli_connect. Lafonctionmysqli_errnoretourneunnumroderreur(0siaucuneerreur)etlafonction mysqli_errorlemessageassoci(chane videsiaucuneerreur). Exemple <?php // Connexion. $db = mysqli_connect(localhost,eniweb,web); if (! $db) { exit(Echec de la connexion.); } // Slection dune mauvaise base de donnes. $ok = mysqli_select_db($db,hermes); echo 1 : ,mysqli_errno($db), - , mysqli_error($db),<br />; // Slection de la bonne base de donnes. $ok = mysqli_select_db($db,eni); // Requte sur une table qui nexiste pas. $sql = SELECT * FROM article; $requte = mysqli_query($db,$sql); echo 2 : ,mysqli_errno($db), - , mysqli_error($db),<br />; // Fetch sur un mauvais rsultat. $ligne = mysqli_fetch_assoc($requte); echo 3 : ,mysqli_errno($db), - , mysqli_error($db),<br />; // Requte INSERT qui viole une cl unique. $sql = "UPDATE collection SET nom = TechNote WHERE id = 1"; $requte = mysqli_query($db,$sql); echo 4 : ,mysqli_errno($db), - , mysqli_error($db),<br />; ?> Rsultat 1 : 1044 - Access denied for user eniweb@localhost to database hermes 2 : 1146 - Table eni.article doesnt exist Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in / a p p / s c r i p t s / i n d e x . p h p on line 1 9 3 : 1146 - Table eni.article doesnt exist 4 : 1062 - Duplicate entry TechNote for key 2 Les points 2 et 3 illustrent le fait que les erreurs lies lutilisation dune ressource (de connexion ou de rsultat) non valide gnrentunealertequiestdirectementaffiche.Danscecas,lerreurnestpasuneerreurMySQLetlesfonctions mysqli_errnoou mysqli_errornesontpasrinitialisesetneretournentdoncpasderreurspcifique :lemessagedupoint3estenfaitceluidu point2. Enpratique,lesfonctionsmysqli_errnoetmysqli_errorsontutilisesaprslexcutiondesrequtes.

- 10 -

ENI Editions - All rigths reserved

5.Utiliserdesrequtesprpares
a.Vuedensemble
LaprincipalenouveautdeMySQL4.1,utilisableaveclextensionMySQLi,estlanotionderequteprpare. Unerequteprpareestunerequtequicontientdesparamtresmatrialissparunpointdinterrogation(?). Exemples SELECT * FROM articles WHERE identifiant = ? INSERT INTO articles(libelle,prix) VALUES( ? , ? )

U nparamtrenepeutpasremplacerunnomdetable,unnombredecolonneoutouteunepartiedelarequte. Exemplesinterdits SELECT * FROM ? SELECT * FROM articles WHERE ? Lestapesdutilisationdunerequteprparesontlessuivantes : Requtedelecture(SELECT) Prparerlarequte=mysqli_prepare LierdesvariablesPHPauxparamtresdelarequte=mysqli_stmt_bind_param Excuterlarequte=mysqli_stmt_execute Connatrelenombredelignesdanslersultat= mysqli_num_rows Connatrelenombredelignestraites= mysqli_stmt_affected_rows Connatrelavaleurdudernieridentifiantgnrpourune colonneayantletypeAUTO_INCREMENT= mysqli_stmt_insert_id Requtedemisejour(INSERT,UPDATE,DELETE)

LierdesvariablesPHPauxcolonnesdursultat= mysqli_stmt_bind_result

Extraireleslignesdursultat=mysqli_stmt_fetch Fermerlarequteprpare=mysqli_stmt_close DanslecasdunerequtedetypeSELECT,ilestpossibledestockerdansunbufferlersultatcompletdelexcutiondunerequte prpare.Danscecas,lesfonctionssuivantessontutiles : mysqli_stmt_store_result StockedansunbufferlersultatcompletdunerequteprparedetypeSELECT. mysqli_stmt_num_rows RetournelenombredelignesslectionnesparunerequteprparedetypeSELECT,dontlersultatatstockaupralable avecmysqli_stmt_store_result. mysqli_stmt_free_result LibrelersultatdunerequteprparedetypeSELECT,dontlersultatatstockaupralableavec mysqli_stmt_store_result. En complment, les fonctions mysqli_stmt_errno et mysqli_stmt_error permettent de rcuprer des informations sur lerreur ventuelledeladernireexcutiondunerequteprpare. chaqueexcutiondelarequteprpare,lavaleurcourantedesvariablesPHPassociesauxparamtresestutilise.Lintrt estdepouvoiremployerplusieursfoislammerequteavecdesvaleursdiffrentesdesparamtressansanalyserdenouveaula requte,cequipermetdamliorerlesperformances.

b.Prparerunerequte
Lafonctionmysqli_prepareprpareunerequtepourlexcution.

ENI Editions - All rigths reserved

- 11 -

Syntaxe objet mysqli_prepare( objet connexion, chane sql) connexion Identifiantdeconnexionretournparlafonctionmysqli_connect. sql TextedelarequteSQL. La fonction mysqli_prepare retourne une ressource de requte prpare (objet mysqli_stmt) ou, en cas derreur, la valeur NULL accompagne dun message dalerte envoy laffichage (cf. chapitre Grer les erreurs dans un script PHP pour grer cette situationcorrectement). Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Prparation de la requte. $sql = INSERT INTO collection(nom,prix_ht) VALUES(?,?); $requte = mysqli_prepare($db, $sql); // Dconnexion. $ok = mysqli_close($db); ?>

L esfonctionsmysqli_stmt_initetmysqli_stmt_preparepermettentdefairelammechose,maisendeuxtapes.

c.LierdesvariablesPHPauxparamtresdelarequte
Lafonctionmysqli_stmt_bind_paramliedesvariablesauxparamtresdunerequteprpare. Syntaxe boolen mysqli_stmt_bind_param( objet requte, chane types, mixte variable[, ...]) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). types Chanedecaractresquicontientunouplusieurscaractresquispcifientletypededonnesdelavariablelier :i=variablede typeentier d=variabledetypenombredcimal s=variabledetypechanedecaractres b=variabledetypeblob. variable Variablelierunparamtre. La fonction mysqli_stmt_bind_param retourne TRUE en cas de succs ou, en cas derreur, la valeur FALSE accompagne dun messagedalerteenvoylaffichage(cf.chapitreGrerleserreursdansunscriptPHPpourgrercettesituationcorrectement). Ildoityavoirexactementlemmenombredevariables,etdoncdecaractresdansleparamtretypes,quedeparamtresdansla requte.Lassociationestpositionnelle(premirevariablepourlepremier?,etc.). Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Prparation de la requte. $sql = INSERT INTO collection(nom,prix_ht) VALUES(?,?); $requte = mysqli_prepare($db, $sql); // Liaison des paramtres. $ok = mysqli_stmt_bind_param($requte,sd,$nom,$prix_ht);

- 12 -

ENI Editions - All rigths reserved

// Dconnexion. $ok = mysqli_close($db); ?> Comme le montre cet exemple, les variables lies nont pas besoin dtre dfinies au moment de lappel la fonction mysqli_stmt_bind_param. Les paramtres peuvent tre lis avec des lignes dun tableau ou les attributs dun objet. Dans les deux cas, mysqli_stmt_bind_paramcreletableauouinstancielobjet,silsnexistentpasdj.Danscecas,ilnefautpasdenouveaucrerle tableau,ouinstancierlobjet,aprslappelmysqli_stmt_bind_paramsouspeinede"casser"laliaison. Exemple <?php ... // Liaison des paramtres. // Avec les lignes dun tableau. $ok = mysqli_stmt_bind_param ($requte,sd, $collection[nom],$collection[prix_ht]); ... ?> <?php ... // Liaison des paramtres. // Avec les attributs dun objet. $ok = mysqli_stmt_bind_param ($requte,sd, $collection->nom,$collection->prix_ht); ... ?>

d.Excuterlarequteprpare
Lafonctionmysqli_stmt_executeexcuteunerequteprpare. Syntaxe boolen mysqli_stmt_execute( objet requte) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). Lafonctionmysqli_executeretourneTRUEencasdesuccsouFALSEencasderreur. Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Prparation de la requte. $sql = INSERT INTO collection(nom,prix_ht) VALUES(?,?); $requte = mysqli_prepare($db, $sql); // Liaison des paramtres. $ok = mysqli_stmt_bind_param($requte,sd,$nom,$prix_ht); // Excution de la requte. $nom = Epsilon; $prix_ht = 51.18; $ok = mysqli_stmt_execute($requte); // Nouvelle excution de la requte. $nom = Expert IT; $prix_ht = 36.97; $ok = mysqli_stmt_execute($requte); // Dconnexion. $ok = mysqli_close($db); ?>

e.Obtenirdesinformationssurlersultatdunerequtedemisejour
Lafonctionmysqli_stmt_affected_rowsretournelenombredelignesmisesjourparunerequteprpare.

ENI Editions - All rigths reserved

- 13 -

Syntaxe entier mysqli_stmt_affected_rows( objet requte) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). Silarequteachou,ousiellenestpasunerequtedemisejour,lafonctionmysqli_stmt_affected_rowsretourne1. Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Prparation de la requte. $sql = UPDATE collection SET frais_ht = ? . WHERE frais_ht IS NULL; $requte = mysqli_prepare($db, $sql); // Liaison des paramtres. $ok = mysqli_stmt_bind_param($requte,d,$frais_ht); // Excution de la requte. $frais_ht = 1; $ok = mysqli_stmt_execute($requte); echo Nombre de collection(s) modifie(s) = , mysqli_stmt_affected_rows ($requte),<br />; // Dconnexion. $ok = mysqli_close($db); ?> Rsultat Nombre de collection(s) modifie(s) = 5 Lafonctionmysqli_stmt_insert_idretournelavaleurdudernieridentifiantgnr,pourunecolonneayantletypeAUTO_INCREMENT, parunerequteprpareINSERT. Syntaxe entier mysqli_stmt_insert_id( objet requte) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). Siaucunidentifiantnatgnrautomatiquementparladernirerequte,lafonctionmysqli_stmt_insert_idretourne0. Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Prparation de la requte. $sql = INSERT INTO collection(nom) VALUES(?); $requte = mysqli_prepare($db, $sql); // Liaison des paramtres. $ok = mysqli_stmt_bind_param($requte,s,$nom); // Excution de la requte. $nom = Solution Informatiques; $ok = mysqli_stmt_execute($requte); echo Identifiant de la nouvelle collection = , mysqli_stmt_insert_id($requte),<br />; // Dconnexion. $ok = mysqli_close($db); ?> Rsultat Identifiant de la nouvelle collection = 8

- 14 -

ENI Editions - All rigths reserved

f.LierdesvariablesPHPauxcolonnesdursultatdunerequtedelecture
Lafonctionmysqli_stmt_bind_resultassociedesvariablesPHPauxcolonnesdursultatdunerequteprparedetypeSELECT. Syntaxe boolen mysqli_stmt_bind_result( objet requte, mixte variable [, ...]) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). variable Variablelierunecolonnedursultat. La fonction mysqli_stmt_bind_result retourne TRUE en cas de succs ou, en cas derreur, la valeur FALSE accompagne dun messagedalerteenvoylaffichage(cf.chapitreGrerleserreursdansunscriptPHPpourgrercettesituationcorrectement). Ildoityavoirexactementlemmenombredevariablesquedecolonnesdanslersultat.Lassociationestpositionnelle(premire variablepourlapremirecolonne,etc.). Lappel la fonction mysqli_stmt_bind_result est ncessaire pour toutes les requtes qui retourne un rsultat ( SELECT, SHOW, DESCRIBE). Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Prparation de la requte. $sql = SELECT id,titre FROM livre WHERE id_collection = ?; $requte = mysqli_prepare($db, $sql); // Liaison des paramtres. $ok = mysqli_stmt_bind_param($requte,i,$id_collection); // Excution de la requte. $id_collection = 1; $ok = mysqli_stmt_execute($requte); // Liaison des colonnes du rsultat. $ok = mysqli_stmt_bind_result($requte,$id,$titre); // Dconnexion. $ok = mysqli_close($db); ?> Les colonnes du rsultat peuvent tre lies avec des lignes dun tableau ou les attributs dun objet. Dans les deux cas, mysqli_stmt_bind_resultcreletableauouinstancielobjet,silsnexistentpasdj.Danscecas,ilnefautpasdenouveaucrer letableau,ouinstancierlobjet,aprslappelmysqli_stmt_bind_resultsouspeinede"casser"laliaison. Exemple <?php ... // Liaison des colonnes du rsultat. // Avec un tableau. $ok = mysqli_stmt_bind_result ($requte,$livre[id],$livre[titre]); ... ?> <?php ... // Liaison des colonnes du rsultat. // Avec un tableau, en laissant PHP affecter les indices. $ok = mysqli_stmt_bind_result ($requte,$livre[],$livre[]); ... ?> <?php ... // Liaison des colonnes du rsultat. // Avec les attributs dun objet. $ok = mysqli_stmt_bind_result ($requte,$livre->id,$livre->titre);

ENI Editions - All rigths reserved

- 15 -

... ?>

g.Extrairelersultatdunerequtedelecture
Lafonctionmysqli_stmt_fetchlitunelignedersultatdunerequteprparedetypeSELECT(SELECT,SHOW,DESCRIBE). Syntaxe boolen mysqli_stmt_fetch( objet requte) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). Lafonctionmysqli_stmt_fetchretourneTRUEencasdesuccs,FALSEencasderreuretNULLsilnyaplusdelignelire. LaligneestextraitedanslesvariablesPHPliesaupralableaursultat. Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Prparation de la requte. $sql = SELECT id,titre FROM livre WHERE id_collection = ?; $requte = mysqli_prepare($db, $sql); // Liaison des paramtres. $ok = mysqli_stmt_bind_param($requte,i,$id_collection); // Excution de la requte. $id_collection = 1; $ok = mysqli_stmt_execute($requte); // Liaison des colonnes du rsultat. $ok = mysqli_stmt_bind_result($requte,$id,$titre); // Lecture du rsultat. echo "<b>Collection numro $id_collection</b><br />"; while (mysqli_stmt_fetch($requte)) { echo "$id - $titre<br />"; } // Nouvelle excution et lecture du rsultat // (inutile de refaire les liaisons). $id_collection = 3; $ok = mysqli_stmt_execute($requte); echo "<b>Collection numro $id_collection</b><br />"; while (mysqli_stmt_fetch($requte)) { echo "$id - $titre<br />"; } // Dconnexion. $ok = mysqli_close($db); ?> Rsultat Collection numro 1 1 - PHP 4 2 - PHP 5.2 4 - Oracle 10g 7 - BusinessObjects 6 8 - MySQL 5 Collection numro 3 9 - PHP et MySQL (versions 4 et 5)

h.Utiliserunrsultatstock
DanslecasdunerequtedetypeSELECT,ilestpossibledestockerdansunbufferlersultatcompletdelexcutiondunerequte prpare.Danscecas,lesfonctionssuivantessontutiles : mysqli_stmt_store_result StockedansunbufferlersultatcompletdunerequteprparedetypeSELECT.

- 16 -

ENI Editions - All rigths reserved

mysqli_stmt_num_rows RetournelenombredelignesslectionnesparunerequteprparedetypeSELECT,dontlersultatatstockaupralable avecmysqli_stmt_store_result. mysqli_stmt_free_result LibrelersultatdunerequteprparedetypeSELECT,dontlersultatatstockaupralableavec mysqli_stmt_store_result. Leseulintrtdestockerlersultatestdepouvoirconnaitreimmdiatementlenombredelignesdanslersultat(aveclafonction mysqli_stmt_num_rows). Par contre, stocker le rsultat dune requte qui retourne un grand nombre de lignes consomme de la mmoire(ctclient). Lafonctionmysqli_stmt_fetchprsenteprcdemmentpermetdelirelersultatstock(sansdiffrencedesyntaxe). mysqli_stmt_store_result La fonction mysqli_stmt_store_result stocke dans un buffer le rsultat complet dune requte prpare de type SELECT(SELECT, SHOW,DESCRIBE). Syntaxe boolen mysqli_stmt_store_result( objet requte) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). Lafonctionmysqli_stmt_store_resultretourneTRUEencasdesuccsetFALSEencasderreur. mysqli_stmt_num_rows Lafonction mysqli_stmt_num_rows retourne le nombre de lignes slectionnes par une requte prpare de type SELECT, dont le rsultatatstockaupralableaveclafonctionmysqli_stmt_store_result. Syntaxe entier mysqli_stmt_num_rows( objet requte) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). La fonction mysqli_stmt_bind_result retourne toujours 0 si le rsultat na pas t stock au pralable laide de la fonction mysqli_stmt_store_result. mysqli_stmt_free_result La fonction mysqli_stmt_free_result libre le rsultat dune requte prpare de type SELECT, dont le rsultat a t stock au pralableavecresult. Syntaxe mysqli_stmt_free_result( objet requte) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). La fonction mysqli_stmt_free_result ne fait rien si le rsultat na pas t stock au pralable laide de la fonction mysqli_stmt_store_result. Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Prparation de la requte. $sql = SELECT id,titre FROM livre WHERE id_collection = ?; $requte = mysqli_prepare($db, $sql); // Liaison des paramtres. $ok = mysqli_stmt_bind_param($requte,i,$id_collection); // Excution de la requte. $id_collection = 1;

ENI Editions - All rigths reserved

- 17 -

$ok = mysqli_stmt_execute($requte); // Liaison des colonnes du rsultat. $ok = mysqli_stmt_bind_result($requte,$id,$titre); echo <b>Avant appel mysqli_stmt_store_result</b><br />, Nombre de lignes slectionnes = , mysqli_stmt_num_rows($requte),<br />; $ok = mysqli_stmt_store_result($requte); echo <b>Aprs appel mysqli_stmt_store_result</b><br />, Nombre de lignes slectionnes = , mysqli_stmt_num_rows($requte),<br />; // Lecture du rsultat. echo "<b>Collection numro $id_collection</b><br />"; while (mysqli_stmt_fetch($requte)) { echo "$id - $titre<br />"; } // Libration du rsultat. mysqli_stmt_free_result($requte); // Dconnexion. $ok = mysqli_close($db); ?> Rsultat Avant appel mysqli_stmt_store_result Nombre de lignes slectionnes = 0 Aprs appel mysqli_stmt_store_result Nombre de lignes slectionnes = 5 Collection numro 1 1 - PHP 4 2 - PHP 5.2 4 - Oracle 10g 7 - BusinessObjects 6 8 - MySQL 5

i.Grerleserreurs
Les fonctions mysqli_stmt_errno et mysqli_stmt_error permettent de rcuprer des informations sur lerreur ventuelle de la dernireexcutiondunerequteprpare. Syntaxe entier mysqli_stmt_errno( objet requte) chane mysqli_stmt_error( objet requte) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). La fonction mysqli_stmt_errno retourne un numro derreur (0 si aucune erreur) et la fonction mysqli_stmt_error le message associ(chanevidesiaucuneerreur). Pourpouvoirutilisercesdeuxfonctions,ilfautpasserenparamtreuneressourcederequteprparevalide.Celasignifiequela requte doit avoir t prpare avec succs avec la fonction mysqli_prepare. Pour obtenir des informations sur une erreur de prparation,ilfaututiliserlesfonctionsmysqli_errnoet/oumysqli_error(cf.danscettesectionUtiliserdesrequtesnonprpares Grerleserreurs). Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Prparation dune requte sur une table qui nexiste pas. $sql = SELECT * FROM article; $requte = mysqli_prepare($db, $sql); // Utilisation de mysqli_errno et mysqli_error ce stade. echo 1 : ,mysqli_errno($db), - , mysqli_error($db),<br />; // Prparation dune requte (sur une table qui existe). $sql = UPDATE collection SET nom = ? WHERE id = ?; $requte = mysqli_prepare($db, $sql); // Liaison des paramtres. $ok = mysqli_stmt_bind_param($requte,si,$nom,$id); // Excution de la requte (viole une cl unique).

- 18 -

ENI Editions - All rigths reserved

$id = 1; $nom = TechNote; $ok = mysqli_stmt_execute($requte); echo 2 : ,mysqli_stmt_errno($requte), - , mysqli_stmt_error($requte),<br />; // Dconnexion. $ok = mysqli_close($db); ?> Rsultat 1 : 1146 - Table eni.article doesnt exist 2 : 1062 - Duplicate entry TechNote for key 2

j.Fermerunerequteprpare
Lafonctionmysqli_stmt_closefermeunerequteprpare. Syntaxe boolen mysqli_stmt_close( objet requte) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init). La fonction mysqli_stmt_close retourne TRUE en cas de succs, ou, en cas derreur, la valeur NULL accompagne dun message dalerteenvoylaffichage(cf.chapitreGrerleserreursdansunscriptPHPpourgrercettesituationcorrectement).Lafonction retourneuneerreursilarequtenapastprpare(avecsuccs). I lestconseilldefermerunerequteprpareavantderutiliserlavariablepouruneautrerequte.

6.Appelerunprogrammestock
a.Procdurestocke
Pourappeleruneprocdurestocke,ilfautexcuterlordre SQL CALL nom_procdure(...)laide des fonctions mysqli_queryou mysqli_stmt_execute. Silaprocdurestockeretourneunrsultatdirectement(utilisationdunordre SELECTparexemple),cedernierdoittrelulaide desfonctionsdefetchadaptes. Si la procdure stocke possde un paramtre OUT, il faut utiliser une variable MySQL (@variable) dans lordre SQL CALL, puis excuterunerequteSELECT @variablepourrcuprerlersultatdanslescriptPHP. Premierexemple:procdureavecparamtreOUT Dans ce premier exemple, nous appellerons une procdure stocke qui permet de crer une nouvelle collection et qui retourne lidentifiantdelanouvellecollectiondansunparamtreOUT. Codesourcedelaprocdurestocke CREATE PROCEDURE ps_creer_collection ( -- Nom de la nouvelle collection. IN p_nom VARCHAR(25), -- Prix HT de la nouvelle collection. IN p_prix_ht DECIMAL(5,2), -- Identifiant de la nouvelle collection. OUT p_id INT ) BEGIN /* ** Insrer la nouvelle collection et ** rcuprer lidentifiant affect. */ INSERT INTO collection (nom,prix_ht) VALUES (p_nom,p_prix_ht); SET p_id = LAST_INSERT_ID(); END; ScriptPHP(requtenonprpare)

ENI Editions - All rigths reserved

- 19 -

<?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Dfinition des caractristiques de la nouvelle collection. $nom = Objectif Solutions; $prix_ht = 19.86; // Excution de la requte dappel de la procdure. // Le paramtre OUT de la procdure est rcupr dans la // variable MySQL @id. $sql = "CALL ps_creer_collection($nom,$prix_ht,@id)"; $requte = mysqli_query($db,$sql); // Excution de la requte qui lit le contenu de la // variable MySQL @id. $sql=SELECT @id; $requte = mysqli_query($db,$sql); $ligne = mysqli_fetch_assoc($requte); // Affichage du rsultat. echo Identifiant de la nouvelle collection = , $ligne[@id],<br />; // Excution dune requte qui supprime la nouvelle // collection. $sql = "DELETE FROM collection WHERE id = {$ligne[@id]}"; $requte = mysqli_query($db,$sql); // Dconnexion. $ok = mysqli_close($db); ?> Rsultat Identifiant de la nouvelle collection = 9 ScriptPHP(requteprpare) <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Dfinition des caractristiques de la nouvelle collection. $nom = Objectif Solutions; $prix_ht = 19.86; // Excution de la requte dappel de la procdure. // Le paramtre OUT de la procdure est rcupr dans la // variable MySQL @id. $sql = CALL ps_creer_collection(?,?,@id); $requte = mysqli_prepare($db,$sql); $ok = mysqli_stmt_bind_param($requte,sd,$nom,$prix_ht); $ok = mysqli_stmt_execute($requte); // Excution de la requte qui lit le contenu de la // variable MySQL @id. $sql=SELECT @id; $requte = mysqli_prepare($db,$sql); $ok = mysqli_stmt_bind_result($requte,$id); $ok = mysqli_stmt_execute($requte); $ok = mysqli_stmt_fetch($requte); // Affichage du rsultat. echo "Identifiant de la nouvelle collection = $id"; // Excution dune requte qui supprime la nouvelle // collection. $sql = "DELETE FROM collection WHERE id = $id"; $requte = mysqli_query($db,$sql); // Dconnexion. $ok = mysqli_close($db); ?> Rsultat Identifiant de la nouvelle collection = 10

Deuximeexemple:procdurequiretourneunrsultatdirectement

- 20 -

ENI Editions - All rigths reserved

Danscedeuximeexemple,nousappelleronsuneprocdurestockequiretournelalistedessousrubriquesdunerubriquedont lidentifiantestpassenparamtre. Codesourcedelaprocdurestocke CREATE PROCEDURE ps_lire_sous_rubriques ( -- Identifiant dune rubrique (parent). IN p_id_parent INT ) BEGIN /* ** Slectionner les sous-rubriques dune ** rubrique dont lidentifiant est pass ** en paramtre. */ SELECT titre FROM rubrique WHERE id_parent = p_id_parent; END; ScriptPHP(requtenonprpare) <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Identifiant de la rubrique parent. $id_rubrique = 1; // Excution de la requte dappel de la procdure. $sql = "CALL ps_lire_sous_rubriques($id_rubrique)"; $requte = mysqli_query($db,$sql); while ($ligne = mysqli_fetch_assoc($requte)) { echo $ligne[titre],<br />; } // Dconnexion. $ok = mysqli_close($db); ?> Rsultat MySQL Oracle ScriptPHP(requteprpare) <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Identifiant de la rubrique parent. $id_rubrique = 1; // Excution de la requte dappel de la procdure. $sql = CALL ps_lire_sous_rubriques(?); $requte = mysqli_prepare($db,$sql); $ok = mysqli_stmt_bind_param($requte,i,$id_rubrique); $ok = mysqli_stmt_execute($requte); // Important de faire le bind du rsultat aprs le execute // car la structure du rsultat nest pas connue avant. $ok = mysqli_stmt_bind_result($requte,$titre); while (mysqli_stmt_fetch($requte)) { echo $titre,<br />; } // Dconnexion. $ok = mysqli_close($db); ?> Rsultat

ENI Editions - All rigths reserved

- 21 -

MySQL Oracle

b.Fonctionstocke
Pour appeler une fonction stocke, il faut excuter lordreSQL SELECT nom_fonction(...) laide des fonctions mysqli_query ou mysqli_stmt_executepuislirelersultatlaidedesfonctionsdefetchadaptes. Danslexemple,nousappelleronsunefonctionstockequiretournelenombredesousrubriquesdunerubriquedontlidentifiant estpassenparamtre. Codesourcedelaprocdurestocke CREATE FUNCTION fs_nombre_sous_rubriques ( -- Identifiant dune rubrique (parent). p_id_parent INT ) RETURNS INT BEGIN /* ** Compter le nombre de sous-rubriques dune ** rubrique dont lidentifiant est pass ** en paramtre. */ DECLARE v_resultat INT; SELECT COUNT(*) INTO v_resultat FROM rubrique WHERE id_parent = p_id_parent; RETURN v_resultat; END; ScriptPHP(requtenonprpare) <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Identifiant de la rubrique parent. $id_rubrique = 1; // Excution de la requte qui appelle la fonction // (lexpression qui appelle la fonction est nomme avec // un alias de colonne). $sql = "SELECT fs_nombre_sous_rubriques($id_rubrique) nb"; $requte = mysqli_query($db,$sql); $ligne = mysqli_fetch_assoc($requte); echo Nombre de sous-rubriques = ,$ligne[nb]; // Dconnexion. $ok = mysqli_close($db); ?> Rsultat Nombre de sous-rubriques = 2 ScriptPHP(requteprpare) <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Identifiant de la rubrique parent. $id_rubrique = 1; // Excution de la requte qui appelle la fonction // (lexpression qui appelle la fonction est nomme avec // un alias de colonne).

- 22 -

ENI Editions - All rigths reserved

$sql = SELECT fs_nombre_sous_rubriques(?) nb; $requte = mysqli_prepare($db,$sql); $ok = mysqli_stmt_bind_param($requte,i,$id_rubrique); $ok = mysqli_stmt_execute($requte); $ok = mysqli_stmt_bind_result($requte,$nb); $ok = mysqli_stmt_fetch($requte); echo Nombre de sous-rubriques = ,$nb; // Dconnexion. $ok = mysqli_close($db); ?> Rsultat Nombre de sous-rubriques = 2

7.UtiliserlestypesdedonnesBLOB
Lireoumettrejour(insrer,modifier)desdonnesdetypeBLOBneposepasdeproblmeparticulier.

a.Insertionoumodification
Dans le cas de linsertion ou de la modification laide dune requte non prpare, il faut juste sassurer que les caractres spciauxdeladonneBLOBsontcorrectementprotgs,parexempleenluiappliquantlafonction mysqli_real_escape_string.(cf. danscechapitre"Magicquotes":leretour). Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Titre du livre dont il faut charger limage de couverture // et nom du fichier image correspondant. $titre= PHP 5.2; $fichier_image = RI52PHP.jpg; // Lecture du contenu du fichier image en sassurant quil // ny a pas dencodage "magic quotes". set_magic_quotes_runtime(0); $image = file_get_contents($fichier_image); // Protection des caractres spciaux de limage. $image = mysqli_real_escape_string($db,$image); // Excution dune requte de mise jour de limage. $sql = "UPDATE livre SET couverture = $image " . "WHERE titre = $titre"; $ok = mysqli_query($db,$sql); if ($ok) { echo Mise jour termine avec succs.; } else { echo Erreur lors de la mise jour., mysqli_error($db); } // Dconnexion. $ok = mysqli_close($db); ?> Rsultat(sitoutsepassebien) Mise jour termine avec succs. Loprationdeprotectiondescaractresspciauxnestpasncessairelorsdelutilisationdunerequteprpare.Parcontre,la donneBLOBdoittre"envoye"auserveurMySQLlaidedelafonctionmysqli_stmt_send_long_data. Syntaxe boolen mysqli_stmt_send_long_data( objet requte, entier numro_paramtre, chane donne) requte Ressourcederequteprpareretourneparlafonctionmysqli_prepare(oumysqli_stmt_init).

ENI Editions - All rigths reserved

- 23 -

numro_paramtre Numroduparamtreauquellesdonnessontassocies(0pourlepremierparamtre). donne Chanedecaractrescontenantlesdonnesenvoyer. Lafonctionmysqli_stmt_send_long_dataretourneTRUEencasdesuccsetFALSEencasderreur. Silalongueurdeladonneenvoyerexcdelalimite max_allowed_packetdeMySQL,cettefonctionpeuttreappeleplusieurs foispourenvoyerlesdonnesparpaquetdetailleinfrieurelalimite. Parailleurs,danslappellafonctionmysqli_stmt_bind_param,ilfaututiliserlalettreb(binaire)pourspcifierletypedeladonne. Exemple <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Titre du livre dont il faut charger limage de couverture // et nom du fichier image correspondant. $titre= PHP 5.2; $fichier_image = RI52PHP.jpg; // Lecture du contenu du fichier image en sassurant quil // ny a pas dencodage "magic quotes". set_magic_quotes_runtime(0); $image = file_get_contents($fichier_image); // Prparation de la requte de mise jour de limage. $sql = UPDATE livre SET couverture = ? . WHERE titre = ?; $requte = mysqli_prepare($db,$sql); $ok = mysqli_stmt_bind_param($requte,bs,$image,$titre); // Envoi des donnes de limage. $ok = mysqli_stmt_send_long_data($requte,0,$image); // Excution de la requte. $ok = mysqli_stmt_execute($requte); if ($ok) { echo Mise jour termine avec succs.; } else { echo Erreur lors de la mise jour., mysqli_stmt_error($requte); } // Dconnexion. $ok = mysqli_close($db); ?>

b.Lecture
LalecturedunedonnedetypeBLOBnencessitepasdoprationparticulire,lexception,ventuellement,delajustementdela directivedeconfigurationPHPmemory_limit. La directive memory_limit dtermine la quantit de mmoire maximum quun script est autoris utiliser. La valeur par dfaut dpenddelaversiondePHP(128Moenversion5.2.4,8Moavantlaversion5.2.0). Cettedirectivepeuttremodifietemporairementpourunscriptlaidedelafonctionini_set. Exemple ini_set(memory_limit,32M); Danslecasdelutilisationdunerequteprpare,lorsdelappellafonction mysqli_stmt_bind_result,ilsemblequePHPalloue unevariablepourladonneBLOBdunetaillegalelataillemaximumpossibledutype(parexemple16Mopourunedonnesde typeMEDIUMBLOB).Sicettetailleestsuprieurelavaleurdeladirectivememory_limit,uneerreurseproduit(mmesiladonne lire est en fait infrieure la limite) : Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 16777216 bytes) .... Exemple(requtenonprpare) <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); }

- 24 -

ENI Editions - All rigths reserved

// Titre du livre dont il faut afficher limage // de couverture et type MIME de limage (ici JPEG). $titre= PHP 5.2; $type_mime = image/jpeg; // Excution dune requte de lecture de limage. $sql = "SELECT couverture FROM livre WHERE titre = $titre"; $requte = mysqli_query($db,$sql); $ligne = mysqli_fetch_assoc($requte); // Dconnexion. $ok = mysqli_close($db); // Envoi de limage au navigateur (le type MIME de limage // est communiqu au navigateur laide de la fonction // header). header("Content-type: $type_mime"); echo $ligne[couverture]; ?> Rsultat

Exemple(requteprpare) <?php // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Titre du livre dont il faut afficher limage // de couverture et type MIME de limage (ici JPEG). $titre= PHP 5.2; $type_mime = image/jpeg; // Par prcaution, augmentation de la valeur de la // directive memory_limit. ini_set(memory_limit,32M); // Excution dune requte de lecture de limage. $sql = SELECT couverture FROM livre WHERE titre = ?; $requte = mysqli_query($db,$sql); $requte = mysqli_prepare($db,$sql); $ok = mysqli_stmt_bind_param($requte,s,$titre); $ok = mysqli_stmt_bind_result($requte,$image); $ok = mysqli_stmt_execute($requte); $ok = mysqli_stmt_fetch($requte); // Dconnexion. $ok = mysqli_close($db); // Envoi de limage au navigateur (le type MIME de limage // est communiqu au navigateur laide de la fonction // header). header("Content-type: $type_mime"); echo $image; ?> Rsultat

ENI Editions - All rigths reserved

- 25 -

- 26 -

ENI Editions - All rigths reserved

UtilisationdelextensionMySQL
Toutes les fonctions prsentes prcdemment dans lextension MySQLi, lexception des fonctions relatives aux requtes prpares, ont un quivalent direct dans lextension MySQL il suffit de remplacer le prfixe mysqli_ par mysql_ : MySQLi MySQL Syntaxe Voirremarque1 Voirremarque2 Voirremarque3 Voirremarque3 Identique Identique Identique Identique Identique Voirremarque2 Voirremarque2 Voirremarque2 Voirremarque2

mysqli_connect mysqli_close mysqli_select_db mysqli_query mysqli_num_rows mysqli_fetch_array mysqli_fetch_array mysqli_fetch_object mysqli_fetch_row mysqli_affected_rows mysqli_insert_id mysqli_errno mysqli_error
Remarques 1

mysql_connect mysql_close mysql_select_db mysql_query mysql_num_rows mysql_fetch_array mysql_fetch_array mysql_fetch_object mysql_fetch_row mysql_affected_rows mysql_insert_id mysql_errno mysql_error

Lespremiersparamtresdemysql_connectetmysqli_connectsontidentiques(serveur,utilisateur,motdepasse) les paramtressuivantssontdiffrents.Lafonctionmysql_connectnepermetpasdeslectionnerlabasededonnes utiliserdslaconnexion. 2 LextensionMySQLpermetdutiliseruneconnexionpardfautdanslesappelsdefonctions(ladernireconnexion ouverte).Enconsquence,lidentifiantdeconnexionestoptionneldanslesfonctionsmysql_close,mysql_affected_rows, mysql_insert_id,mysql_errnoetmysql_error. 3 Pourlesfonctionsmysql_select_dbetmysql_querylasyntaxeestinverse :lidentifiantdeconnexionestpassen deuximeparamtre,etildevientfacultatif(utilisationdeladernireconnexionouverteencasdomission). Les fonctions mysql_connect et mysql_query retournent des ressources et non des objets. Dans la pratique, cela na aucuneincidencecarlersultatdecesfonctionsestsimplementpassenparamtredautresfonctions. Lextension MySQL noffre pas de fonctions quivalentes aux fonctions mysqli_connect_error et mysqli_connect_errno qui permettent de rcuprer des informations sur une ventuelle erreur de connexion. Par contre, les fonctions mysql_error et mysql_errno peuvent tre appeles pour rcuprer des informations sur une ventuelle erreur de connexion. LextensionMySQLoffreparailleursunefonction mysql_unbuffered_queryquiproposelammesyntaxequelafonction mysql_query, et permet dexcuter une requte mais sans placer le rsultat dans un buffer. Le fonctionnement est

ENI Editions - All rigths reserved

- 1-

identiquelappeldemysqli_queryenpassantlaconstanteMYSQLI_USE_RESULTcommetroisimeparamtre. Exemple <?php // Dfinir quelques variables. $serveur = localhost; $utilisateur = eniweb; $mot_de_passe = web; $base = eni; // Connexion = mysql_connect // Pas de slection de la base dans cet appel. $db = mysql_connect($serveur,$utilisateur,$mot_de_passe); // Vrifier le succs de la connexion if (mysql_errno() != 0) { printf( Erreur mysql_connect : %d - %s<br />, mysql_errno(),mysql_error()); exit; } // Slectionner la base = mysql_select_db // Diffrences par rapport mysqli_select_db : // > syntaxe inverse // > identifiant de connexion optionnel $ok = mysql_select_db($base,$db); if (! $ok) { printf( Erreur mysql_connect : %d - %s<br />, mysql_errno(),mysql_error()); exit; } // Excuter une requte = mysql_query // Diffrences par rapport mysqli_query : // > syntaxe inverse // > identifiant de connexion optionnel // > pas de troisime paramtre $sql = SELECT * FROM collection LIMIT 4; $requte = mysql_query($sql, $db); if (! $requte) { printf( Erreur mysql_connect : %d - %s<br />, mysql_errno(),mysql_error()); exit; } // Dterminer le nombre de lignes du rsultat = mysql_num_rows // Identique mysqli_num_rows. printf("Nombre de collections = %s<br />\n", mysql_num_rows($requte)); // Rcuprer le rsultat = mysql_fetch_* // Diffrences par rapport mysqli_fetch_* : // > constantes MYSQL_NUM, MYSQL_ASSOC, MYSQL_BOTH // dans mysql_fetch_array $ligne = mysql_fetch_array($requte, MYSQL_ASSOC); printf( "Premire collection = %s - %s<br />\n", $ligne[nom],$ligne[prix_ht]); // Excuter une requte = mysql_query // Exemple avec INSERT. $sql = "INSERT INTO collection(nom,prix_ht) " . "VALUES(Open IT,5)"; $requte = mysql_query($sql, $db); // Rcuprer lidentifiant gnr = mysql_insert_id // Diffrences par rapport mysqli_insert_id : // > identifiant de connexion optionnel printf( "Identifiant de la nouvelle collection = %s<br />\n", mysql_insert_id($db)); // Excuter une requte = mysql_query // Exemple avec UPDATE.
- 2 ENI Editions - All rigths reserved

$sql = "UPDATE collection SET prix_ht = 5.69 " . "WHERE nom = Open IT"; $requte = mysql_query($sql, $db); // Rcuprer le nombre de lignes mises jour = // mysql_affected_rows // Diffrences par rapport mysqli_affected_rows : // > identifiant de connexion optionnel printf( "Nombre de collection(s) modifie(s) = %s<br />\n", mysql_affected_rows($db)); // Dconnexion = mysql_close // Diffrences par rapport mysqli_close : // > identifiant de connexion optionnel mysql_close($db); ?> Rsultat Nombre de collections = 4 Premire collection = Ressources Informatiques - 25.66 Identifiant de la nouvelle collection = 11 Nombre de collection(s) modifie(s) = 1

ENI Editions - All rigths reserved

- 3-

PHPDataObjects(PDO)
PHP Data Objects (PDO) est une extension apparue en version 5.1 qui dfinit une interface uniforme pour accder aux basesdedonnesenPHP.LaccsunebasededonnestraversPDOseffectueparlintermdiaire dundriverqui exposelesfonctionnalitsdelabasededonnes. IlfautbiennoterquePDOnefournitpasunecouchedabstractiondelabasededonnesmaisunecouchedabstraction delaccsauxbasesdedonnes.Lesrequtesquevouscrivezdoiventrespecterlasyntaxedelabasededonnes quevousutilisez PDOnercritpaslesrequtesSQLetnmulepaslesfonctionnalitsmanquantes(lexceptiondes requtesparamtres). DenombreusesbasesdedonnesdisposentdundriverPDOparmilesquellesMySQL,Oracle,MicrosoftSQLServeret SQLite. PDOestuneextensionorienteobjetquipropose3classes :
q

PDO :connexionentrePHPetlabasededonnes, PDOStatement :requteprpare,et,aprsexcution,rsultatassoci, PDOException :exceptionleveparPDO.

Danscechapitre,nousprsenteronscetteextensionparlintermdairedunsimpleexemplecomment : <?php // Dfinition des paramtres de connexion. // La syntaxe de la source (Data Source Name ou DSN) // est spcifique chaque driver. $source = mysql:host=localhost;dbname=eni; $utilisateur = eniweb; $mot_de_passe = web; // Dfinition de deux requtes de test. // Noter que la requte dinsertion est paramtre (cest // en fait la seule fonctionnalit qui est mule par PDO, // si elle nest pas nativement supporte par la base de // donnes). $sql_select = SELECT * FROM collection; $sql_insert = INSERT INTO collection(nom,prix_ht) . VALUES(:p1,:p2); // Toutes les oprations sont effectues dans un bloc // try afin de rcuprer les exceptions leves par PDO. try { // Connexion la base de donnes. $db = new PDO($source, $utilisateur, $mot_de_passe); // Modification des paramtres de la connexion pour // demander que des exceptions soient leves en cas // derreur. $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); // Prparer une requte pour linsertion. $st = $db->prepare($sql_insert); // Lier les paramtres. $st->bindParam(:p1,$nom); $st->bindParam(:p2,$prix_ht); // Affecter une valeur aux variables. $nom = Mega +; $prix_ht = 21.38; // Excuter la requte. // Pour les bases de donnes qui supportent les transactions, // les mthodes beginTransaction(), commit() et rollback() // des objets PDO peuvent tre utilises. $st->execute(); // Prparer une requte pour la slection. $st = $db->prepare($sql_select); // Excuter la requte. $st->execute(); // Rcuprer le rsultat. // Plusieurs mthodes sont disponibles pour rcuprer
ENI Editions - All rigths reserved - 1-

// le rsultat : fetch(), fetchObject(), fetchAll(). // La mthode fetch() dispose dun paramtre qui permet // de spcifier le type de rsultat (tableau, objet, etc.). while ($ligne = $st->fetch()) { echo "$ligne[1] - $ligne[2]<br />\n"; } // Librer les resources. $st = null; $db = null; } catch (PDOException $e) { // Grer les exceptions echo Error!: ,$e->getMessage(),<br />; die(); } ?> Rsultat Ressources Informatiques - 25.66 TechNote - 9.95 Les TP Informatiques - 25.59 Coffret Technique - 46.45 Coffret Solutions - 55.92 Epsilon - 51.18 Expert IT - 36.97 Solution Informatiques - 20.00 Objectif Solutions - 19.86 Open IT - 5.69 Mega + - 21.38

- 2-

ENI Editions - All rigths reserved

"Magicquotes" :leretour
1.Prambule
NousavonsvudanslechapitreUtiliserlesfonctionsPHPquePHPproposeunefonctionnalit,appele"magicquotes", dontlobjectifprincipalestdersoudreunproblmelilenregistrementdesdonnesdansunebasededonnes,en effectuantunencodagesurlesdonnessaisiesdansunformulaire. Exemple(insertiondansunebasededonnesMySQLdunedonnequicontientuneapostrophe) <?php // Donne qui pose problme (peut tre saisie innocemment // dans un formulaire). $nom = " L A t o u t Russite"; $prix_ht = 10; // Requte dinsertion. $sql = "INSERT INTO collection(nom,prix_ht) " . "VALUES($nom,$prix_ht)"; echo $sql,<br />; // Excution. $db = mysqli_connect(localhost,eniweb,web,eni); $requte = mysqli_query($db,$sql); echo mysqli_error($db),<br />; // Dconnexion. $ok = mysqli_close($db); ?> Rsultat INSERT INTO You have an corresponds to use near collection(nom,prix_ht) VALUES(LAtout Russite,10) error in your SQL syntax; check the manual that to your MySQL server version for the right syntax Atout Russite,10) at line 1

EnSQL,ledlimiteurdechanedecaractresestlapostrophe :siunerequteenvoielachane LAtout Russite labase,cettedernirevainterprterLcommeunechaneetnesaurapasquoifairedureste( Atout Russite). Pour rgler ce problme, il faut indiquer la base que les apostrophes lintrieur de la chane ne sont pas les dlimiteursdelachane,gnralementenfaisantprcderlapostropheduncaractre"magique"("dchappement") : cestlecaractreantislash(\)ouapostrophe( )pourMySQL. Exemple <?php // Donne corrige. $nom = " L \ A t o u t Russite"; $prix_ht = 10; // Requte dinsertion. $sql = "INSERT INTO collection(nom,prix_ht) " . "VALUES($nom,$prix_ht)"; echo $sql,<br />; // Excution. $db = mysqli_connect(localhost,eniweb,web,eni); $requte = mysqli_query($db,$sql); echo mysqli_error($db),<br />; // Dconnexion. $ok = mysqli_close($db); ?> Rsultat INSERT INTO collection(nom,prix_ht) VALUES(L\Atout Russite,10) Lafonctionnalit"magicquotes"dencodageautomatiquerpondcetteproblmatique :sielleestactive(directivede configuration magic_quotes_gpc = on),touteslesdonnesissuesdunformulaire(mthodes GETou POST), duneURL (mthodeGET)ouduncookiesontautomatiquementencodesaveclecaractreantislash(\),ouapostrophe()sila
ENI Editions - All rigths reserved - 1-

directivedeconfigurationmagic_quotes_sybaseeston. Malheureusement,nousavonsvuquecettefonctionnalit"magicquotes"posaitdautresproblmesvisvis :
q

delaffichagedesdonnesdanslapageHTML deladpendancepotentielleducodedesdirectivesdeconfiguration.

Pour mmoire, la solution propose consiste sassurer que les donnes sont charges dans des variables sans encodageetfairecequilfautaumomentdelenregistrementdanslabase cestcequenousallonsvoirdansce chapitre.

2.Chargementdesdonnesenprovenancedunebase
CommenouslavonsvudanslechapitreUtiliserlesfonctionsPHP,lorsqueladirective magic_quotes_runtimeest on, uneprotection"magicquotes"estautomatiquementappliqueauxdonnesluesdansunebasededonnesMySQL. En complment, la fonction get_magic_quotes_runtime permet de connatre la valeur de la directive magic_quotes_runtimeetlafonctionset_magic_quotes_runtimedelamodifierencoursdescript. Exemple <?php // Requte de test. $sql = "SELECT LAtout Russite data"; // Connexion. $db = mysqli_connect(localhost,eniweb,web,eni); // Affichage de la valeur de la directive magic_quotes_runtime. $mqr = get_magic_quotes_runtime(); echo "<b>magic_quotes_runtime = $mqr</b><br />"; // Excution de la requte et affichage du rsultat. $requte = mysqli_query($db,$sql); $ligne = mysqli_fetch_assoc($requte); echo $ligne[data],<br />; // Modification de la valeur de la directive // magic_quotes_runtime. $mqr = ($mqr == 1)?0:1; set_magic_quotes_runtime($mqr); echo "<b>magic_quotes_runtime = $mqr</b><br />"; // Excution de la requte et affichage du rsultat. $requte = mysqli_query($db,$sql); $ligne = mysqli_fetch_assoc($requte); echo $ligne[data],<br />; // Dconnexion. $ok = mysqli_close($db); ?> Rsultat magic_quotes_runtime = 0 LAtout Russite magic_quotes_runtime = 1 L\Atout Russite Lafonction set_magic_quotes_runtimeestparticulirementintressanteavecMySQLpourcrireuncodeindpendant delaconfiguration :avantchaqueexcutiondunerequteSELECT,ilsuffitdappelercettefonctionaveclavaleur0ou 1correspondantlastratgiequevousavezadopte. Dans le mme ordre dide, un appel du type set_magic_quotes_runtime(get_magic_quotes_gpc()) permet dobtenir, pourlesdonnesissuesdelabase,lemmecomportementquepourlesdonnesGPC.

3.Misejourdesdonnesdanslabase
Pourlamisejourdesdonnesdanslabase,ilfautsassurerquetouteslesdonnesdetype"texte"ontlecaractre dchappementadapt( \oupourMySQL)devantchaqueapostrophe.

- 2-

ENI Editions - All rigths reserved

Sivousavezadoptunestratgiedanslaquelletouteslesvariablescontiennentdesdonnesencodes,ilnyarien faire. linverse,sivousavezadoptunestratgie(recommandedanscetouvrage)danslaquelletouteslesvariablesne contiennent pas de donnes encodes, il convient dassurer lchappement des apostrophes dans les donnes envoyeslabase. Lafonctionmysqli_real_escape_stringpeuttreutilisepourcela. Syntaxe chane mysqli_real_escape_string( objet connexion, chane valeur) Avec connexion Identifiantdeconnexionretournparlafonctionmysqli_connect. valeur Chanedecaractresprotger. La fonction mysqli_real_escape_string ajoute un antislash(\) devant tous les caractres apostrophe ( ),guillemet ("),antislash(\),NUL(ASCII0),retourlaligne(\n)etretourchariot(\r)trouvsdanslachanevaleur. L eparamtrevaleurnedoitpasdjtreprotg.

Exemple <?php // Donne qui pose problme (peut tre saisie innocemment // dans un formulaire). $nom = " L A t o u t Russite"; $prix_ht = 10; // Connexion. $db = mysqli_connect(localhost,eniweb,web,eni); // Dfinition de la requte avec protection des donnes // de type "texte". $sql = sprintf( "INSERT INTO collection(nom,prix_ht) VALUES(%s,%s)", m y s q l i _ e s c a p e _ s t r i n g ( $ d b , $ n o m ) ,$prix_ht); echo $sql,<br />; // Dconnexion. $ok = mysqli_close($db); ?> Rsultat INSERT INTO collection(nom,prix_ht) VALUES(L\Atout Russite,10) Il est possible dcrire une fonction gnrique, dans le mme esprit que la fonction sprintf, en marquant lemplacement des paramtres par une squence %n, n valant 1 pour le 1er paramtre, 2 pour le deuxime... Cette fonctionaccepteunnombrevariabledeparamtres,lepremiertantlaconnexionutiliser,ledeuximelastructure delarequteetlessuivantslesvaleursdesparamtresdanslordredenumrotation. Exemple <?php function construire_requte($db,$sql) { // Rcuprer le nombre de paramtres. $nombre_param = func_num_args(); // Boucler sur tous les paramtres partir du troisime. for($i=2;$i<$nombre_param;$i++) { // Rcuprer la valeur du paramtre. $valeur = func_get_arg($i); // Si cest une chane, lchapper.

ENI Editions - All rigths reserved

- 3-

if (is_string($valeur)) { $valeur = mysqli_escape_string($db,$valeur); } // Mettre la valeur son emplacement %n (n = $i-1). $sql = str_replace(%.($i-1),$valeur,$sql); } // Retourner la requte. return $sql; } // Des variables contiennent des valeurs venant // de quelque part ... $nom = " L A t o u t Russite"; $prix_ht = 10; // Connexion. $db = mysqli_connect(localhost,eniweb,web,eni); // Construction de la requte. $sql = construire_requte( $db, " INSERT INTO collection(nom,prix_ht) VALUES(%1,%2)", $nom, $prix_ht); echo $sql,<br />; // Dconnexion. $ok = mysqli_close($db); ?> Rsultat INSERT INTO collection(nom,prix_ht) VALUES(L\Atout Russite,10)

Ilnyapasdeproblmedecetypelorsdelutilisationderequtesparamtres. Exemple <?php // Des variables contiennent des valeurs venant // de quelque part ... $nom = " L A t o u t Russite +"; $prix_ht = 10; // Connexion. $db = mysqli_connect(localhost,eniweb,web,eni); // Execution dune requte dinsertion. $sql = INSERT INTO collection(nom,prix_ht) VALUES(?,?); $requte = mysqli_prepare($db,$sql); $ok = mysqli_stmt_bind_param($requte,sd,$nom,$prix_ht); $ok = mysqli_execute($requte); if ($ok) { echo mysqli_stmt_affected_rows($requte), collection insre<br />; } else { echo mysqli_stmt_error($requte),<br />; } // Dconnexion. $ok = mysqli_close($db); ?> Rsultat 1 collection insre.

- 4-

ENI Editions - All rigths reserved

Exemplesdintgrationdansdesformulaires
1.Vuedensemble
Pourterminercechapitre,nousallonsprsenterquelquesexemplesdaccsunebasededonnesMySQLpartirde formulaires. Troisexemplessontproposs :
q

unformulairequipermetdesaisirdesdonnesdansuneliste unformulairederechercheavecaffichagedursultat unformulairedesaisiedetype"page".

Pour des raisons de concision, dans ces exemples, le contrle de la saisie et la gestion derreur sont pratiquement absents,etlamiseenformeesttrssimple.

2.Formulairedesaisieenliste
Prsentationduformulaire

Leformulaireproposelecontenuactueldelatablequipeuttremodifi(saisiedirectedansleszones)ousupprim (par les cases cocher), plus cinq lignes vides qui permettent de saisir de nouvelles valeurs. Dans tous les cas, lidentifiantnepeutpastresaisi,cestleserveurMySQLquivalattribuer. Chaque ligne du tableau contient 4 zones de formulaire qui sont nommes (attribut namedelabalise <input>) de la maniresuivante : Colonne Identifiant Nom PrixH.T. Nom

saisie[i][modifier] saisie[i][nom] saisie[i][prix_ht]


ENI Editions - All rigths reserved - 1-

Supprimer

saisie[i][supprimer]

Lindiceiestlidentifiantdelacollectionpourleslignesquiexistentetunnumrocomprisentre1et5pourleslignes vides.Lazonedelacolonne Identifiantestunezonemasque( type="hidden")quivatreemployepouridentifier leslignesdanslesquelleslutilisateuraeffectuunemodification. Avec ce processus de nommage, toute la saisie est rcupre dans le script PHP sous la forme dun tableau multidimensionnel.Chaquelignedutableaucorresponduneligneduformulaireaveclaclgallidentifiant(ou1 5pourlesnouvelleslignes)etlavaleurgaleuntableauassociatifdonnantleslmentssaisis. Pour identifier les lignes modifies par lutilisateur, les zones de saisie du nom et du prix des lignes existantes contiennentlecodeJavaScriptsuivant : onChange="document.formulaire[$n].value=1" CepetitboutdecodeJavaScriptapoureffet,chaquefoisquelazoneenquestionestmodifie,demettreun1dans la zone masque associe la ligne. Le formulaire sappelant formulaire (<form name = "formulaire"...), lexpression document.formulaire[n] dsigne la nime zone du formulaire formulaire du document courant, la premirezoneduformulaireayantlenumro0.Danslecodesource,lavariable $nestcalculepourchaqueligne $i du formulaire par la formule $n = 4 * ($i - 1) : la zone cache de la ligne 1 a le numro 0 (cest la premire du formulaire),celledelaligne2lenumro4etainsidesuite. Cetexemplepeut(doit)treamlior :
q

pourcontrlerlasaisiedelutilisateur pourgrerleserreurs.

Source <?php // Inclusion du fichier qui contient les fonctions gnrales. include(fonctions.inc); // Connexion. $db = mysqli_connect(localhost,eniweb,web,eni); // Traitement du formulaire. if (isset($_POST[ok])) { // Supprimer la protection "magic quotes" ventuelle // des tableaux GPC. supprimer_encodage_MQ_GPC(); // Rcuprer le tableau contenant la saisie. $lignes = $_POST[saisie]; foreach($lignes as $id => $ligne) { // Nettoyage de la saisie. $nom = trim($ligne[nom]); // Pour le prix, remplacer la virgule par un point // et supprimer les espaces. $prix_ht = str_replace(,,.,$ligne[prix_ht]); $prix_ht = str_replace( ,,$prix_ht); // A ce stade, il faudrait vrifier la saisie ... // Dfinition de la requte excuter. // Pour chaque action, nous allons utiliser une requte // prpare. Lorsquun cas est rencontr pour la premire // fois, il faut prparer la requte et lier les variables. $requte = NULL; if ($id < 0 and $nom.$prix_ht != ) { // Identifiant ngatif et quelque chose de saisi // = cration = INSERT if (! $req_ins) { $sql = INSERT INTO collection(nom,prix_ht) . VALUES(?,?); $req_ins = mysqli_prepare($db,$sql); $ok = mysqli_stmt_bind_param ($req_ins,sd,$nom,$prix_ht); } $requte = $req_ins; } elseif (isset($ligne[supprimer])) { // Case "supprimer" coche = suppression = DELETE
- 2 ENI Editions - All rigths reserved

if (! $req_del) { $sql = DELETE FROM collection WHERE id = ?; $req_del = mysqli_prepare($db,$sql); $ok = mysqli_stmt_bind_param($req_del,i,$id); } $requte = $req_del; } elseif ($ligne[modifier]==1) { // Zone "modifier" TRUE (1) = modification = UPDATE if (! $req_upd) { $sql = UPDATE collection . SET nom = ?, prix_ht = ? . WHERE id = ?; $req_upd = mysqli_prepare($db,$sql); $ok = mysqli_stmt_bind_param ($req_upd,sdi,$nom,$prix_ht,$id); } $requte = $req_upd; } // Si une requte a t dfinie, lexcuter. if ($requte) { $ok = mysqli_execute($requte); // A ce stade, il faudrait tester les erreurs ... } } } // Recharger les collections (ici avec une requte // non prpare). $sql = SELECT * FROM collection; $rsultat = mysqli_query($db,$sql); // A ce stade, il faudrait tester les erreurs ... // Affichage de la page ... ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Gestion des collections</title></head> <body> <!-- construction dune table HTML lintrieur ++++ dun formulaire --> <form action="saisie-liste.php" name="formulaire" method="post"> <table border="1" cellpadding="4" cellspacing="0"> <!-- ligne de titre --> <tr align="center"> <th>Identifiant</th><th>Nom</th><th>Prix H.T.</th> <th>Supprimer</th> </tr> <?php // Code PHP pour les lignes du tableau. if ($rsultat) { // Sil y a un rsultat afficher // Initialisation dun compteur de ligne. $i = 0; // Boucle de fetch. while ($ligne = mysqli_fetch_assoc($rsultat)) { // Incrmentation du compteur de ligne. $i++; // Calcul du numro dordre dans le formulaire de la // zone cache correspondant lidentifiant. $n = 4 * ($i - 1); // Mise en forme des donnes. $ligne[nom] = vers_page($ligne[nom]); $ligne[prix_ht] = vers_page (number_format($ligne[prix_ht],2,"," ," ")); // Gnration de la ligne de la table HTML. // Insertion des balises INPUT du formulaire. printf( "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>", "$ligne[id] <input type=\"hidden\"

ENI Editions - All rigths reserved

- 3-

name=\"saisie[$ligne[id]][modifier]\" />", "<input type=\"text\" name=\"saisie[$ligne[id]][nom]\" value=\"$ligne[nom]\" onchange=\"document.formulaire[$n].value=1\" />", "<input type=\"text\" name=\"saisie[$ligne[id]][prix_ht]\" value=\"$ligne[prix_ht]\" onchange=\"document.formulaire[$n].value=1\" />", "<input type=\"checkbox\" name=\"saisie[$ligne[id]][supprimer]\" value=\"$ligne[id]\" />"); } // while // Ajout de 5 lignes vides pour la cration // (sans identifiant, sans case de suppression). for($i=1;$i<=5;$i++) { printf( "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>", "", "<input type=\"text\" name=\"saisie[-$i][nom]\" value=\"\" />", "<input type=\"text\" name=\"saisie[-$i][prix_ht]\" value=\"\" />", ""); } // for } ?> </table> <p><input type="submit" name="ok" value="Enregistrer" /></p> </form> </body> </html>

3.Formulairederecherche
Prsentationduformulaire
q

Affichageinitial :

Rsultatdunerecherche :

- 4-

ENI Editions - All rigths reserved

Leformulairederechercheesttrssimple:ileffectueunerechercheentexteintgralsuruntextesaisidanslunique zone.Lersultatestaffichsouslaformedunelisteaveclimagedecouverturedulivreetquelquesinformationssur lelivre. Pour que la recherche en texte intgral fonctionne, il faut crer un index FULLTEXT (cf. chapitre Techniques avances avecMySQLEffectuerdesrecherchesentexteintgral). Exemple mysql> CREATE FULLTEXT INDEX ix_texte -> ON livre(titre,sous_titre,description); Query OK, 9 rows affected (0.01 sec) Records: 9 Duplicates: 0 Warnings: 0 Source <?php // Inclusion du fichier qui contient les fonctions gnrales. include(fonctions.inc); // Variable pour un ventuel message. $message = ; // Traitement du formulaire. if (isset($_POST[ok])) { // Supprimer la protection "magic quotes" ventuelle // des tableaux GPC. supprimer_encodage_MQ_GPC(); // Rcuprer le texte saisi. $recherche = $_POST[recherche]; if (empty($recherche)) { $message = Vous devez saisir le texte recherch.; } else { // Connexion. // Utilisation de loprateur @ pour masquer les alertes. $db = @mysqli_connect(localhost,eniweb,web,eni); if ($db === FALSE) { $message = Erreur de connexion la base de donnes.;

ENI Editions - All rigths reserved

- 5-

} else { // Excuter la requte de recherche. $sql = SELECT liv.id,liv.titre,liv.sous_titre,col.nom . FROM livre liv JOIN collection col . ON (liv.id_collection = col.id) . WHERE MATCH(titre,sous_titre,description) . AGAINST(?); if ($requte = mysqli_prepare($db,$sql)) { $ok = mysqli_stmt_bind_param($requte,s,$recherche); if ($ok) { $ok = mysqli_stmt_bind_result ($requte,$id,$titre,$sous_titre,$collection); } if ($ok) { $ok = mysqli_execute($requte); } if (! $ok) { $message = mysqli_stmt_error($requte);} } else { $message = mysqli_error($db); } if ($message) { $message = "Erreur lors de la recherche ($message)."; } } } } // Affichage de la page ... ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Rechercher un livre</title></head> <body> <!-- Formulaire de recherche (trs simple !) --> <form action="recherche-livre.php" method="post"> <div>Rechercher : <input type="text" name="recherche" value="<?php echo vers_formulaire($recherche) ?>" /> <input type="submit" name="ok" value="OK" /></div> </form> <!-- Rsultat de la recherche --> <?php // Compteur du nombre de livres trouvs. $nombre_livres = 0; if ($requte) { // Sil y a un rsultat afficher // Balise douverture de la table HTML. echo <table border="0" cellpadding="4">,"\n"; // Boucle de fetch. while (mysqli_stmt_fetch($requte)) { $nombre_livres++; // Mise en forme des donnes. $titre = vers_page($titre); $sous_titre = vers_page($sous_titre); $collection = vers_page($collection); // Gnration de la ligne de la table HTML. // Limage est affiche par appel un autre script. printf( "<tr><td>%s</td><td>%s<br />%s<br />%s</td></tr>\n", "<img alt=\"\" src=\"image-livre.php?id=$id\" />", "<b>$titre</b>", $sous_titre, "Collection : $collection"); } // while // Balise de fermeture de la table HTML. echo </table>,"\n"; // Si le rsultat est vide, afficher un message. if ($nombre_livres == 0) { $message = Aucun livre trouv.; } } // if ($requte) ?>

- 6-

ENI Editions - All rigths reserved

<div><?php echo vers_page($message); ?></div> </body> </html> Limageestaffichelaidedundeuximescript. Source <?php // Rcupration de lidentifiant du livre dont il faut // afficher limage de couverture : pass dans lURL. // Utilisation dun filtre pour sassurer que la valeur // passe est bien un entier. $id = filter_input(INPUT_GET,id,FILTER_VALIDATE_INT); // Le filtre a "chou" : quitter le script. if ($id === FALSE OR $id === NULL) { exit(Paramtre invalide ou absent.); } // Connexion et slection de la base de donnes. $db = mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Echec de la connexion.); } // Type MIME des images. $type_mime = image/jpeg; // Excution dune requte de lecture de limage. $sql = "SELECT couverture FROM livre WHERE id = $id"; $requte = mysqli_query($db,$sql); $ligne = mysqli_fetch_assoc($requte); // Dconnexion. $ok = mysqli_close($db); // Envoi de limage au navigateur (le type MIME de limage // est communiqu au navigateur laide de la fonction // header). header("Content-type: $type_mime"); echo $ligne[couverture]; ?>

4.Formulairedesaisie
Prsentationduformulaire
q

Affichageinitial :

Livreaffichdansleformulaire :

ENI Editions - All rigths reserved

- 7-

Lepetitformulaireaffichenhautdelapagepermetdesaisirlidentifiantdulivrequilfautmodifier lorquelutilisateur cliquesurleboutonCharger,lelivreestchargdansleformulaire. Le bouton Enregistrer permet denregistrer les modifications dans la base. Une fois enregistr le livre est recharg dansleformulairepourcontrle. Le bouton Parcourir permet de slectionner un fichier qui sera stock dans la base et associ comme image de couvertureaulivre.Lorsquuneimagedecouvertureestassocieaulivre,celleciestaffichedansleformulaire,avec lammetechniquequedansleformulairederecherche. Exemple

Source <?php // Inclusion du fichier qui contient les fonctions gnrales. include(fonctions.inc); // Pas de protection "magic quotes" pour les donnes lues dans // la base de donnes ou dans les fichiers. set_magic_quotes_runtime(0); // Suppression de la protection "magic quotes" ventuelle // des tableaux GPC. supprimer_encodage_MQ_GPC(); // Variables qui indiquent si un livre doit tre charg et/ou

- 8-

ENI Editions - All rigths reserved

// si un livre doit tre enregistr. $charger_livre = FALSE; $enregistrer_livre = FALSE; // Variable pour un ventuel message. $message = ; // Tester si le script est appel en traitement dun formulaire. if (isset($_POST[charger]) OR isset($_POST[ok])) { // oui // Rcuprer lidentifiant du livre. // Utilisation dun filtre pour sassurer que la valeur // rcupre est bien un entier. $id_livre = filter_input(INPUT_POST,id,FILTER_VALIDATE_INT); // Identifiant absent ou invalide => message. // Sinon, dterminer laction effectuer. if ($id_livre === FALSE OR $id_livre === NULL) { $message = Identifiant absent ou invalide.; } else { $enregistrer_livre = isset($_POST[ok]); $charger_livre = // enregistrer => rechargement (isset($_POST[charger]) OR $enregistrer_livre); } } // Connexion si ncessaire. if ($charger_livre OR $enregistrer_livre) { // Utilisation de loprateur @ pour masquer les alertes. $db = @mysqli_connect(localhost,eniweb,web,eni); // En cas derreur, on arrte tout. if ($db === FALSE) { $message = Erreur de connexion la base de donnes.; $charger_livre = FALSE; $enregistrer_livre = FALSE; } } // Sil y a un livre enregistrer ... if ($enregistrer_livre) { // Rcuprer le contenu du formulaire. // Il faudrait vrifier la saisie ... $livre = $_POST; // Enregistrement du livre. $sql = UPDATE livre SET . isbn = ?, . titre = ?, . sous_titre = ?, . nombre_pages = ?, . annee_parution = ?, . niveau = ?, . id_collection = ?, . description = ? . WHERE id = ?; if ($ok = ($req_maj = mysqli_prepare($db,$sql))) { $ok = mysqli_stmt_bind_param ( $req_maj, sssiisisi, $livre[isbn], $livre[titre], $livre[sous_titre], $livre[nombre_pages], $livre[annee_parution], $livre[niveau], $livre[collection], $livre[description], $id_livre ); if ($ok) { $ok = mysqli_stmt_execute($req_maj); } if (! $ok) { $message = mysqli_stmt_error($req_maj);} mysqli_stmt_close($req_maj); } else { $message = mysqli_error($db); }

ENI Editions - All rigths reserved

- 9-

// Enregistrement des rubriques du livre. // Annule (DELETE) et remplace (INSERT) lexistant. if ($ok) { // Suppression des rubriques actuelles. $sql = DELETE FROM rubrique_livre WHERE id_livre = ?; if ($ok = ($req_maj = mysqli_prepare($db,$sql))) { $ok = mysqli_stmt_bind_param($req_maj,i,$id_livre); if ($ok) { $ok = mysqli_stmt_execute($req_maj); } if (! $ok) { $message = mysqli_stmt_error($req_maj);} mysqli_stmt_close($req_maj); } else { $message = mysqli_error($db); } // Insertions des nouvelles rubriques (sil y en a). if ($ok AND ($rubriques = $livre[rubriques])) { $sql = INSERT INTO rubrique_livre(id_livre,id_rubrique) . VALUES(?,?); if ($ok = ($req_maj = mysqli_prepare($db,$sql))) { $ok = mysqli_stmt_bind_param ($req_maj,ii,$_POST[id],$id_rubrique); if ($ok) { foreach ($rubriques as $id_rubrique) { $ok = mysqli_stmt_execute($req_maj); if (! $ok) { $message = mysqli_stmt_error($req_maj); break; } } } mysqli_stmt_close($req_maj); } else { $message = mysqli_error($db); } } } // Enregistrement de limage de couverture if ($ok) { // Si un fichier a t tlcharg avec succs, lire // son contenu. switch ($_FILES[couverture][error]) { case UPLOAD_ERR_NO_FILE : break; case UPLOAD_ERR_OK : $couverture = file_get_contents($_FILES[couverture][tmp_name]); if (! $couverture) { $message = problme avec l\image de couverture; } break; default : $message = image de couverture non transfre; break; } if ($couverture) { // il a bien une image ... $sql = UPDATE livre SET couverture = ? WHERE id = ?; if ($ok = $req_maj = mysqli_prepare($db,$sql)) { $ok = mysqli_stmt_bind_param ($req_maj,bi,$couverture,$_POST[id]); if ($ok) { $ok = mysqli_stmt_send_long_data ($req_maj,0,$couverture); } if ($ok) { $ok = mysqli_stmt_execute($req_maj); }; if (! $ok) { $message = mysqli_stmt_error($req_maj);} mysqli_stmt_close($req_maj); } else { $message = mysqli_error($db); } }

- 10 -

ENI Editions - All rigths reserved

} // Complter le message derreur si ncessaire. if ($message) { $message = "Erreur lors de lenregistrement du livre ($message)."; } } // Sil y a un livre charger ... if ($charger_livre) { // Charger les informations sur le livre proprement dit, // dans le tableau associatif $livre. $sql = "SELECT * FROM livre WHERE id = $id_livre"; if ($ok = ($req_liv = mysqli_query($db,$sql))) { $livre = mysqli_fetch_assoc($req_liv); if (! $livre) { $message = Aucun livre trouv.; } } // Si tout est OK ce stade, slectionner la liste // des collections (pour la liste droulante). // Le fetch sera fait plus tard. if ($ok AND $livre) { $sql = SELECT id,nom FROM collection; $ok = ($req_col = mysqli_query($db,$sql)); } // Si tout est OK ce stade, slectionner la liste // des rubriques (pour la liste de slection). // Le fetch sera fait plus tard. if ($ok AND $livre) { // La requte utilise permet davoir une colonne // selection qui est 1 lorsque la rubrique est // slectionne pour le livre. $sql = "SELECT rub.id,rub.titre,rul.selection FROM ( /* liste des sous-rubriques, sous la forme <rubrique> - <sous-rubrique> */ SELECT sru.id,CONCAT(rub.titre, - ,sru.titre) titre FROM rubrique sru JOIN rubrique rub ON (sru.id_parent = rub.id) WHERE sru.id_parent IS NOT NULL ) rub LEFT JOIN ( /* liste des rubriques slectionnes pour le livre */ SELECT id_rubrique,1 selection FROM rubrique_livre WHERE id_livre = $id_livre ) rul ON (rub.id = rul.id_rubrique)"; $ok = ($req_rub = mysqli_query($db,$sql)); } // En cas derreur, initialisation dun message et effacement // du tableau $livre. if (! $ok) { $message = Erreur lors du chargement du livre.; unset($livre); } } // Affichage de la page ... ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Saisir un livre</title></head> <body> <!-- Formulaire de saisie de lidentifiant. --> <form action="saisie-livre.php" method="post"> <div> Identifiant :

ENI Editions - All rigths reserved

- 11 -

<input type="text" name="id" size="6" value="<?php echo vers_formulaire($id_livre); ?>" /> <input type="submit" name="charger" value="Charger" /> </div> </form> <!-- Formulaire de saisie du livre (affich uniquement si un livre a t charg avec succs) --> <?php if ($livre): ?> <form action="saisie-livre.php" method="post" enctype="multipart/form-data"> <div> <br />ISBN : <input type="text" name="isbn" size="20" maxlength="20" value="<?php echo vers_formulaire($livre[isbn]); ?>" /> <br />Titre : <input type="text" name="titre" size="75" maxlength="75" value="<?php echo vers_formulaire($livre[titre]); ?>" /> <br />Sous-titre : <input type="text" name="sous_titre" size="75" maxlength="75" value= "<?php echo vers_formulaire($livre[sous_titre]); ?>" /> <br />Nombre pages : <input type="text" name="nombre_pages" size="4" maxlength="4" value= "<?php echo vers_formulaire($livre[nombre_pages]); ?>" /> Anne de parution : <input type="text" name="annee_parution" size="4" maxlength="4" value= "<?php echo vers_formulaire($livre[annee_parution]); ?>" /> <br />Niveau : <?php // Gnration dynamique des boutons radios utiliss pour // le niveau. $niveaux = array(Dbutant,Initi,Confirm,Expert); foreach ($niveaux as $niveau) { // Niveau du livre = niveau courant => bouton coch. if ($livre[niveau] == $niveau) { $slection = checked="checked"; } else { $slection = ; } printf ( <input type="radio" name="niveau" %s value="%s" />%s, $slection,$niveau,$niveau ); } ?> <br />Collection : <select name="collection"> <?php // Gnration dynamique de la liste utilise pour // la collection. while ($collection = mysqli_fetch_assoc($req_col)) { // Collection du livre = collection courante // => ligne slectionne. if ($livre[id_collection] == $collection[id]) { $slection = selected="selected"; } else { $slection = ; } printf (<option %s value="%s">%s</option>, $slection,$collection[id],$collection[nom]); } ?> </select>

- 12 -

ENI Editions - All rigths reserved

<br />Rubriques :<br /> <select name="rubriques[]" multiple="multiple" size="8"> <?php // Gnration dynamique de la liste utilise pour // les rubriques. while ($rubrique = mysqli_fetch_assoc($req_rub)) { // Colonne selection = 1 = rubrique du livre // => ligne slectionne. if ($rubrique[selection] == 1) { $slection = selected="selected"; } else { $slection = ; } printf (<option %s value="%s">%s</option>, $slection,$rubrique[id],$rubrique[titre]); } ?> </select> <br />Description :<br /> <textarea name="description" rows="6" cols="65"><?php echo vers_formulaire($livre[description]); ?></textarea> <br /> <!-- Limage de couverture est affiche par appel un autre script PHP. --> <img alt="Couverture :" src="image-livre.php?id=<?php echo $id_livre; ?>" /> <input type="file" name="couverture" value="" size="65" /> <input type="hidden" name="id" value="<?php echo $id_livre; ?>" /> <br /> <input type="submit" name="ok" value="Enregistrer" /> </div> </form> <?php endif; ?> <div><?php echo vers_page($message); ?></div> </body> </html> Leformulaireactuelpermetuniquementdemodifierunlivreexistant.Ilpeuttrefacilementmodifipourpermettrela saisiedunnouveaulivre.

ENI Editions - All rigths reserved

- 13 -

Descriptionduproblme
Le protocole HTTP (HyperText Transfer Protocol) est un protocole "sans tat" : rien ne permet didentifier que cest le mmeutilisateurquitaitprcdemmentsurlapageAetquimaintenantaccdelapageB. En ce qui concerne PHP, nous avons vu quune variable a une porte gale au script dans lequel elle est dfinie et nexistequeletempsdelexcutiondunscript. Or,unsiteinteractifquinesecontentepasdafficherdespageslesunesderrirelesautres,asouventbesoin,dupoint devuedelalogiqueapplicative,didentifierunutilisateurdunepagelautreetdeconserverdesinformationsrelatives cetutilisateurdunepagelautre(typiquement,unpanierlectroniqueconstituparlutilisateursurunepagedoit toujourstredfinisurlapagepermettantlepaiement). Le terme "session" dsigne la priode de temps correspondant la navigation continue dun utilisateur sur un site. "Grerlessessions"consistedonctreenmesuredidentifierlinstantounnouvelutilisateuraccdeunepagedu site et de conserver des informations relatives cet utilisateur jusqu ce quil quitte le site. Lutilisateur nest pas forcment un utilisateur authentifi par un nom et un mot de passe mais peut trs bien tre un "anonyme", non rfrencparlesite,quieffectueunachat.Beaucoupdesitesinteractifsproposentdesfonctionnalitsdidentification (membre, abonn ...) car cela permet de conserver des informations sur lutilisateurdune visite lautre(prfrences parexemple).Cettepossibilitseraaussitudiedanscechapitremaisdupointdevuedelanotiondesession,lavisite delutilisateurlevendredicorrespondraunesessiondiffrentedesavisitedulundi,mmesicertainesinformations saisieslelundisontsusceptiblesdtrerestitueslevendredi. Ce chapitre a pour objectif de prsenter les diffrentes techniques qui vont permettre, dune part didentifier un utilisateuretdautrepartde"suivre"cetutilisateur,etlesdonnesquiluisontassocies,dunepagelautre. Enprambule,nousallonsvoircommentauthentifierunutilisateur. Enfin,nousallonsterminercechapitreenvoquantlestechniquesquipermettentdeconserverdesinformationsdune visitelautre. DanslechapitreGrerlesformulairesetlesliensavecPHP,nousavonsvucommentpasserdesinformationsdunepage lautrelaidedunformulaire(aveclapossibilitdutiliserdeszonescachessibesoin)ouduneURL.Cestechniques peuvent tre utilises pour grer les sessions, mais cest un peu "artisanal" il est prfrable dutiliser les fonctionnalitsnativesdePHPpourgrerlessessions.

ENI Editions - All rigths reserved

- 1-

Authentification
1.Vuedensemble
Certainssitesontbesoindauthentifierlesutilisateursquiaccdentausiteafindevrifierquecesdernierssontbien inscrits. Cetteauthentificationcomprendgnralementdeuxtapes :
q

saisieparlutilisateurdinformationsdidentification,typiquementunnometunmotdepasse vrificationquelidentificationsaisiecorrespondbienunutilisateurinscrit.

2.Saisiedelidentification
Lidentificationpeuttresaisiededeuxmanires :
q

parlintermdiairedunformulaireprvuceteffet parlesfonctionsdauthentificationHTTP.

a.Identificationparformulaire
Ilesttrssimpledecrerunpetitformulairepermettantlutilisateurdesaisirunnometunmotdepasse. ExempledescriptPHP(login.php)quiafficheceformulaire(fonctiondevrificationpourlinstantnondfinie) <?php // Inclusion du fichier contenant les fonctions gnrales. include(fonctions.inc); // Fonction qui vrifie que lidentification saisie // est correcte. function utilisateur_existe($identifiant,$mot_de_passe) { // Alatoire, en attendant mieux ... return (bool) rand(0,1); } // Initialisation des variables. $identifiant = ; $mot_de_passe = ; $message = ; // Traitement du formulaire. if (isset($_POST[connexion])) { // Rcuprer les informations saisies. $identifiant = valeur_saisie($_POST[identifiant]); $mot_de_passe = valeur_saisie($_POST[mot_de_passe]); // Vrifier que lutilisateur existe. if (utilisateur_existe($identifiant,$mot_de_passe)) { // Lutilisateur existe ... // Partir sur une autre page et interrompre // le script. header(location: accueil.php); exit; } else { // Lutilisateur nexiste pas ... // Afficher un message et proposer de // nouveau lidentification $message = Identification incorrecte. ; $message .= Essayez de nouveau.; // Laisser le formulaire safficher de nouveau ... } }
ENI Editions - All rigths reserved - 1-

?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>MonSite.com</title></head> <body> <form action="login.php" method="post"> <table border="0"> <tr> <td align="right">Identifiant :</td> <td><input type="text" Name="identifiant" value= "<?php echo vers_formulaire($identifiant); ?>" /></td> </tr> <tr> <td align="right">Mot de passe :</td> <td><input type="password" Name="mot_de_passe" value= "<?php echo vers_formulaire($mot_de_passe); ?>" /></td> </tr> <tr> <td></td> <td align="right"><input type="submit" name="connexion" value="Connexion" /></td> </tr> </table> <?php echo $message; ?> </form> </body> </html> Rsultat
q

Affichageinitial :

Saisie :

Rsultatsilidentificationesterrone :

Lutilisationdunezonedetypepasswordpermetdemasquerlasaisiedumotdepasse. Silasaisieestincorrecte,lapageestproposedenouveau.Danslecascontraire,unepagedaccueilestaffiche.

b.IdentificationparauthentificationHTTP
laidedelafonction header(cf.UtiliserlesfonctionsPHPManipulerlesenttesHTTP),ilestpossiblededemander

- 2-

ENI Editions - All rigths reserved

aunavigateurdafficherunefentrededialogueinvitantlutilisateursaisirunnometunmotdepasse.Lemessage dentteenvoyerest : WWW-Authenticate: Basic realm="xxxxx" Avec xxxxx=nomaffich(nomdorganisationparexemple) Silutilisateurcliquesurlebouton OK,lescriptestappeldenouveauaveclesvaleurssaisiesdisponiblesdansles variablesPHP $PHP_AUTH_USERet$PHP_AUTH_PW. Parscurit,ilestprfrabledercuprercesinformationsparlintermdiairedutableauassociatif $_SERVER,avec lesclsPHP_AUTH_USERetPHP_AUTH_PW. Exempledescriptlogin.phputilisantcettetechnique <?php // Inclusion du fichier contenant les fonctions gnrales. include(fonctions.inc); // Fonction qui vrifie que lidentification saisie // est correcte. function utilisateur_existe($identifiant,$mot_de_passe) { // Alatoire, en attendant mieux ... return (bool) rand(0,1); } // Fonction qui affiche lauthentification HTTP. function authentification($message) { header("WWW-Authenticate: Basic realm=\"$message\""); // Si lutilisateur clique sur le bouton annuler, // Les lignes suivantes sexcutent (sinon, le script est // de nouveau appel mais avec $PHP_AUTH_USER renseign // et le script ne passera plus par ici). // Afficher un message et proposer lutilisateur // dessayer de nouveau echo Vous devez saisir un nom et un mot de passe , pour accder au site.<br />; echo <a href="login.php">Essayer de nouveau</a>; exit; } if (! isset($_SERVER["PHP_AUTH_USER"])) { // Pas de variable $PHP_AUTH_USER = premier appel du script. // Demande didentifiation. authentification("MonSite.com"); } else { // Variable $PHP_AUTH_USER existe = appel aprs saisie. // Rcuprer les information saisies. $identifiant = valeur_saisie($_SERVER["PHP_AUTH_USER"]); $mot_de_passe = valeur_saisie($_SERVER["PHP_AUTH_PW"]); // Vrifier que lutilisateur existe. if (utilisateur_existe($identifiant,$mot_de_passe)) { // Lutilisateur existe ... // Partir sur une autre page et interrompre le script header(location: accueil.php); exit; } else { // Lutilisateur nexiste pas ... // Essayer de nouveau. authentification(MonSite.com : identification incorrecte); } } ?> Rsultat
q

Affichageinitial(Firefox) :

ENI Editions - All rigths reserved

- 3-

ClicsurleboutonAnnuler :

Nouvelaffichage(parlelien)etsaisie :

Nouvelaffichagesilidentificationestincorrecte :

Silidentificationestcorrecte,unepagedaccueilestaffiche. ourlinstant,surlesdeuxexemples,laccslapagedaccueilnestpasprotg :unutilisateurquidemande P cettepageyaccdesansproblme.

- 4-

ENI Editions - All rigths reserved

3.Vrifierlidentificationsaisie
Quelle que soit la mthode utilise au point prcdent, il convient ensuite de vrifier que les informations saisies correspondentbienunutilisateur"connu". Typiquement,cecontrleseraralislaidedunebasededonnesquicontientnotammentlalistedesutilisateurs. Pourlasuite,noussupposeronsquilexistedansunebaseMySQL,unetableutilisateurscomportantdeuxcolonnes, identifiantetmot_de_passe. Exemple <?php // Fonction qui vrifie que lidentification saisie // est correcte. function utilisateur_existe($identifiant,$mot_de_passe) { // Connexion et slection de la base de donnes $connexion = mysqli_connect(localhost,root); mysqli_select_db($connexion,eni); // Dfinition et excution dune requte prpare $sql = SELECT 1 FROM utilisateurs ; $sql .= WHERE identifiant = ? AND mot_de_passe = ?; $requte = mysqli_stmt_init($connexion); $ok = mysqli_stmt_prepare($requte,$sql); $ok = mysqli_stmt_bind_param ($requte,ss,$identifiant,$mot_de_passe); $ok = mysqli_stmt_execute($requte); mysqli_stmt_bind_result($requte,$existe); $ok = mysqli_stmt_fetch($requte); mysqli_stmt_free_result($requte); // Lidentification est bonne si la requte a retourn // une ligne (lutilisateur existe et le mot de passe // est bon). // Si cest le cas $existe contient 1, sinon elle est // vide. Il suffit de la retourner en tant que boolen. return (bool) $existe; }?> Dautremthodesdauthentification,quinesappuientpassurunebasededonnessontenvisageables(simplefichier parexemple).

ENI Editions - All rigths reserved

- 5-

Utiliserdescookies
1.Principe
Uncookieestunpetitfichierdpos,parunsite,surlepostedelinternauteetquipeutcontenirdesinformations.Les cookies sont automatiquement renvoys au serveur Web, par le navigateur, lorsque linternaute navigue dans les pagesdusiteenquestion. PHPpermetdercuprertrsfacilement,dansdesvariables,lesdonnesstockesdanslecookie. Lafonctionsetcookiepermetdedposeruncookiesurlepostedelinternaute. Syntaxe boolen setcookie( chane nom [, chane valeur [, entier expiration [, chane chemin [, chane domaine [, boolen securis[, boolen http_uniquement]]]]]]) nom Nomducookie. valeur Valeurstockedanslecookie. expiration Datedexpirationducookie(timestampUnix) chemin Chemindurpertoiresurleserveurdanslequellecookieestdisponible.Mettre/ pourrendrelecookiedisponiblesur ledomaineentierou/rep/pourrendrelecookiedisponibledanslerpertoire/rep/dudomaineettoussessous rpertoires.Pardfaut,galaurpertoirepartirduquellecookieatdpos. domaine Domaineauquellecookieestrenvoy..monSite.com(avecunpointaudbut)permetparexemplederendrelecookie disponiblepourtouslessousdomainesdemonSite.com. scuris MettreTRUEpourindiquerquelecookienedoittretransmisquesuruneconnexionscurise( FALSEpardfaut). http_uniquement MettreTRUEpourindiquerquelecookienedoittretransmisquepourleprotocoleHTTP(FALSEpardfaut).Ajouten version5.2.0. Silafonctionnestappelequavecleparamtre nom,lecookieportantcenomestsupprimdupostedelinternaute. Silesparamtresdomaineetcheminavaienttspcifislorsdudptducookie,ilfautlesspcifierlidentiquepour supprimerlecookie(mettreunedatedexpirationdanslepass). Sileparamtrevaleurestspcifi,uncookieportantlenomnometcontenantlavaleur valeurestenvoysurleposte delutilisateur silexistedjuncookieportantcenom,cedernierestmisjouraveclanouvellevaleur. Leparamtre expirationpermetdedterminerladatedexpirationducookie(etdoncladatedesasuppressiondu postedelutilisateur) siceparamtreestnonspcifi(ougal0)lecookieexpirelafindelasession,cestdire lorsquelutilisateurquittelesite. Lescookiessontenvoysdanslenttedelapage.linstardelafonctionheader,lafonctionsetcookiedoitdonctre appeleavanttouteinstruction(PHPouHTML)quiapoureffetdecommencerconstruirelapageHTML.Encasde problme,unmessagedutypesuivantestaffich : W a r n i n g : Cannot add header information - headers already sent by (output started at /app/scripts/test.php:1) in / a p p / s c r i p t s / t e s t . p h p on line 7

ENI Editions - All rigths reserved

- 1-

LafonctionsetcookieretourneTRUEsilinstructionaputreexcute(pasdedonnesdjtransmises)etFALSEdans le cas contraire.Parcontre,lecodederetourdelafonctionnedonneaucuneinformationsurlefaitquelecookiea rellementputredpossurlepostedelutilisateur :sicedernierrefuselescookies,lafonction setcookieretourne quandmmeTRUEbienquelecookienaitpastdpos. es cookies sont grs par site deux cookies de sites diffrents peuvent porter le mme nom. Le cookie est L dpos sur le poste de linternaute par la fonction setcookie puis renvoy ultrieurement lors de la visite de nimportequellepagedusite. Exemple <?php // Dpt dun cookie nomm "nom" contenant // la valeur "Olivier" et expirant la fin de // la session. $ok = setcookie(nom,Olivier); // Idem mais expirant date du jour (time() en secondes) // plus 30 fois 24 fois 3600 secondes (soit 30 jours). $ok = setcookie(nom,Olivier,time()+(30*24*3600)); // Suppression du cookie nomm nom. $ok = setcookie(nom); ?> Lorsque le cookie est renvoy au serveur Web, par le navigateur, lors de la demande dunepagePHP,lavaleurdu cookieestaccessibledansunevariablePHPselonunmcanismesimilaireceluimisen uvrepourlesformulaireset lesURL. La valeur de chaque cookie envoy par le navigateur est automatiquement enregistre dans le tableau associatif $_COOKIE :lacldutableauestgaleaunomducookie. esvariablesdecookiesontaussidisponiblesdansletableauassociatif $_REQUESToupeuventtreimportes L dans le script par appel la fonction import_request_variables (cf. chapitre Grer les formulaires et les liens avecPHPVuedensemble). Exemple
q

Scriptpage1.phpquidposedeuxcookies :

<?php // Premier cookie expirant la fin de la session. $ok1 = setcookie(prnom,Olivier); // Deuxime cookie expirant dans 30 jours. $ok2 = setcookie(nom,HEURTEL,time()+(30*24*3600)); // Rsultat. if ($ok1 and $ok2) { $message = Cookies dposs (du moins, a priori); } else { $message = L\un des cookies n\a pas pu tre dpos; } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <?php echo $message; ?><br /> <!-- lien vers la page 2 --> <a href="page2.php">Page 2</a> </div> </body> </html>
q

Scriptpage2.phpquiaffichelavaleurdesdeuxcookies :

- 2-

ENI Editions - All rigths reserved

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 2</title></head> <body> <div> <?php if ( isset($_COOKIE["prnom"]) ) { echo "\$_COOKIE[\"prnom\"] = {$_COOKIE[prnom]}<BR>"; } else { echo "\$_COOKIE[\"prnom\"] = <BR>"; } if ( isset($_COOKIE["nom"]) ) { echo "\$_COOKIE[\"nom\"] = {$_COOKIE[nom]}<BR>"; } else { echo "\$_COOKIE[\"nom\"] = <BR>"; } ?> </div> </body> </html> Rsultat
q

Affichagedelapage1

Rsultatduclicsurlelien

Rsultatdunretour,avanttrentejours,surlapage2dummesite :

ENI Editions - All rigths reserved

- 3-

Le cookie de dure de vie gale la session nexiste plus et linformation est perdue linformation stocke dans lautrecookierestedisponible(danslalimitedesaduredevie). Il est possible de stocker nimporte quelle chane dans le cookie sans avoir se soucier dun ventuel encodage/dcodage :lencodageetledcodagesonteffectusautomatiquement. Lecookieestdpossurlepostedelinternauteparlafonction setcookiepuisrenvoyultrieurementlorsdelavisite denimportequellepagedusite lecookienestpasdisponibleimmdiatementdanslapagequiledpose. Exemple <?php // valeur du cookie avant. $avant = (isset($_COOKIE [heure]))?$_COOKIE [heure]:; // Dpt du cookie expirant la fin de la session. $ok = setcookie(heure,date(H:i:s)); // Valeur du cookie aprs. $aprs = (isset($_COOKIE [heure]))?$_COOKIE [heure]:; // heure actuelle $actuel = date(H:i:s); // Affichage echo "Actuel : $actuel<br />"; echo "Avant : $avant<br />"; echo "Aprs : $aprs<br />"; ?> Rsultatdupremierappel Actuel : 08:28:55 Avant : Aprs : Lorsdupremierappel,lecookienexistepasavant(cestnormal)etnexistetoujourspasaprs,carilasimplementt envoymaisnestpasencore"revenu"(manireimagedeprsenterleschoses). Rsultatdudeuximeappel(danslammesession) Actuel : 08:29:19 Avant : 08:28:55 Aprs : 08:28:55 Lorsdudeuximeappel,lavaleurducookieestdisponibledsledbutduscript(lecookieestrevenuaveclarequte pourlapage)etabienunevaleurquicorrespondlinstantoilatdpos parcontresavaleuraprsnereflte pasimmdiatementlaralit(mmeprincipequepourledptinitial :lecookienestpasencore"revenu"). Unedesconsquencesdecemodedefonctionnementestquilnestpaspossible,toutdesuiteaprsavoirdposle cookie,detestersilecookieatacceptounonparleposte. Poursavoirsiunposteacceptelescookies,ilfautdposeruncookieetrechargerunepagedanslaquellelaprsence ounonducookiepermettradedterminersileposteacceptelescookies. Exempledescripttester_cookie.phpquipermetdefairecetest <?php // Tester si cest le deuxime appel de la page. if (! isset($_GET[retour])) { // Non ... // Dposer le cookie.
- 4 ENI Editions - All rigths reserved

setcookie(test,test); // Et recharger la page avec une information dans // lURL indiquant que cest le deuxime passage. header(Location: tester_cookie.php?retour=1); } else { // Oui ... // Tester si le cookie est "revenu". if (isset($_COOKIE[test])) { // oui ... echo Cookie accept; } else { // non ... echo Cookie refus; } } ?> Ilestpossibledercupreruntableaucommevaleurdecookiesousrservedutiliserunenotationdetypetableau lorsdudptducookie. Exemple(bassurlexempleprcdent) <?php // Inclusion du fichier qui contient les fonctions gnrales. include(fonctions.inc); // Tester si cest le deuxime appel de la page. if (! isset($_GET[retour])) { // Non ... // Dposer le cookie. setcookie(test[0],zro); setcookie(test[1],un); // Et recharger la page avec une information dans // lURL indiquant que cest le deuxime passage. header(Location: tester_cookie.php?retour=1); } else { // Oui ... // Tester si le cookie est "revenu". if (isset($_COOKIE[test])) { // oui ... echo Cookie accept<br />; afficher_tableau($_COOKIE[test]); } else { // non ... echo Cookie refus; } } ?> Rsultat Cookie accept 0 = zro 1 = un Dans la pratique, il y a en fait plusieurs cookies dposs sur le poste de lutilisateur, mais les valeurs sont bien rcupres dans le script PHP sous la forme dun tableau. Pour dposer un seul cookie contenant plusieurs valeurs, vouspouvezprocderparconcatnation,ouutiliserunefonctioncommeimplode(etexplodeauretourducookie).

2."magicquotes" :leretour
Commepourlesdonnes GETet POST,lavaleurrcupredansuncookiepeutsubirlencodage"magicquotes"sila directivedeconfiguration magic_quotes_gpc(Get/Post/Cookie)est on(cf.chapitreUtiliserlesfonctionsPHPGrerles "guillemetsmagiques"("magicquotes")). Enconsquence,lorsdelarcuprationduneinformationtransmiseparURL,ilconvientventuellementdappelerla fonction stripslashes ou nos fonctions gnriques valeur_saisie ou supprimer_encodage_MQ_GPC pour supprimer lencodage"magicquotes".

3.Applicationlagestiondessessions

ENI Editions - All rigths reserved

- 5-

Lescookiespeuventtreutilisspourgrerlessessions,aveclavantagedtreparfaitementindpendantslafois delanavigationparbalise<a href=...>etdelagestiondesformulaires. Ilsprsententparcontreungrosinconvnient :ilspeuventtrerefussparlesinternautes.Parailleurs,lenombrede cookiesestlimit20parserveuretlatailleduncookieestelleaussilimite. Une gestion des sessions, dans laquelle un identifiant de session est transmis dune page lautre (les autres informationstantstockessurleserveur)peuttremiseenplacerelativementfacilementenutilisantlescookies,si lutilisateur les accepte, et en utilisant lURL dans le cas contraire. Cest exactement ce que propose la gestion des sessionsdePHPquenousallonsvoirmaintenant :nenousamusonsdoncpasredveloppercequiexistedj ! Nousallonsvoirgalementdanscechapitre(cf.Conserverdesinformationsdunevisiteuneautre),quelecookieest unbonoutil(sousrservedelaccorddelutilisateur)pourstockeruneinformationdunesessionlautre(enutilisant doncuncookieayantuneduredeviespcifielacration).

- 6-

ENI Editions - All rigths reserved

UtiliserlagestiondessessionsdePHP
1.Principes
Depuislaversion4,PHPproposeunensembledefonctionsquifacilitentlagestiondessessions.Lesprincipessontles suivants :
q

Unidentifiantuniqueestautomatiquementattribuchaquesession. Cetidentifiantuniqueesttransmisdunepagelautre,soitparcookie(sileposteacceptelescookies),soit par lURL dans le cas contraire en tout tat de cause, cest PHP qui choisit automatiquement la bonne mthodeetassurecetransfert(quelquesrservesprslieslaconfiguration). Lesdonnesdontvoussouhaitezconserverlavaleurdunepagelautrependantladuredelasessionsont indiques PHP qui se charge automatiquement de restituer leur valeur au dbut du script et de les sauvegarderlafinduscript.

Enbref,PHPsechargedetoutelagestion.

2.Miseenuvre
Lesprincipalesfonctionsdumoduledegestiondessessionssontlessuivantes : Nom Rle Ouvreunenouvellesessionouractivelasession courante. Retourne(ouventuellementmodifie)lidentifiantde lasession. Retourne(ouventuellementmodifie)lenomdela variableutilisepourstockerlidentifiantdelasession. Supprimelasession.

session_start session_id session_name session_destroy

Encomplment,letableau$_SESSIONpermetdemanipulertrsfacilementlesvariablesdesession. Plusieurs fonctions (notamment session_registeret session_unregister)sontconservesparPHPpourdesraisons de compatibilit ascendante et ne fonctionnent que lorsque la directive de configuration register_globals est on. Lutilisationde $_SESSIONestrecommandeetrendcesfonctionsinutilesellesnesontdoncpasprsentesdanscet ouvrage. oubliez pas que la directive de configuration register_globals est off par dfaut depuis la version 4.2 et N quellepasseradfinitivementoffdansuneprochaineversion.

session_start Syntaxe boolen session_start() Lafonction session_startinterrogelenvironnementpourdtectersiunesessionadjtouvertepourlutilisateur actuel.Sioui,lesdonnesenregistresdanslasessionsontrestitues.Autrement,unenouvellesessionestouverte avecattributiondunidentifiant. Lafonctionsession_startretournetoujoursTRUE. Toutscriptconcernparlagestiondessessionsdoitappeler session_startpourpouvoiravoiraccsauxvariablesde

ENI Editions - All rigths reserved

- 1-

session. Si la session nest pas encore ouverte, la fonction session_start va chercher dposer un cookie, contenant lidentifiant de session, sur le poste de lutilisateur : il est donc primordial, comme pour les fonctions header et setcookie que le dbut de la page naitpasencoretenvoyaunavigateur.Encasdeproblme,unmessagedu typesuivantestaffich : W a r n i n g : session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at /app/scripts/test.php:1) in / a p p / s c r i p t s / t e s t . p h p on line 4 Exemple <?php // Ouvrir/ractiver la session. session_start(); ?>

session_id Syntaxe chane session_id([ chane nouvelle_valeur]) nouvelle_valeur Nouvellevaleurattribuelidentifiantdesession. Appele sans paramtre, la fonction session_id retourne la valeur de lidentifiant de session. Cette valeur sera toujoursvidesisession_startnapastappeldanslescript. Appeleavecunparamtre,lafonction session_idmodifielavaleurattribuelidentifiant de session. En pratique, danslamajoritdescas,celaneprsentepasungrandintrt. Exemple <?php // Rcuprer la valeur de session_id avant. $avant = session_id(); // Ouvrir/ractiver la session. session_start(); // Rcuprer la valeur de session_id aprs. $aprs = session_id(); // Affichage. $actuel = date("H:i:s"); echo "Heure : $actuel<br />"; echo "Avant : $avant<br />"; echo "Aprs : $aprs<br />"; ?> Rsultat
q

Premierappel

Heure : 20:15:40 Avant : Aprs : 3abfb1ff70a7dc7ad13d1d47d890880e


q

Deuximeappelsansquitterlesite(mmesession)

Heure : 20:15:56 Avant : Aprs : 3abfb1ff70a7dc7ad13d1d47d890880e

session_name Syntaxe
- 2 ENI Editions - All rigths reserved

chane session_name([chane nouvelle_valeur]) nouvelle_valeur Nouvellevaleurattribueaunomdelavariablequistockelidentifiantdesession. Appelesansparamtre,lafonction session_nameretournelenomdelavariabledanslaquellelidentifiantdesession eststock.Lafonction session_nameretourneunrsultatmmesilafonction session_startnapastappeledans lescript. Appeleavecunparamtre,lafonction session_namemodifielenomdelavariable.Enpratique,danslamajoritdes cas,celaneprsentepasungrandintrt(ilestdetoutefaonremissavaleurpardfautlafinduscript). Exemple <?php // Rcuprer la valeur de session_name avant. $avant = session_name(); // Ouvrir/ractiver la session. session_start(); // Rcuprer la valeur de session_name aprs. $aprs = session_name(); // Affichage. echo "Avant : $avant<br />"; echo "Aprs : $aprs<br />"; // Affichage de la valeur. // Lidentifiant de session est transmis soit par cookie, // soit par lURL, et donc disponible en tant que variable // dans le tableau $_REQUEST. echo "$aprs = {$_REQUEST[$aprs]}<br />"; // Comparaison avec la valeur retourne par session_id(). echo session_id() = ,session_id(); ?> Rsultat Avant : PHPSESSID Aprs : PHPSESSID PHPSESSID = 3abfb1ff70a7dc7ad13d1d47d890880e session_id() = 3abfb1ff70a7dc7ad13d1d47d890880e Le nom de la variable est dfini par la directive de configuration session.name. Vous pouvez modifier cette directive pourutiliserunautrenom. Manipulerlesvariablesenregistresdanslasession Aprsappellafonctionsession_start,lesdonnesdesessionpeuventtremanipulesdirectementdansletableau associatif $_SESSION. Toutes les entres stockes dans le tableau $_SESSION sont automatiquement enregistres en tantquedonnesdesession. Pourenregistrerunenouvelledonnedanslasession,ilsuffitdestockercettedonnedansletableau$_SESSION,avec lacldevotrechoix. Pour lire ou modifier une donne de session pralablement enregistre il suffit daccder au tableau $_SESSION en utilisantlabonnecl. oubliez pas dappeler la fonction session_start pour pouvoir manipuler les donnes de session laide du N tableau$_SESSION.

Scriptpage1.phpquiouvreunesessionetenregistredesdonnesdanslasession.

<?php // Ouvrir/ractiver la session. session_start(); // Enregistrer deux informations dans la session. $_SESSION[prnom] = Olivier; $_SESSION[informations] = // cest un tableau ...
ENI Editions - All rigths reserved - 3-

array(prnom=>Olivier,nom=>HEURTEL); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div><a href="page2.php">Page 2</a></div> </body> </html>
q

Scriptpage2.phpquiaffichelavaleurdesvariablesdesession.

<?php // Appel session_start. session_start(); // Affichage. echo $_SESSION[\prnom\] = , isset($_SESSION[prnom])?$_SESSION[prnom]:, <br />; echo $_SESSION[\informations\][\nom\] = , isset($_SESSION[informations][nom])? $_SESSION[informations][nom]:, <br />; ?> Rsultatsurlapage2aprsaffichagedelapage1etclicsurlelien $_SESSION[prnom] = Olivier $_SESSION[informations][nom] = HEURTEL

Ilnyaaucunencodage(nimmede"magicquotes")surlesdonnesenregistresdanslasession. Letableau $_SESSIONestunevariable"superglobale" :elleestdisponibledanslatotalitduscript,mmelintrieur desfonctions,sansdevoirladclarerglobale(global $_SESSIONestinutile). Commelemontrelexempleprcdent,lafonction issetpeuttreutilisepourtestersiunedonneestenregistre danslasession. Si vous souhaitez supprimer une donnes de session, vous pouvez utiliser la fonction unsetpoursupprimerlentre dansletableau$_SESSION : unset($_SESSION[prnom]). Pour supprimer dun seul coup toutes les donnes de session, vous pouvez affecter un tableau vide ( array()) au tableau $_SESSION. D anslesdeuxcas,nesupprimezpaslatotalitdelavariable$_SESSION(unset($_SESSION)) !

session_destroy Syntaxe boolen session_destroy() Aprsunappellafonction session_destroy,lasessionnexisteplus unappelultrieurlafonction session_start vaouvrirunenouvellesession. Lafonctionsession_destroyretourneTRUEencasdesuccsetFALSEencasdchec. Lafonctionsession_destroychoue(etdoncretourne FALSE)etafficheunealertesielleestappeleavantlafonction session_start. La fonction session_destroy ne supprime pas les donnes de session dans le script en cours. Pour supprimer immdiatementtouteslesdonnesdesession,vouspouvezaffecteruntableauvide$_SESSION. De mme, cette fonction ne dtruit pas le cookie de session ventuellement utilis pour propager lidentifiant de session.Poursupprimerlecookiedesession,vouspouvezutiliserlafonction setcookie(cf.danscechapitreUtiliser descookies).

- 4-

ENI Editions - All rigths reserved

Exemple
q

Scriptpage1.php

<?php // Ouvrir/ractiver la session. session_start(); // Enregistrer une information dans la session. $_SESSION[nom] = Olivier; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <b>Page 1</b><br /> <?php echo Bonjour ,$_SESSION[nom],<br />; echo session_id() = ,session_id(),<br />; ?> <a href="page2.php">Page 2</a><br /> </div> </body> </html>
q

Scriptpage2.php

<?php // Ouvrir/ractiver la session. session_start(); // Dtruire la session. session_destroy(); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 2</title></head> <body> <div> <b>Page 2</b><br /> <?php echo Bonjour ,$_SESSION[nom],<br />; echo session_id() = ,session_id(),<br />; ?> <a href="page3.php">Page 3</a><br /> </div> </body> </html>
q

Scriptpage3.php

<?php // Ouvrir/ractiver la session. session_start(); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 3</title></head> <body> <div> <b>Page 3</b><br /> <?php echo Bonjour ,$_SESSION[nom],<br />; echo session_id() = ,session_id(),<br />; ?>

ENI Editions - All rigths reserved

- 5-

</div> </body> </html> Rsultat


q

Page1

Page 1 Bonjour Olivier session_id() = defbd28027131043572a86e1bf41299b Page 2


q

Page2

Page 2 Bonjour Olivier session_id() = Page 3


q

Page3

Page 3 Bonjour session_id() = defbd28027131043572a86e1bf41299b Dans la deuxime page, la donne de session nest pas encore supprime. Par contre, dans la troisime page, la donneestvide.Cestenfaitunenouvellesession,maislemmeidentifiantatrutiliscarlecookiedesession navaitpartsupprim. Ilestpossibledemodifierlescriptpage2.phppourquildtruisecompltementlasession. Exemple <?php // Ouvrir/ractiver la session. session_start(); // Effacer toutes les informations de session. $_SESSION = array(); // Supprimer le cookie de session (si utilis). // Le cookie porte le nom de la variable qui stocke // lidentifiant de session. if (isset($_COOKIE[session_name()])) { setcookie(session_name(),,time()-1,/); } // Dtruire la session. session_destroy(); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 2</title></head> <body> <div> <b>Page 2</b><br /> <?php echo Bonjour ,$_SESSION[nom],<br />; echo session_id() = ,session_id(),<br />; ?> <a href="page3.php">Page 3</a><br /> </div> </body> </html> Rsultat
q

Page1

- 6-

ENI Editions - All rigths reserved

Page 1 Bonjour Olivier session_id() = defbd28027131043572a86e1bf41299b Page 2


q

Page2

Page 2 Bonjour session_id() = Page 3


q

Page3

Page 3 Bonjour session_id() = 99f7fc425b98e6ff51d28c6da8502fc4 La donne de session est bien efface ds la deuxime page, et un nouvel identifiant de session est utilis sur la troisimepage.

3.Grersoimmelatransmissiondelidentifiantdesession
a.Descriptionduproblme
Normalement, lidentifiant de session est automatiquement transmis par PHP, soit par cookie soit par lURL (si lutilisateurnacceptepaslescookies). Nanmoins,troisdirectivesdeconfigurationpilotentcecomportement :
q

session.use_cookie session.use_trans_id session.use_only_cookie

Si la directive session.use_cookie est gale 0, PHP ne tente mme pas dutiliser les cookies pour transmettre lidentifiantdesession.Parcontre,siladirectiveestgale1(valeurpardfaut),PHPtentedutiliserlescookies. Si la directive session.use_trans_sid est gale 0 (valeur par dfaut), PHP nutilise pas lURL pour transmettre lidentifiant de session. Par contre, si la directive est gale 1 et que lidentifiant de session ne puisse pas tre transmisparcookie(dufaitdelaconfigurationoudunrefusdelutilisateur),alorsPHPutiliselURLpourtransmettre lidentifiantdesession. Si la directive session.use_only_cookie est 1, seuls les cookies sont utiliss pour transmettre lidentifiant de session.Pardfaut,ladirectiveest0(compatibilitascendante). Laconsquenceprincipaleestlasuivante :siladirective session.use_trans_sidestgale0(valeurpardfaut)et si lidentifiant de session ne peut pas tre transmis par cookie (du fait de la configuration ou dun refus de lutilisateur),lagestiondessessionsnefonctionneplus. En terme de scurit, il est dconseill de permettre la transmission de lidentifiant de session par lURL. Il est prfrable dutiliser des cookies, mais cela ncessite que linternaute les accepte. Les valeurs par dfaut des directivesdeconfigurationvontdanscesens. Exemple
q

Scriptpage1.php

<?php // Ouvrir/ractiver la session. session_start(); // Rcuprer lidentifiant de session. $session = session_id();;

ENI Editions - All rigths reserved

- 7-

// Enregistrer une information dans la session. $_SESSION[nom] = Olivier; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <b>Page 1</b><br /> <?php // Afficher lID de la session. echo session_id() = ,session_id(),<br />; // Afficher la donne de session. echo nom = , isset($_SESSION[nom])?$_SESSION[nom]:,<br />; ?> <a href="page2.php">Page 2</a><br /> </div> </body> </html>
q

Scriptpage2.php

<?php // Ouvrir/ractiver la session. session_start();?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 2</title></head> <body> <div> <b>Page 2</b><br /> <?php // Afficher lID de la session. echo session_id() = ,session_id(),<br />; // Afficher la donne de session. echo nom = , isset($_SESSION[nom])?$_SESSION[nom]:,<br />; ?> </div> </body> </html> Rsultat(premiercas)
q

Affichageinitialdelapage1

Page 1 session_id() = 7580071d734e76516999f37d00a96cb7 nom = Olivier Page 2


q

Affichage de la page 2 aprs un clic sur le lien Page 2 (si lutilisateur refuse les cookies et que session.use_trans_sid = 0)

Page 2 session_id() = 161492b7dd7f5738b9c8105bedf3250b nom = Les informations de session nont pas t transmises et lappel la fonction session_start a ouvert une nouvelle session. Rsultat(deuximecas)
q

Affichageinitialdelapage1

- 8-

ENI Editions - All rigths reserved

Page 1 session_id() = 0283b72fb608b8255874c4e9144f8d47 nom = Olivier Page 2


q

Affichage de la page 1 aprs un clic sur le lien Page 2 (si lutilisateur refuse les cookies et que session.use_trans_sid = 1)

Page 2 session_id() = 0283b72fb608b8255874c4e9144f8d47 nom = Olivier Danscecas,lasessionabientconserve. RegardonslecodesourceHMTLdelapremirepagepourcomprendrecequisestpass : <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <div> <b>Page 1</b><br /> session_id() = 0283b72fb608b8255874c4e9144f8d47<br />nom = Olivier<br /> <a href="page2.php?PHPSESSID=0283b72fb608b8255874c4e9144f8d47"> P a g e 2 < / a > <br /> </div> </body> </html> Labalise <a href>atautomatiquementrcriteparPHP,pourintgrerlatransmissiondelidentifiantdesession (nomm PHPSESSID par dfaut). Si un paramtre tait dj prsent dans lURL, PHP aurait ajout le paramtre PHPSESSIDdanslURL(&PHPSESSID=...). Parcontre,unproblmeseposeencasderetoursurlapage1parlebouton"Prcdente"dunavigateur : Page 1 session_id() = 6be4fb067efdb037c4c6bb63fa0b5536 nom = Olivier Page 2 Commelidentifiantdesessionnestpasretransmislorsdelappelcettepage,unenouvellesessionestouverte. Delammemanire,siunepagecomporteunformulaire,unezonecacheestautomatiquementajouteparPHP pourtransmettrelidentifiantdesessionlorsdelasoumissionduformulaire. Exemple <input type="hidden" name="PHPSESSID" value="556e46fb45de467e0b2a18ce46855016" /> Parcontre,linformationnestpastransmiselorsduneredirectionaveclafonctionheader.

b.Solution
SilidentifiantnestpasautomatiquementtransmisparPHP,ilconvientdassurersoimmecettetransmission,leplus simpletantdelefaireparlURL(commePHPleferaitsiloptiontaitactive). Unepremirepossibilitconsisteutiliserlesfonctions session_nameet session_idpourconstruireleparamtre insrerdanslURLsouslaformenom_identifiant=valeur_identifiant. La deuxime possibilit (plus simple), consiste utiliser une constante, nomme SID, qui est automatiquement initialiseparPHPavecunechanenom_identifiant=valeur_identifiant. Exemple <?php

ENI Editions - All rigths reserved

- 9-

// Ouvrir/ractiver la session. session_start(); // Construire la chane soi mme. echo Mon SID : ,session_name(),=,session_id(),<br />; // Afficher la constante SID. echo SID : ,SID; ?> Rsultat Mon SID : PHPSESSID=8e7ebe7660d0441de4337d64bbec409a SID : PHPSESSID=8e7ebe7660d0441de4337d64bbec409a Danslesdeuxcas,silenomdelavariableatmodifidanslefichier php.ini,lesdeuxconstructionsentiennent compte. La constante SID, telle quelle est dfinie, peut tre utilise directement pour construire une URL transmettant la valeurdelidentifiantdesession. Exemples
q

Dansunebalise<a href=...> :

<a href="page2.php?<?php echo SID; ?>">Page 2</a>


q

Danslattributactiondelabalise <form> :

<form action="page2.php?<?php echo SID; ?>" method="post">


q

Dansuneredirectionaveclafonctionheader :

header(Location: page2.php?.SID); Parcontre,dansunezonecachedunformulaire,ilfaututiliserlesfonctionssession_nameetsession_id. Exemple <input type = "hidden" name="<?php echo session_name(); ?>" value="<?php echo session_id(); ?>" />

aconstante SIDnest pas renseigne si le cookie est accept, sauf dans le script qui vient juste douvrirla L session(carPHPnesaitpasencoresilecookieestacceptparleclient).Intgrerun SIDvidedansuneURL nest pas trs lgant mais ne pose pas de problme ( <a href="page2.php?"> est valide). Si vous intgrez systmatiquement le SID dans les URL et que la transmission automatique fonctionne (soit par cookie, soit par lURL),cenestpasnonplustrslgantmaiscelaneposepasdeproblme. Pourcrireducodeportableetlgant,ilconvientdoncdenintgrersoimmele SIDdanslURLquelorsquecest ncessaire. Une fonction gnrique peut trs bien se charger de cette tche en testant la directive de configuration et la constanteSID. Exemple <?php function url($url) { // Si la directive de configuration session.use_trans_sid // est 0 (pas de transmission automatique par lURL) et // si SID est non vide (le poste a refus le cookie) alors // il faut grer soi mme la transmission. if ((get_cfg_var(session.use_trans_sid) == 0) and (SID != )) { // Ajouter la constante SID derrire lURL avec un ? // sil ny a pas encore de paramtre, ou avec un & dans // le cas contraire.

- 10 -

ENI Editions - All rigths reserved

$url .= ((strpos($url,?) === FALSE)??:&).SID; } return $url; } // Ouvrir/ractiver la session. session_start(); // Quelques tests echo url(page2.php),<br />; echo url(page3.php?nom=Olivier),<br />; ?> Rsultat
q

Sisession.trans_id = 0etcookierefus :

page2.php?PHPSESSID=dda5ca567f453851a717ff118040e29f page3.php?nom=Olivier&PHPSESSID=dda5ca567f453851a717ff118040e29f
q

Sisession.trans_id = 0etcookieaccept(mais1erappel) :

page2.php?PHPSESSID=66312cb7e9c351fd73fb74b0bbdacd76 page3.php?nom=Olivier&PHPSESSID=66312cb7e9c351fd73fb74b0bbdacd76
q

Sisession.trans_id = 0etcookieaccept(mais2meappel) :

page2.php page3.php?nom=Olivier
q

Sisession.trans_id = 1quelecookiesoitrefusouaccept :

page2.php page3.php?nom=Olivier Dans le dernier cas, lorsque le cookie est refus, cest PHP qui ajoute automatiquement le SID dans lURL (car la directivesession.trans_id est on). CettefonctionpeutensuitetreappelepartoutoilfautconstruireuneURLsusceptibledetransmettrelidentifiant desession. uellequesoitlaconfiguration,cettefonctiondoittreutiliselorsdune redirection avec la fonction header Q (carPHPnercritjamaislesURLappelesparcettefonction).

4.Quelquesdirectivesdeconfigurationsupplmentaires
Encomplmentdecellesdjcites,ilestbondeconnatrelesdirectivessuivantes : session.save_path Rpertoiredanslequellesfichierstemporairescontenantlesinformationsdesessionsontenregistrs. session.auto_start Sielleestpositionne1,lafonctionsession_startestautomatiquementappeleaudbutdechaquescript(pourun codeportable,ilestprfrabledappelerexplicitementlafonctionsession_start). session.cookie_lifetime Duredeviedescookiesdposssurlepostedelutilisateur.Lavaleur0proposepardfautestbienadaptepour uncookiedesession. session.cache_limiter Dterminelecomportementvisvisducachedetouteslespagesconcernesparlagestiondessessionsenvoyes
ENI Editions - All rigths reserved - 11 -

aunavigateur.Valeurspossibles :nocache,private,public.Cetteinformationesttransmisedanslenttedela rponseduserveurWeb.nocachepardfaut. session.cookie_path Cheminsurleserveurdanslequellecookiedesessionestdisponible(voirlafonctionsetcookie)./pardfaut. session.cookie_domain Domaineauquellecookieestrenvoy(voirlafonctionsetcookie).Videpardfaut. session.cookie_secure Indiquesilecookienedoittretransmisqueviauneconnexionscurise(voirlafonctionsetcookie).Offpardfaut. session.cache_expire Duredevieenminutesdespagesdanslecache.180pardfaut.Sanseffetsilavaleurnocacheestspcifiedans session.cache_limiter.

5.Exempledapplication
Les principes prsents dans les points prcdents peuvent tre illustrs sur une gestion de session avec authentificationdesutilisateurs. Source
q

Scriptlogin.phppourlauthentification

<?php // Inclusion du fichier contenant les fonctions gnrales. include(fonctions.inc); // Fonction qui vrifie que lidentification saisie // est correcte. function utilisateur_existe($identifiant,$mot_de_passe) { // Connexion et slection de la base de donnes $connexion = mysqli_connect(localhost,root); mysqli_select_db($connexion,eni); // Dfinition et excution dune requte prpare $sql = SELECT 1 FROM utilisateurs ; $sql .= WHERE identifiant = ? AND mot_de_passe = ?; $requte = mysqli_stmt_init($connexion); $ok = mysqli_stmt_prepare($requte,$sql); $ok = mysqli_stmt_bind_param ($requte,ss,$identifiant,$mot_de_passe); $ok = mysqli_stmt_execute($requte); mysqli_stmt_bind_result($requte,$existe); $ok = mysqli_stmt_fetch($requte); mysqli_stmt_free_result($requte); // Lidentification est bonne si la requte a retourn // une ligne (lutilisateur existe et le mot de passe // est bon). // Si cest le cas $existe contient 1, sinon elle est // vide. Il suffit de la retourner en tant que boolen. return (bool) $existe; } // Initialisation des variables. $identifiant = ; $mot_de_passe = ; $message = ; // Traitement du formulaire. if (isset($_POST[connexion])) { // Rcuprer les information saisies. $identifiant = valeur_saisie($_POST[identifiant]); $mot_de_passe = valeur_saisie($_POST[mot_de_passe]); // Vrifier que lutilisateur existe.

- 12 -

ENI Editions - All rigths reserved

if (utilisateur_existe($identifiant,$mot_de_passe)) { // Lutilisateur existe ... // Ouvrir une session et enregistrer les donnes // de session. session_start(); $_SESSION[date] = date("\l\e d/m/Y H:i:s"); $_SESSION[identifiant] = $identifiant; // Puis rediriger lutilisateur vers la page daccueil // en appelant la fonction gnrique url() pour tre // certain que lidentifiant de session est transmis // quelles que soient les conditions. header(location: .url(accueil.php)); exit; } else { // Lutilisateur nexiste pas ... // Afficher un message et proposer de // nouveau lidentification. $message = Identification incorrecte. ; $message .= Essayez de nouveau.; // Laisser le formulaire safficher de nouveau ... } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>MonSite.com - Identification</title></head> <body> <form action="login.php" method="post"> <table border="0"> <tr> <td align="right">Identifiant :</td> <td><input type="text" Name="identifiant" value= "<?php echo vers_formulaire($identifiant); ?>" /></td> </tr> <tr> <td align="right">Mot de passe :</td> <td><input type="password" Name="mot_de_passe" value= "<?php echo vers_formulaire($mot_de_passe); ?>" /></td> </tr> <tr> <td></td> <td align="right"><input type="submit" name="connexion" value="Connexion" /></td> </tr> </table> <?php echo $message; ?> </form> </body> </html>
q

Scriptaccueil.phppourlapagedaccueil

<?php // Inclusion du fichier contenant les fonctions gnrales. include(fonctions.inc); // Ouvrir/ractiver la session. session_start(); // Tester si la session est nouvelle (ouverte par // lappel session_start() ci-dessus) ou ancienne (ouverte // par un appel antrieur session_start()). // Le mieux est de tester si une de nos donnes de session // est dj enregistre. if (! isset($_SESSION[identifiant])) { // Donne "identifiant" pas encore enregistre : // => lutilisateur nest pas connect ; // => le rediriger vers la page de login. header(location: login.php); exit;
ENI Editions - All rigths reserved - 13 -

} else { // Donne "identifiant"dj enregistre : // => lutilisateur est connect ; // => rcuprer les donnes de session utilises dans // le script. $date = $_SESSION [date]; $identifiant = $_SESSION[identifiant]; // Rcuprer lidentifiant de la session (pour lexemple). $session = session_id(); // Prparer un message. $message = "Session : $session - $identifiant - $date"; } // Dtermination de la date et de lheure actuelle (pas celle // de louverture de la session). $actuel = Nous sommes le .date(d/m/Y). ; il est .date(H:i:s); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>MonSite.com - Accueil</title></head> <body> <div> <b>Accueil - <?php echo $actuel; ?></b><br /> <?php echo $message; ?><br /> <!-- Lien vers une autre page. Utiliser notre fonction gnrique url() pour tre certain que lidentifiant de session est transmis quelles que soient les conditions. --> <a href="<?php echo url("action.php"); ?>">Action</a> </div> </body> </html> LepremierappeldelURL http://.../accueil.phpprovoquelaredirectiondelutilisateurverslapagedidentification aprsuneidentificationrussie,lutilisateurrevientsurlapagedaccueilquiaffichelesinformationssuivantes : Accueil - Nous sommes le 08/02/2008 ; il est 13:51:40 Session : 64b1740cbf6422491cd5860d3fa33a4a - heurtel - le 08/02/2008 13:51:40 Action SI vous actualisez le contenu de la page quelques instants plus tard, lheure actuelle change mais pas lheure de louverturedelasession : Accueil - Nous sommes le 08/02/2008 ; il est 13:53:59 Session : 64b1740cbf6422491cd5860d3fa33a4a - heurtel - le 08/02/2008 13:51:40 Action

6.Remarqueetconclusion
Lesutilisateursmalinsoumalintentionns LepassagedelidentifiantdesessionparlURLpeutposerdesproblmesdescurit. Considronslescriptpage.phpsuivant : <?php // Ouvrir/ractiver la session. session_start(); // Afficher lid de session. echo session_id = ,session_id(); ?> Si lURL http://.../page.php?PHPSESSID=abc est appele, et si la directive session.use_only_cookie est 0, nous obtenonslersultatsuivant :

- 14 -

ENI Editions - All rigths reserved

session_id : abc LavaleurdonnelavariablePHPSESSIDdanslURLatprisecommeidentifiantdesession.Celapeutpermettreun utilisateur(malinet/oumalintentionn)defairecroirevotreapplicationquiladjunesessionouverte,oudutiliser unesessionouverteparunautreutilisateur. Ce phnomne se produit mme si la directive session.use_trans_id est 0, ce qui interdit PHP de transmettre lidentifiantdesessiondanslURL,maispasdelerecevoir. Pourempchercephnomne,ilfautmettreladirectivedeconfigurationsession.use_only_cookies1,afindeforcer lutilisationduncookiepourlatransmissiondelidentifiantdesession.Linconvnientestquelutilisateurpeutrefuser les cookies et que cette mthode nest, de toute faon, pas compltement scurise la seule solution vraiment scuriseconsisteutiliseruneconnexionscurise. Indpendammentdecela,ilestrelativementsimpledeseprmunircontrelutilisationdunfauxidentifiantdesession, soit en mmorisant ct serveur les identifiants des sessions ouvertes, soit en testant lexistence dune donne de sessiondans$_SESSION. Exemple <?php // Ouvrir/ractiver la session. session_start(); if (! isset($_SESSION[identifiant])) { // Si la donne de session identifiant // nexiste pas, cest que la session na // pas t rellement ouverte par lapplication. // Faire ce quil faut ... // Pour cet exemple : // - afficher un message echo Session non ouverte,<br />; // - simuler louverture applicative de la session $_SESSION[identifiant] = 123; } else { // Si la donne de session identifiant existe, // cest que la session a rellement t ouverte // par lapplication. echo Session ouverte,<br />; echo identifiant = ,$_SESSION[identifiant],<br />; } // Afficher lid de session echo session_id = ,session_id(),<br />; ?> Rsultat :
q

Premierappeldutypehttp://.../page.php?PHPSESSID=abc :

Session non ouverte session_id = abc


q

Deuximeappel(sansfermerlenavigateur) :

Session ouverte identifiant = 123 session_id = abc PHPaconservlidentifiantdesessioninitial.Encasdebesoin,lafonction session_regenerate_idpeuttreappele pourrgnrerunidentifiantdesession. Exemple : <?php // Ouvrir/ractiver la session. session_start(); if (! isset($_SESSION[identifiant])) { // Si la donne de session identifiant // nexiste pas, cest que la session na // pas t rellement ouverte par lapplication.

ENI Editions - All rigths reserved

- 15 -

// Faire ce quil faut ... // Pour cet exemple : // - r g n r e r u n i d e n t i f i a n t d e s e s s i o n session_regenerate_id(); // - afficher un message echo Session non ouverte,<br />; // - simuler louverture applicative de la session $_SESSION[identifiant] = 123; } else { // Si la donne de session identifiant existe, // cest que la session a rellement t ouverte // par lapplication. echo Session ouverte,<br />; echo identifiant = ,$_SESSION[identifiant],<br />; } // Afficher lid de session echo session_id = ,session_id(),<br />; ?> Rsultat :
q

Premierappeldutypehttp://.../page.php?PHPSESSID=abc :

Session non ouverte session_id = 1863f3b9f496b9923e8b90fb2cb6b96b


q

Deuximeappel(sansfermerlenavigateur) :

Session ouverte identifiant = 123 session_id = 1863f3b9f496b9923e8b90fb2cb6b96b Cette technique ne met pas labri de lutilisation abusive par un internaute dun identifiant de session dun autre internaute. Rsultat :
q

Unpremierutilisateureffectueunappeldutypehttp://.../page.php :

Session non ouverte session_id = a5e762abc38f20f6a431ae81544fd080


q

Undeuximeutilisateurrussitrcuprerlidentifiantdesessiondupremierutilisateureteffectueunappel dutypehttp://.../page.php?PHPSESSID= a5e762abc38f20f6a431ae81544fd080

Session ouverte identifiant = 123 session_id = a5e762abc38f20f6a431ae81544fd080

S ivousavezbesoindunhautniveaudescurit,utilisezuneconnexionscurise. Conclusion Moyennant un peu de rigueur dans le code, la fonctionnalit de gestion des sessions de PHP est facile mettre en uvre et indpendante des techniques de navigation utilises (liens, formulaires). Pour des besoins de scurit avance,ellepeuttrefacilementutilisedanslecadreduneconnexionscurise danscecas,ilsagitsurtoutdune problmatiquedeconfigurationduserveurwebetilnyariendeparticulierfaireauniveaudePHP.

- 16 -

ENI Editions - All rigths reserved

Conserverdesinformationsdunevisiteuneautre
Si vous souhaitez pouvoir conserver des informations sur un utilisateur dune visite lautre (ventuellement trs loignesdansletemps),ilexistedeuxsolutionsprdominantes :
q

dposeruncookiesursonposte(sipossibleavecsonaccordpralable) stocker les informations ct serveur (le plus pratique tant dutiliser une base de donnes), et associer ces informationsuneidentification(typiquementunnometunmotdepasse)quelutilisateurdevrasaisirchaque visite.

Une solution intermdiaire, lgante et respectueuse de lutilisateur est utilise par certains sites cette solution consiste proposer lutilisateur de dposer sur son poste un cookie qui ne contient quune ou deux informations permettantlaconnexionautomatiqueausite(sanssaisirdenometdemotdepasse),lesinformationscomplmentaires tantrcupresdansunebasededonnes. Nousallonsillustrercettesolutionlaidededeuxpages :
q

unepagedepersonnalisation(script personnaliser.php)quipermetlutilisateurdactiveroudedsactiverla connexionautomatique une page didentification(script login.php)qui,selonlecas,effectuelaconnexionautomatiqueoudemande lutilisateurdeseconnecter.

Chaqueconnexiondelutilisateurestunesession. Source
q

Scriptpersonnaliser.php :

<?php // Inclusion du fichier contenant les fonctions gnrales. include(fonctions.inc); // Ouvrir/ractiver la session. session_start(); // Initialisation des variables. $message = ; // La session a-t-elle t ouverte au niveau applicatif ? if (isset($_SESSION[identifiant])) { // oui // Rcuprer les informations de session. $identifiant = $_SESSION[identifiant]; $mot_de_passe = $_SESSION[mot_de_passe]; // Le script est-il appel en traitement du formulaire ? if (isset($_POST[activer])) { // oui // Activer la connexion automatique. // Dposer deux cookies dune dure de vie de 30 jours, // un pour lidentifiant de lutilisateur et un pour son // mot de passe. $expiration = time()+ (30 * 24 * 3600); setcookie(identifiant,$identifiant,$expiration); setcookie(mot_de_passe,$mot_de_passe,$expiration); // Prparer un message. $message = Connexion automatique active; } elseif (isset($_POST[dsactiver])) { // oui // Dsactiver la connexion automatique. // Supprimer les deux cookies. setcookie(identifiant); setcookie(mot_de_passe); // Prparer un message. $message = Connexion automatique dsactive; } } else { // Session non ouverte au niveau applicatif. // Rediriger lutilisateur vers la page de login header(Location: login.php); exit;

ENI Editions - All rigths reserved

- 1-

} ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>MonSite.com - Personnaliser</title></head> <body> <form action="personnaliser.php" method="post"> <div> <input type="submit" name="activer" value="Activer la connexion automatique" /><br /> <input type="submit" name="dsactiver" value="Dsactiver la connexion automatique" /><br /> <?php echo $message; ?><br /> </div> </form> </body> </html>
q

Scriptlogin.php(variantesimpledelaversionprcdente) :

<?php // Inclusion du fichier contenant les fonctions gnrales. include(fonctions.inc); // Fonction qui vrifie que lidentification saisie // est correcte. function utilisateur_existe($identifiant,$mot_de_passe) { // Connexion et slection de la base de donnes $connexion = mysqli_connect(localhost,root); mysqli_select_db($connexion,eni); // Dfinition et excution dune requte prpare $sql = SELECT 1 FROM utilisateurs ; $sql .= WHERE identifiant = ? AND mot_de_passe = ?; $requte = mysqli_stmt_init($connexion); $ok = mysqli_stmt_prepare($requte,$sql); $ok = mysqli_stmt_bind_param ($requte,ss,$identifiant,$mot_de_passe); $ok = mysqli_stmt_execute($requte); mysqli_stmt_bind_result($requte,$existe); $ok = mysqli_stmt_fetch($requte); mysqli_stmt_free_result($requte); // Lidentification est bonne si la requte a retourn // une ligne (lutilisateur existe et le mot de passe // est bon). // Si cest le cas $existe contient 1, sinon elle est // vide. Il suffit de la retourner en tant que boolen. return (bool) $existe; } // Initialisation des variables. $identifiant = ; $mot_de_passe = ; $message = ; $action = ; // Le script est-il appel en validation du formulaire ? if (isset($_POST[connexion])) { // oui // => connexion manuelle. // Rcuprer les informations saisies. $identifiant = valeur_saisie($_POST[identifiant]); $mot_de_passe = valeur_saisie($_POST[mot_de_passe]); // Indiquer laction effectuer pour la suite. $action = connexion; // Prparer un message en cas de problme. $message = Identification incorrecte. . Essayez de nouveau.; // Sinon, existe-til un cookie "identifiant" ? } elseif (isset($_COOKIE[identifiant])) { // oui // => connexion automatique. // Rcuprer les informations des cookies $identifiant = valeur_saisie($_COOKIE[identifiant]);
- 2 ENI Editions - All rigths reserved

$mot_de_passe = valeur_saisie($_COOKIE[mot_de_passe]); // Indiquer laction effectuer pour la suite. $action = connexion; // Prparer un message en cas de problme. $message = Identification automatique incorrecte. . Essayez manuellement.; } // Finalement, que fait-on ? if ($action == connexion) { // tenter une connexion // Vrifier que lutilisateur existe. if (utilisateur_existe($identifiant,$mot_de_passe)) { // Lutilisateur existe ... // => ouvrir la session au niveau applicatif session_start(); session_regenerate_id(); // au cas ou ... $_SESSION[identifiant] = $identifiant; $_SESSION[mot_de_passe] = $mot_de_passe; // Rediriger lutilisateur vers une autre page du site // (il ny en a quune !). header(location: .url(personnaliser.php)); exit; } // utilisateur_existe } // $action == connexion // Si cest le premier appel, ou si la connexion manuelle // ou automatique a chou, laisser le formulaire safficher. ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>MonSite.com - Identification</title></head> <body> <form action="login.php" method="post"> <table border="0"> <tr> <td align="right">Identifiant :</td> <td><input type="text" Name="identifiant" value= "<?php echo vers_formulaire($identifiant); ?>" /></td> </tr> <tr> <td align="right">Mot de passe :</td> <td><input type="password" Name="mot_de_passe" value= "<?php echo vers_formulaire($mot_de_passe); ?>" /></td> </tr> <tr> <td></td> <td align="right"><input type="submit" name="connexion" value="Connexion" /></td> </tr> </table> <?php echo $message; ?> </form> </body> </html> Rsultat
q

Premierappel :

Connexionmanuelleerrone :

ENI Editions - All rigths reserved

- 3-

Aprsuneconnexionrussie :

ClicsurleboutonActiver :

Quitter puis revenir sur une des deux pages. Arrive directe sur la page de personnalisation (une connexion automatiquesesteffectue) :

ClicsurleboutonDsactiver :

Quitter puis revenir sur une des deux pages. La page didentification est propose (plus de connexion automatique) :

l est prfrable de stocker le mot de passe de lutilisateur sous forme crypte ou dutiliser un identifiant de I connexionautomatiqueassocilutilisateur.Decettemanire,danslesdeuxcas,lemotdepassedelutilisateur nestpasexposauxregardsindiscrets.

- 4-

ENI Editions - All rigths reserved

PetitesynthsesurlesvariablesGPCS(Get/Post/Cookie/Session)
Depuisledbutdecetouvrage,nousavonsrencontrdesvariables"particulires",cellesassociesdesdonnesde formulaire,desdonnestransmisesparuneURL,desdonnesduncookieouencore,desdonnesdesessions. CesdiffrentstypesdevariablessontdsignssousletermedevariablesGPCS( Get/Post/Cookie/Session). Nousavonsvuquecesvariablesfonctionnaientselonlesmmesprincipes :
q

Ellessontaccessiblesdirectementsouslaforme$xsiladirectivedeconfigurationregister_globalseston. Ellessontaussiaccessiblesparlintermdiairedetableauxassociatifs $_GET, $_POST, $_COOKIEet $_SESSION.En complment,letableauassociatif$_REQUESTregroupelecontenudestableaux$_GET,$_POSTet$_COOKIE. Les variables Get/Post/Cookie peuvent aussi tre explicitement importes dans le script grce la fonction import_request_variables.

Pourchaquetype,leconseilestlemme :utilisezdeprfrencelaccsparletableauassociatifcorrespondant.Deux raisonsjustifientceconseil :


q

Cestlaseulemaniredtrecertainquelinformationquiestluearrivebienparlemoyenattendu. La directive de configuration register_globals est off par dfaut et passera dfinitivement off dans une prochaineversiondePHP.

Le tableau $_REQUEST doit tre utilis avec prcaution car il contient des donnes fournies au script par plusieurs mcanismesnousnesommesdoncpasforcmentcertainquelinformationluearrivebienparlemoyenattendu. Le fait que les tableaux $_GET, $_POST, $_COOKIE et $_SESSION soient effectivement crs dpend de la directive de configurationvariables_order. Cette directive est une chane compose des caractres G, P, C et S correspondant aux types dj voqus et dun cinquimecaractre,E,correspondantauxvariablesdenvironnement. Lesvariablesdenvironnementcorrespondentauxvariablesdenvironnementdusystmedexploitationquisontrendues disponibles dans lenvironnement PHP, soit directement sous la forme $x (si la directive de configuration register_globalseston)soittraversletableauassociatif$_ENV. Lorsqueladirectivedeconfiguration register_globalsest on,lordredapparition des lettres EGPCSdansladirective variables_ordercorrespondunordredeprioritcroissantdanslacrationdesvariables. Lecontenudutableau$_REQUESTestaussiconditionnparladirectivevariables_order. Pardfaut,ladirectivevariables_orderestgaleEGPCS. Exemple
q

Scriptpage1.php :

<?php // Ouvrir une session et enregistrer une information de // session nomme "x" de valeur "SESSION". session_start(); $_SESSION[x] = SESSION; // Dposer un cookie nomm "x" de valeur "COOKIE". setcookie(x,COOKIE); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Page 1</title></head> <body> <!-- Dans un formulaire, mettre une variable donne nomme "x" de valeur "GET" dans lURL de lattribut "action" --> <form action="page2.php?x=GET" method="post"> <!-- Mettre aussi une zone nomme "x" de

ENI Editions - All rigths reserved

- 1-

valeur "POST" --> <input type="hidden" name="x" value="POST" /> <!-- Plus un bouton pour aller sur la page 2 --> <input type="submit" name="ok" value="Page 2"> </form> </body> </html>
q

Scriptpage2.php :

<?php // Ractiver la session. session_start(); // Afficher les valeurs de x partir des tableaux. echo $_GET[\x\] = , isset($_GET[x])?$_GET[x]:,<br />; echo $_POST[\x\] = , isset($_POST[x])?$_POST[x]:,<br />; echo $_COOKIE[\x\] = , isset($_COOKIE[x])?$_COOKIE[x]:,<br />; echo $_SESSION[\x\] = , isset($_SESSION[x])?$_SESSION[x]:,<br />; echo $_REQUEST[\x\] = , isset($_REQUEST[x])?$_REQUEST[x]:,<br />; ?> Danslepremierscript,plusieursinformationsdiffrentessontassociesaummeidentifiant"x". Rsultatdelaffichagedelapage1puisduclicsurleboutonPage2 $_GET[x] = GET $_POST[x] = POST $_COOKIE[x] = COOKIE $_SESSION[x] = SESSION $_REQUEST[x] = COOKIE Letableau $_REQUESTcontientlavaleur"COOKIE",car,dansladirective variables_order,lalettre Capparataprsles lettres G et P :linformation en provenance du cookie est donc prioritaire par rapport aux autres (les informations de sessionnapparaissentpasdansletableau$_REQUEST). Siladirectivevariables_orderestmodifieenCP,nousobtenonslersultatsuivant : $_GET[x] = $_POST[x] = POST $_COOKIE[x] = COOKIE $_SESSION[x] = SESSION $_REQUEST[x] = POST Letableau $_GETnestplusalimentetletableau $_REQUESTcontientdornavantlavaleur"POST".Commelemontrecet exemple,letableau$_SESSIONestrenseignbienquelalettreSnesoitpasprsentedansladirectivevariables_order. Un problme similaire peut se produire lors de lutilisation de la fonction import_request_variables. Le premier paramtredecettefonctionindiquelestypesdevariablesimporter,souslaformedunecombinaisondeslettres G, P et C : CP par exemple. Les variables sont importes dans lordre indiqu et crasent les variables de mme nom prcdemment importes. Sur notre exemple, la valeur "COOKIE" crasera la valeur "POST". Pour viter ce genre de problme,ilestpossibledappelerplusieursfoislafonction,enindiquantchaquefoisunprfixediffrentpourlenom delavariable(deuximeparamtre). e nest pas une bonne habitude de programmation dutiliser le mme nom pour plusieurs informations un C dveloppeur sens ne sera pas confront ce problme. Cette situation carte, il faut avoir conscience quun utilisateur (malin et/ou mal intentionn) peut assez facilement fournir une valeur par un moyen donn (GPC en loccurrence),unevariabledontvouspensezcontrlerlorigine.crireducodedontlefonctionnementestliune certainevaleurdeladirective variables_ordernestsansdoutepas,nonplus,unebonneidedupointdevuedela portabilitetdelamaintenabilit. Leconseilavis,donnparlquipededveloppementdePHP,estdonclesuivant :

- 2-

ENI Editions - All rigths reserved

Rcuprezlesvaleurs"EGPCS"parlestableauxassociatifspourvitertoutproblme. Cestpourcelaqueladirective register_globalsest offpardfaut,etquelleseraforcedfinitivement offdans uneprochaineversiondePHP.

ENI Editions - All rigths reserved

- 3-

VariablesPHPprdfinies
PHPprdfinitungrandnombredevariablesrelativessonfonctionnement.Cesvariablessontdirectementaccessibles souslaforme $xsiladirectivedeconfigurationregister_globalsest on,maiscenestpaslamthoderecommande. Pouraccdercesinformations,ilestprfrabledutiliserlestableauxassociatifspropossparPHP. Lestableauxassociatifssontlessuivants : Nom Contenu Tableauassociatifdetouteslesvariablesdisponibles danslaporteduscript(chapitreEcriredesfonctions etdesclassesPHP). Tableauassociatifdesvariablespassesauscriptpar lescookies(chapitreGrerlessessions). Tableauassociatifdesvariablespassesauscriptpar unemthodeGET(chapitresGrerlesformulaireset lesliensavecPHP). Tableauassociatifdesvariablespassesauscriptpar unemthodePOST(chapitresGrerlesformulaireset lesliensavecPHP) Tableauassociatifcontenantlesinformationssurles fichierstlchargsdupostedelutilisateurversle serveurWeb(chapitreGrerlesformulairesetlesliens avecPHP). Tableauassociatifdesvariablesdenvironnementdu systmedexploitationpassesauscript(chapitre Grerlessessions). Tableauassociatifdesvariablesduserveurpassesau script(variabledenvironnementetvariablesdu serveurHTTPnotamment). Tableauassociatifregroupantlestableaux$_GET, $_POSTet$_COOKIE(chapitresGrerlesformulaireset lesliensavecPHPetGrerlessessions). Tableauassociatifdesdonnesdesessionaccessible danslescript(chapitreGrerlessessions).

$GLOBALS

$_COOKIE

$_GET

$_POST

$_FILES

$_ENV

$_SERVER

$_REQUEST

$_SESSION

Ces tableaux associatifs sont des variables "super globales" : ils sont disponibles dans la totalit du script, mme lintrieurdesfonctions,sansdevoirlesdclarerglobaux(global $...estinutile). Exemple :affichagepartielducontenude$_SERVER HTTP_HOST = xampp HTTP_USER_AGENT = Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv: .8.1.11) Gecko/20071127 Firefox/2.0.0.11 HTTP_ACCEPT = text/xml,application/xml,application/xhtml +xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 HTTP_ACCEPT_LANGUAGE = fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3 HTTP_ACCEPT_ENCODING = gzip,deflate HTTP_ACCEPT_CHARSET = ISO-8859-1,utf-8;q=0.7,*;q=0.7 HTTP_KEEP_ALIVE = 300 HTTP_CONNECTION = keep-alive HTTP_REFERER = http://xampp/eni/ CONTENT_TYPE = application/x-www-form-urlencoded CONTENT_LENGTH = 97 SERVER_SOFTWARE = Apache/2.2.6 (Unix) DAV/2 mod_ssl/2.2.6 OpenSSL/0.9.8e PHP/5.2.4 mod_apreq2-20051231/2.5.7 mod_perl/2.0.2 Perl/v5.8.7

ENI Editions - All rigths reserved

- 1-

SERVER_NAME = xampp SERVER_ADDR = 192.168.154.200 SERVER_PORT = 80 REMOTE_ADDR = 192.168.154.1 DOCUMENT_ROOT = /opt/lampp/htdocs SERVER_ADMIN = you@example.com SCRIPT_FILENAME = /app/scripts/index.php REMOTE_PORT = 42134 GATEWAY_INTERFACE = CGI/1.1 SERVER_PROTOCOL = HTTP/1.1 REQUEST_METHOD = POST QUERY_STRING = REQUEST_URI = /eni/ SCRIPT_NAME = /eni/index.php PHP_SELF = /eni/index.php REQUEST_TIME = 1202411345 Quelquesinformationsintressantesapparaissentengras. Lafonctionphpinfopermetdaffichercesdiffrentesinformations(entreautres).

- 2-

ENI Editions - All rigths reserved

ConstantesPHPprdfinies
PHPprdfinitungrandnombredeconstantesparmilesquelles : Nom Contenu Nomdufichierencoursdexcution.Donnelenomdu fichierinclussielleestutilisedansunfichierinclus. Numrodelaligneactuellementexcute.Donnele numrodelignedanslefichierinclussielleestutilise dansunfichierinclus. VersiondePHP. SystmedexploitationduserveurPHP.Exemples(non exhaustifs) :AIX,Linux,SunOS,WINNT. Valeurboolennevraie(TRUE). Valeurboolennefausse( FALSE). Codesdeserreurs(chapitreGrerleserreursdansun scriptPHP). Caractredesparationutilisdanslesnomsde rpertoirepourlaplateformesurlaquellePHPest installe. Squencedecaractresutiliseparlaplateformepour reprsenterunenouvelleligne.Ajoutenversion 5.0.2. Valeurduplusgrandentier.Ajoutenversion5.0.5. Tailledesentiers(nombredoctets).Ajoutenversion 5.0.5.

__FILE__ *

__LINE__ * PHP_VERSION PHP_OS TRUE * FALSE * E_*

DIRECTORY_SEPARATOR

PHP_EOL PHP_INT_MAX PHP_INT_SIZE

Lesconstantessuiviesdunetoilesontinsensibleslacasse(etpeuventtreutilisesindiffremmentenmajuscules ouenminuscules).

ENI Editions - All rigths reserved

- 1-

Exemplescomplmentaires
1.Introduction
La puissance du langage PHP est renforce par lexistence dun grand nombre de bibliothques qui tendent les fonctionnalits du langage : vrification dorthographe, gnration de documents PDF ( Portable Document Format), manipulationdedocumentsXML(ExtensibleMarkupLanguage),accsdesserveursFTP(FileTransferProtocol),accs desserveursIMAP(InternetMessageAccessProtocol),accsdesannuairesLDAP(LightweightDirectoryAccessProtocol), cryptage,gnrationdedocumentsShockwaveFlash,gestionduprotocoleSNMP(SimpleNetworkManagementProtocol), compression, etc. Certaines bibliothques ncessitent des librairies complmentaires. Ces diffrentes bibliothques correspondentdesbesoinsparticuliersetnesontpasdcritesplusendtaildanscetouvrage. Dans cette partie de lannexe, nous allons donner trois exemples comments dutilisation de ces bibliothques correspondanttroisbesoinsfrquents :
q

lireundocumentXML gnrerundocumentPDF gnreruneimage.

Pourplusdinformationssurlesbibliothquesdisponiblesousurunefonction,reportezvouslaideenligneaccessible surlesiteofficieldePHP(www.php.net/manual/fr/).

2.LireundocumentXML
CetexempleillustrelespossibilitsdelextensionSimpleXMLapparueenversion5. Pourcetexemple,noussupposonsquunelistedarticleseststockedansunfichiernommarticles.xml : <?xml version=1.0 encoding=UTF-8?> <articles> <article code="A1" couleur="jaune"> <identifiant>1</identifiant> <libelle>Abricots</libelle> <prix>35.5</prix> </article> <article code="A2" couleur="rouge"> <identifiant>2</identifiant> <libelle>Cerises</libelle> <prix>48.9</prix> </article> <article code="A3" couleur="rouge"> <identifiant>3</identifiant> <libelle>Fraises</libelle> <prix>29.95</prix> </article> <article code="A4" couleur="jaune"> <identifiant>4</identifiant> <libelle>Pches</libelle> <prix>37.2</prix> </article> </articles> Code <?php // Charger le document XML = simplexml_load_file() // - retourne un objet de la classe simplexml_element // ou FALSE en cas derreur (document XML mal form par exemple) $xml = simplexml_load_file(articles.xml); if (! $xml) { exit; }
ENI Editions - All rigths reserved - 1-

// Lobjet $xml a une structure qui correspond la // structure de notre document : // - article (tableau dobjets) // - identifiant // - libelle // - prix // Parcours du noeud article (tableau). echo "<b>Parcours de \$xml->article</b><br />\n"; foreach ($xml->article as $article) { printf("%s,%s,%s,%s,%s<br />\n", $article->identifiant, $article->libelle, $article->prix, $article[code], $article[couleur]); } // Accs une information particulire. echo "<b>Accs une information particulire</b><br />\n"; printf("Avant - Prix de %s = %s (code = %s)<br />\n", $xml->article[2]->libelle, $xml->article[2]->prix, $xml->article[2][code]); $xml->article[2]->prix = 123; $xml->article[2][code] .= +; printf("Aprs - Prix de %s = %s (code = %s)<br />\n", $xml->article[2]->libelle, $xml->article[2]->prix, $xml->article[2][code]); // Extraction des attributs dun noeud = mthode attributes() // - retourne un objet de la classe simplexml_element // - sur notre exemple, rcupration des attributs du 1er article $attributs = $xml->article[0]->attributes(); // Parcours des attributs ainsi rcuprs. echo "<b>Attributs du premier article</b><br />\n"; foreach($attributs as $nom => $valeur) { printf("%s = %s<br />\n",$nom,$valeur); } // Extraire les enfants dun noeud = mthode children() // - retourne un objet de la classe simplexml_element echo "<b>Parcours de larborescence</b><br />\n"; echo "racine<br />\n"; foreach ($xml->children() as $nom1 => $niveau1) { printf("----%s (%s,%s)<br />\n", $nom1,$niveau1[code],$niveau1[couleur]); foreach ($niveau1->children() as $nom2 => $niveau2) { printf("--------%s = %s<br />\n",$nom2,$niveau2); } } // Effectuer une recherche Xpath = mthode xpath() // - retourne un tableau dobjets de la classe simplexml_element echo "<b>Recherche Xpath : /articles/article</b><br />\n"; $rsultat = $xml->xpath("/articles/article"); foreach ($rsultat as $valeur) { printf("%s,%s<br />\n",$valeur->identifiant,$valeur->libelle); } echo "<b>Recherche Xpath : article/libelle</b><br />\n"; $rsultat = $xml->xpath("article/libelle"); foreach ($rsultat as $valeur) { printf("%s<br />\n",$valeur); } echo "<b>Recherche Xpath : //prix</b><br />\n"; $rsultat = $xml->xpath("//prix");
- 2 ENI Editions - All rigths reserved

foreach ($rsultat as $valeur) { printf("%s<br />\n",$valeur); } // Gnrer une chane XML = mthode asXML() echo "<b>Chane XML</b><br />\n"; file_put_contents (les_articles.xml, $ x m l - > a s X M L ( ) ) ; file_put_contents (un_article.xml, $ x m l - > a r t i c l e [ 0 ] - > a s X M L ( ) ); echo "Voir les fichiers les_articles.xml et un_article.xml<br />\n"; ?> Rsultatlcran Parcours de $xml->article 1,Abricots,35.5,A1,jaune 2,Cerises,48.9,A2,rouge 3,Fraises,29.95,A3,rouge 4,Pches,37.2,A4,jaune Accs une information particulire Avant - Prix de Fraises = 29.95 (code = A3) Aprs - Prix de Fraises = 123 (code = A3+) Attributs du premier article code = A1 couleur = jaune Parcours de larborescence racine ----article (A1,jaune) --------identifiant = 1 --------libelle = Abricots --------prix = 35.5 ----article (A2,rouge) --------identifiant = 2 --------libelle = Cerises --------prix = 48.9 ----article (A3+,rouge) --------identifiant = 3 --------libelle = Fraises --------prix = 123 ----article (A4,jaune) --------identifiant = 4 --------libelle = Pches --------prix = 37.2 Recherche Xpath : /articles/article 1,Abricots 2,Cerises 3,Fraises 4,Pches Recherche Xpath : article/libelle Abricots Cerises Fraises Pches Recherche Xpath : //prix 35.5 48.9 123 37.2 Chane XML Voir les fichiers les_articles.xml et un_article.xml Contenudufichierles_articles.xml <?xml version="1.0" encoding="UTF-8"?> <articles> <article code="A1" couleur="jaune"> <identifiant>1</identifiant> <libelle>Abricots</libelle>

ENI Editions - All rigths reserved

- 3-

<prix>35.5</prix> </article> <article code="A2" couleur="rouge"> <identifiant>2</identifiant> <libelle>Cerises</libelle> <prix>48.9</prix> </article> <article code="A3+" couleur="rouge"> <identifiant>3</identifiant> <libelle>Fraises</libelle> <prix>123</prix> </article> <article code="A4" couleur="jaune"> <identifiant>4</identifiant> <libelle>Pches</libelle> <prix>37.2</prix> </article> </articles> Contenudufichierun_article.xml <article code="A1" couleur="jaune"> <identifiant>1</identifiant> <libelle>Abricots</libelle> <prix>35.5</prix> </article>

3.GnrerundocumentPDF
LextensionPDFdePHPpermetdegnrerdesdocumentsPDF.CetteextensionutiliselalibrairiePDFlibquincessite unelicence(http://www.pdflib.com/products/pdflibfamily/). IlexisteplusieursalternativesgratuitespourgnrerdesdocumentsPDF,dontlalibrairieFPDF(http://www.fpdf.org/). CettelibrairienestpasinstallepardfautavecPHPmaiselleestprsentedanslepackageXAMPP.Cestcettelibrairie quenousallonsutiliserdanscetexemple. LecodeciaprspermetdegnrerledocumentPDFsuivant :

- 4-

ENI Editions - All rigths reserved

Lalistedescollectionsestluedanslabasededonnes. Code <?php // Inclusion de la librairie. include (fpdf.php); // Slectionner les donnes dans la base de donnes. set_magic_quotes_runtime(0); $db = @mysqli_connect(localhost,eniweb,web,eni); if (! $db) { exit(Erreur lors de la connexion.); } $sql = SELECT nom,prix_ht FROM collection LIMIT 4; $ok = ($requte = mysqli_prepare($db, $sql)); if ($ok) { $ok = @mysqli_stmt_execute($requte); } if ($ok) { $ok = @mysqli_stmt_bind_result($requte,$nom,$prix); } if (! $ok) { exit(Erreur lors de la slection des donnes dans la base.); } // Crer un nouveau document PDF = new FPDF() // - premier paramtre = orientation

ENI Editions - All rigths reserved

- 5-

// > P = portrait - L = Paysage // - deuxime paramtre = unit de mesure // > pt = point - mm = millimtre - cm = centimtre // - troisime paramtre = format (A3, A4, etc) // Tous les paramtres sont optionnels. Dfaut = P, mm, A4. $pdf = new FPDF(P,mm,A4); // Dfinir les sauts de page automatiques = SetAutoPageBreak() // - premier paramtre = automatique (true/false) // > P = portrait - L = Paysage // - deuxime paramtre = marge // > distance par rapport au bas de la page qui dclenche // le saut (2 cm par dfaut, si actif) $pdf->SetAutoPageBreak(false); // Crer une nouvelle page dans le document = AddPage() // - premier paramtre = orientation // > P = portrait - L = Paysage // Par dfaut, celle du document. $pdf->AddPage(); // Dfinir les informations de rsum du document = SetTitle(), // SetAuthor(), SetSubject(). $pdf->SetTitle(Liste des collections); $pdf->SetAuthor(Olivier HEURTEL); $pdf->SetSubject(Collections); // Dfinir la police utiliser = SetFont() // - premier paramtre = famille // > nom dune famille standard (Courier, Helvetica ou Arial, // Times, Symbol, ZapfDingbats) ou dun nom dfini par // AddFont(). // - deuxime paramtre (optionnel) = style // > combinaison de : B = gras - I = italique - U = soulign // - troisime paramtre (optionnel) = taille en points // Voir aussi la mthode SetFontSize() pour modifier la taille. $pdf->SetFont(Arial,B,16); // Ecrire du texte partir de la position courante = Write() // - premier paramtre = hauteur de la ligne // - deuxime paramtre = texte crire // Utilise les caractristiques actuelles de police, couleurs, etc. // Le retour la ligne est automatique lorsque la marge droite est // atteinte (ou que le caractre \n est rencontr). $pdf->Write(5, Liste des collections); // Effectuer un saut de ligne = Ln() // - premier paramtre (optionnel) = hauteur de la ligne // Labcisse revient la valeur de la marge gauche. $pdf->Ln(10); // Changer la taille de police = SetFontSize() // - premier paramtre = taille en points $pdf->SetFontSize(12); // Dfinir la couleur utiliser pour le texte = SetTextColor() // - si un seul paramtre = niveau de gris (entre 0 et 255) // - si 3 paramtres = composantes RGB (entre 0 et 255) $pdf->SetTextColor(255,0,0); // rouge // Dfinir la couleur utiliser pour le fond = SetFillColor() // - si un seul paramtre = niveau de gris (entre 0 et 255) // - si 3 paramtres = composantes RGB (entre 0 et 255) $pdf->SetFillColor(255,255,140); // jaune pale // Ecrire une cellule = Cell() // - premier paramtre = largeur (0 = jusqu la marge droite) // - deuxime paramtre = hauteur

- 6-

ENI Editions - All rigths reserved

// - troisime paramtre = texte crire // - quatrime paramtre = bordure // > soit un nombre : 0 = aucun bord - 1 = cadre // > soit une chane : combinaison de L (gauche), T (haut), // R (droit), B (bas) // - cinquime paramtre = position la fin // > 0 = droite - 1 = dbut ligne suivante - 2 = en dessous // - sixime paramtre = alignement // > L ou chane vide = gauche - C = centr - R = droite // - septime paramtre = remplissage // > 0 = non - 1 = oui // Seul le premier paramtre est obligatoire. $pdf->Cell(80,7,Nom,1,0,C,1); // titre de colonne $pdf->Cell(40,7,Prix H.T.,1,1,C,1); // titre de colonne // Changer de couleur et de police $pdf->SetFont(Arial,,12); // = normal $pdf->SetTextColor(0,0,0); // noir // Dans une boucle, crire les donnes du tableau. while (mysqli_stmt_fetch($requte)) { // fetch de la requte $prix = number_format($prix,2,,, ); $pdf->Cell(80,7,$nom,1); $pdf->Cell(40,7,$prix,1,1,R); // ligne suivante + droite } // Se positionner un endroit prcis dans la page = SetXY() // - premier paramtre = abscisse (x) // - deuxime paramtre = ordonne (y) // Lorigine est le coin suprieur gauche. // Si les valeurs sont ngatives, lorigine est le coin // infrieur droit. // Voir aussi SetX() et SetY(). $pdf->SetXY(10,-10); // 1 cm gauche, 1 cm du bas // Afficher le numro de page = PageNo() $pdf->SetFontSize(10); $pdf->Cell(0,0,Page .$pdf->PageNo(),0,0,R); // Afficher une image = Image() // - premier paramtre = nom du fichier // - deuxime paramtre = abscisse du coin suprieur gauche // - troisime paramtre = ordonne du coin suprieur gauche // - quatrime paramtre (optionnel) = largeur de limage // > 0 ou absent = calcule automatiquement // - cinquime paramtre (optionnel) = hauteur de limage // > 0 ou absent = calcule automatiquement // - sixime paramtre (optionnel) = type // > JPG ou JPEG ou PNG // > Dduit de lextension si absent $pdf->Image(logo.jpg,10,285,20); // Dfinir la couleur utiliser pour le dessin = SetDrawColor() // - si un seul paramtre = niveau de gris (entre 0 et 255) // - si 3 paramtres = composantes RGB (entre 0 et 255) $pdf->SetDrawColor(128); // niveau de gris $pdf->line(10,15,200,15); // ligne horizontale en haut $pdf->line(10,285-2,200,285-2); // ligne horizontale en bas // Envoyer le document vers une destination = Output() // - premier paramtre (optionnel) = nom du fichier // - deuxime paramtre (optionnel) = type de destination // > F = fichier sur le serveur // > I = navigateur (en ligne) // > D = navigateur (tlchargement) // Si aucun paramtre : destination = I // Si un nom est spcifi : destination par dfaut = F $pdf->Output(); // navigateur (en ligne)

ENI Editions - All rigths reserved

- 7-

?>

4.Gnreruneimage
LextensionGDdePHPpermetdecreretmanipulerdesimages. Lecodecidessouspermetdegnrerlapagesuivante :

Lagnrationdugraphiqueesteffectuedynamiquementlorsdelappellapage pourcetexemple,lesdonnesdu graphiquesontcalculesalatoirement. Code <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Mon beau graphique</title> </head> <body> <div> <b>Mon beau graphique</b> <p> <img alt="Mon beau graphique" src="mon-beau-graphique.php" /> </p> </body> </html> Notezquelasourcedelimage est un script PHP qui cre limage dynamiquement lorsque la page est affiche. Cette techniquepeutaussitreutilisepourafficherdansunepageuneimagequieststockedansunebasededonnes. Scriptmon-beau-graphique.php <?php // Dfinir un en-tte indiquant quil sagit dune image (ici PNG). header(Content-type: image/png); /* Les fonctions dfinies dans le script utilisent deux variables globales : - $image = ressource image en cours de cration - $hauteur_image = hauteur de limage Pour les coordonnes, lorigine de limage est le coin suprieur gauche. Pour le dessin de notre graphique, nous utilisons une origine dans le coin infrieur gauche (plus pratique). Les fonctions effectuent la conversion. */

- 8-

ENI Editions - All rigths reserved

// Fontion de dessin dun rectangle // - $x1,$y1 = point 1 // - $x2,$y2 = point 2 // - $bordure, $fond = couleurs de la bordure et du fond // function rectangle($x1,$y1,$x2,$y2,$bordure,$fond) { global $image; global $hauteur_image; // Conversion du systme de coordonnes pour laxe y. $y1 = $hauteur_image - 1 - $y1; $y2 = $hauteur_image - 1 - $y2; // Dessiner le bord dun rectangle = imagerectangle imagerectangle($image,$x1,$y1,$x2,$y2,$bordure); // Remplissage (si demand i.e. $fond renseign) if ( ( $fond != NULL) and ($x1 != $x2) and ($y1 != $y2) ) { // Remplir un rectangle = imagefilledrectangle imagefilledrectangle($image,$x1+1,$y1-1,$x2-1,$y2+1,$fond); } } // Fontion de dessin dune ligne // - $x1,$y1 = point 1 // - $x2,$y2 = point 2 // - $couleur = couleur // function ligne($x1,$y1,$x2,$y2,$couleur) { global $image; global $hauteur_image; // Conversion du systme de coordonnes pour laxe y $y1 = $hauteur_image - 1 - $y1; $y2 = $hauteur_image - 1 - $y2; // Dessiner une ligne = imageline imageline($image,$x1,$y1,$x2,$y2,$couleur); } // Fontion de dessin dun texte // - $police = code de la police prdfinie (1 5) // - $x,$y = point de rfrence // - $texte = texte // - $couleur = couleur // - $horizontal = alignement horizontal par rapport au point // de rfrence // > D = align droite, C = centr, G = align gauche // - $vertical = alignement vertical par rapport au point de rfrence // > H = texte en haut, C = centr, B = texte en bas // function texte($police,$x,$y,$texte,$couleur,$horizontal,$vertical) { global $image; global $hauteur_image; // Conversion du systme de coordonnes pour laxe y $y = $hauteur_image - 1 - $y; // Calculer la largeur dun caractre dans une police = // imagefontwidth $largeur = imagefontwidth($police) * strlen($texte); // Calculer la hauteur dun caractre dans une police = // imagefontheight $hauteur = imagefontheight($police);
ENI Editions - All rigths reserved - 9-

// Calcul des coordonnes en fonction de lalignement switch ($horizontal) { case D: $x = $x - $largeur; break; case C: $x = $x - floor($largeur/2); break; case G: break; } switch ($vertical) { case H: $y = $y - $hauteur; break; case C: $y = $y - floor($hauteur/2); break; case B: break; } // Dessiner un texte = imagestring imagestring($image,$police,$x,$y,$texte,$couleur); } // Pour cet exemple, les donnes du graphe sont calcules de // faon alatoires. // - unit, valeur min et valeur max pour laxe y $axe_y_unite = 10; $axe_y_min = 0; $axe_y_max = 40; // - nombre de barres : entre 5 et 15 $nombre_barres = rand(5,15); // - mettre les donnes dans le tableau $donnes = array(); for ($i = 1 ; $i <= $nombre_barres ; $i++) { $donnes[$i] = rand($axe_y_min,$axe_y_max); } // Dimensions du dessin (pixels) $largeur_image = 400; // largeur de limage $hauteur_image = 200; // hauteur de limage $marge_blanche = 2; // marge blanche $marge_gauche = 25; // marge gauche avec la zone de traage $marge_droite = 20; // marge droite avec la zone de traage $marge_haute = 20; // marge haute avec la zone de traage $marge_basse = 30; // marge basse avec la zone de traage $cart_barres = 5; // cart entre les barres // En dduire la largeur et la hauteur de la zone de traage. $largeur_trac = $largeur_image - $marge_droite - $marge_gauche; $hauteur_trac = $hauteur_image - $marge_haute - $marge_basse; // En dduire la largeur des barres et lchelle de laxe y. $largeur_barre = ($largeur_trac-$cart_barres)/$nombre_barres - $cart_barres ; $chelle_axe_y = ($hauteur_trac-1) / $axe_y_max ; // Crer limage = imagecreatetruecolor $image = imagecreatetruecolor($largeur_image,$hauteur_image); // Dfinir des couleurs = imagecolorallocate // - en RGB $blanc = imagecolorallocate($image, 255, 255, 255); $noir = imagecolorallocate($image, 0, 0, 0); $gris_clair = imagecolorallocate($image, 192, 192, 192); $gris_fonc = imagecolorallocate($image, 100, 100, 100); $vert = imagecolorallocate($image, 0, 128, 0);

- 10 -

ENI Editions - All rigths reserved

// Coordonnes de limage. $ox1 = 0; $oy1 = 0; $ox2 = $largeur_image - 1; $oy2 = $hauteur_image - 1; // dessiner le cadre extrieur rectangle($ox1,$oy1,$ox2,$oy2,$noir,$blanc); // Coordonnes de limage moins le bord blanc. $mx1 = $ox1 + $marge_blanche; $my1 = $oy1 + $marge_blanche; $mx2 = $ox2 - $marge_blanche; $my2 = $oy2 - $marge_blanche; // dessiner le fond gris clair rectangle($mx1,$my1,$mx2,$my2,$gris_clair,$gris_clair); // Coordonnes de la zone de traage. $tx1 = $ox1 + $marge_gauche; $ty1 = $oy1 + $marge_basse; $tx2 = $ox2 - $marge_droite; $ty2 = $oy2 - $marge_haute; // dessiner le cadre de la zone de traage rectangle($tx1,$ty1,$tx2,$ty2,$noir,NULL); // Dessin des lignes horizontales avec leur tiquette. $x1 = $tx1; $x2 = $tx2; for ($axe = $axe_y_min ; $axe <= $axe_y_max ; $axe += $axe_y_unite) { $y1 = $ty1 + $axe * $chelle_axe_y; $y2 = $y1; // ne pas dessiner la ligne en bas et en haut if ( ( $axe > $axe_y_min ) and ( $axe < $axe_y_max ) ) { ligne($x1,$y1,$x2,$y2,$gris_fonc); } texte(3,$x1-2,$y1,$axe,$noir,"D","C"); } // Dessin des barres. $i = 0; foreach($donnes as $cl => $valeur) { $i++; $x1 = $tx1 + $cart_barres + ($i-1)*($cart_barres+$largeur_barre); $x2 = $x1 + $largeur_barre; $y1 = $ty1; $y2 = $y1 + $valeur * $chelle_axe_y; rectangle($x1,$y1,$x2,$y2,$noir,$vert); texte(3,($x1+$x2)/2,$y1,$cl,$noir,"C","B"); } // Gnrer limage au format PNG = imagepng // - soit lcran (pas de deuxime paramtre) // - soit dans un fichier (deuxime paramtre = nom du fichier) // Il existe des fonctions similaires pour dautres formats. imagepng($image /*, image.png */); // Supprimer limage = imagedestroy imagedestroy($image); ?>

ENI Editions - All rigths reserved

- 11 -

Das könnte Ihnen auch gefallen